ActivityManagerService.java revision c02a4a46139761f1bb06540007a322dbd83fea0a
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    // it's a semaphore; boost when 0->1, reset when 1->0
644    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
645        @Override protected Integer initialValue() {
646            return 0;
647        }
648    };
649
650    static void boostPriorityForLockedSection() {
651        if (sIsBoosted.get() == 0) {
652            // boost to prio 118 while holding a global lock
653            Process.setThreadPriority(Process.myTid(), -2);
654            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
655        }
656        int cur = sIsBoosted.get();
657        sIsBoosted.set(cur + 1);
658    }
659
660    static void resetPriorityAfterLockedSection() {
661        sIsBoosted.set(sIsBoosted.get() - 1);
662        if (sIsBoosted.get() == 0) {
663            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
664            Process.setThreadPriority(Process.myTid(), 0);
665        }
666    }
667    public class PendingAssistExtras extends Binder implements Runnable {
668        public final ActivityRecord activity;
669        public final Bundle extras;
670        public final Intent intent;
671        public final String hint;
672        public final IResultReceiver receiver;
673        public final int userHandle;
674        public boolean haveResult = false;
675        public Bundle result = null;
676        public AssistStructure structure = null;
677        public AssistContent content = null;
678        public Bundle receiverExtras;
679
680        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
681                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
682            activity = _activity;
683            extras = _extras;
684            intent = _intent;
685            hint = _hint;
686            receiver = _receiver;
687            receiverExtras = _receiverExtras;
688            userHandle = _userHandle;
689        }
690        @Override
691        public void run() {
692            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
693            synchronized (this) {
694                haveResult = true;
695                notifyAll();
696            }
697            pendingAssistExtrasTimedOut(this);
698        }
699    }
700
701    final ArrayList<PendingAssistExtras> mPendingAssistExtras
702            = new ArrayList<PendingAssistExtras>();
703
704    /**
705     * Process management.
706     */
707    final ProcessList mProcessList = new ProcessList();
708
709    /**
710     * All of the applications we currently have running organized by name.
711     * The keys are strings of the application package name (as
712     * returned by the package manager), and the keys are ApplicationRecord
713     * objects.
714     */
715    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
716
717    /**
718     * Tracking long-term execution of processes to look for abuse and other
719     * bad app behavior.
720     */
721    final ProcessStatsService mProcessStats;
722
723    /**
724     * The currently running isolated processes.
725     */
726    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
727
728    /**
729     * Counter for assigning isolated process uids, to avoid frequently reusing the
730     * same ones.
731     */
732    int mNextIsolatedProcessUid = 0;
733
734    /**
735     * The currently running heavy-weight process, if any.
736     */
737    ProcessRecord mHeavyWeightProcess = null;
738
739    /**
740     * All of the processes we currently have running organized by pid.
741     * The keys are the pid running the application.
742     *
743     * <p>NOTE: This object is protected by its own lock, NOT the global
744     * activity manager lock!
745     */
746    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
747
748    /**
749     * All of the processes that have been forced to be foreground.  The key
750     * is the pid of the caller who requested it (we hold a death
751     * link on it).
752     */
753    abstract class ForegroundToken implements IBinder.DeathRecipient {
754        int pid;
755        IBinder token;
756    }
757    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
758
759    /**
760     * List of records for processes that someone had tried to start before the
761     * system was ready.  We don't start them at that point, but ensure they
762     * are started by the time booting is complete.
763     */
764    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of persistent applications that are in the process
768     * of being started.
769     */
770    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Processes that are being forcibly torn down.
774     */
775    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of running applications, sorted by recent usage.
779     * The first entry in the list is the least recently used.
780     */
781    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Where in mLruProcesses that the processes hosting activities start.
785     */
786    int mLruProcessActivityStart = 0;
787
788    /**
789     * Where in mLruProcesses that the processes hosting services start.
790     * This is after (lower index) than mLruProcessesActivityStart.
791     */
792    int mLruProcessServiceStart = 0;
793
794    /**
795     * List of processes that should gc as soon as things are idle.
796     */
797    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
798
799    /**
800     * Processes we want to collect PSS data from.
801     */
802    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
803
804    private boolean mBinderTransactionTrackingEnabled = false;
805
806    /**
807     * Last time we requested PSS data of all processes.
808     */
809    long mLastFullPssTime = SystemClock.uptimeMillis();
810
811    /**
812     * If set, the next time we collect PSS data we should do a full collection
813     * with data from native processes and the kernel.
814     */
815    boolean mFullPssPending = false;
816
817    /**
818     * This is the process holding what we currently consider to be
819     * the "home" activity.
820     */
821    ProcessRecord mHomeProcess;
822
823    /**
824     * This is the process holding the activity the user last visited that
825     * is in a different process from the one they are currently in.
826     */
827    ProcessRecord mPreviousProcess;
828
829    /**
830     * The time at which the previous process was last visible.
831     */
832    long mPreviousProcessVisibleTime;
833
834    /**
835     * Track all uids that have actively running processes.
836     */
837    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
838
839    /**
840     * This is for verifying the UID report flow.
841     */
842    static final boolean VALIDATE_UID_STATES = true;
843    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
844
845    /**
846     * Packages that the user has asked to have run in screen size
847     * compatibility mode instead of filling the screen.
848     */
849    final CompatModePackages mCompatModePackages;
850
851    /**
852     * Set of IntentSenderRecord objects that are currently active.
853     */
854    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
855            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
856
857    /**
858     * Fingerprints (hashCode()) of stack traces that we've
859     * already logged DropBox entries for.  Guarded by itself.  If
860     * something (rogue user app) forces this over
861     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
862     */
863    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
864    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
865
866    /**
867     * Strict Mode background batched logging state.
868     *
869     * The string buffer is guarded by itself, and its lock is also
870     * used to determine if another batched write is already
871     * in-flight.
872     */
873    private final StringBuilder mStrictModeBuffer = new StringBuilder();
874
875    /**
876     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
877     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
878     */
879    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
880
881    /**
882     * Resolver for broadcast intents to registered receivers.
883     * Holds BroadcastFilter (subclass of IntentFilter).
884     */
885    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
886            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
887        @Override
888        protected boolean allowFilterResult(
889                BroadcastFilter filter, List<BroadcastFilter> dest) {
890            IBinder target = filter.receiverList.receiver.asBinder();
891            for (int i = dest.size() - 1; i >= 0; i--) {
892                if (dest.get(i).receiverList.receiver.asBinder() == target) {
893                    return false;
894                }
895            }
896            return true;
897        }
898
899        @Override
900        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
901            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
902                    || userId == filter.owningUserId) {
903                return super.newResult(filter, match, userId);
904            }
905            return null;
906        }
907
908        @Override
909        protected BroadcastFilter[] newArray(int size) {
910            return new BroadcastFilter[size];
911        }
912
913        @Override
914        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
915            return packageName.equals(filter.packageName);
916        }
917    };
918
919    /**
920     * State of all active sticky broadcasts per user.  Keys are the action of the
921     * sticky Intent, values are an ArrayList of all broadcasted intents with
922     * that action (which should usually be one).  The SparseArray is keyed
923     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
924     * for stickies that are sent to all users.
925     */
926    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
927            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
928
929    final ActiveServices mServices;
930
931    final static class Association {
932        final int mSourceUid;
933        final String mSourceProcess;
934        final int mTargetUid;
935        final ComponentName mTargetComponent;
936        final String mTargetProcess;
937
938        int mCount;
939        long mTime;
940
941        int mNesting;
942        long mStartTime;
943
944        // states of the source process when the bind occurred.
945        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
946        long mLastStateUptime;
947        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
948                - ActivityManager.MIN_PROCESS_STATE+1];
949
950        Association(int sourceUid, String sourceProcess, int targetUid,
951                ComponentName targetComponent, String targetProcess) {
952            mSourceUid = sourceUid;
953            mSourceProcess = sourceProcess;
954            mTargetUid = targetUid;
955            mTargetComponent = targetComponent;
956            mTargetProcess = targetProcess;
957        }
958    }
959
960    /**
961     * When service association tracking is enabled, this is all of the associations we
962     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
963     * -> association data.
964     */
965    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
966            mAssociations = new SparseArray<>();
967    boolean mTrackingAssociations;
968
969    /**
970     * Backup/restore process management
971     */
972    String mBackupAppName = null;
973    BackupRecord mBackupTarget = null;
974
975    final ProviderMap mProviderMap;
976
977    /**
978     * List of content providers who have clients waiting for them.  The
979     * application is currently being launched and the provider will be
980     * removed from this list once it is published.
981     */
982    final ArrayList<ContentProviderRecord> mLaunchingProviders
983            = new ArrayList<ContentProviderRecord>();
984
985    /**
986     * File storing persisted {@link #mGrantedUriPermissions}.
987     */
988    private final AtomicFile mGrantFile;
989
990    /** XML constants used in {@link #mGrantFile} */
991    private static final String TAG_URI_GRANTS = "uri-grants";
992    private static final String TAG_URI_GRANT = "uri-grant";
993    private static final String ATTR_USER_HANDLE = "userHandle";
994    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
995    private static final String ATTR_TARGET_USER_ID = "targetUserId";
996    private static final String ATTR_SOURCE_PKG = "sourcePkg";
997    private static final String ATTR_TARGET_PKG = "targetPkg";
998    private static final String ATTR_URI = "uri";
999    private static final String ATTR_MODE_FLAGS = "modeFlags";
1000    private static final String ATTR_CREATED_TIME = "createdTime";
1001    private static final String ATTR_PREFIX = "prefix";
1002
1003    /**
1004     * Global set of specific {@link Uri} permissions that have been granted.
1005     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1006     * to {@link UriPermission#uri} to {@link UriPermission}.
1007     */
1008    @GuardedBy("this")
1009    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1010            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1011
1012    public static class GrantUri {
1013        public final int sourceUserId;
1014        public final Uri uri;
1015        public boolean prefix;
1016
1017        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1018            this.sourceUserId = sourceUserId;
1019            this.uri = uri;
1020            this.prefix = prefix;
1021        }
1022
1023        @Override
1024        public int hashCode() {
1025            int hashCode = 1;
1026            hashCode = 31 * hashCode + sourceUserId;
1027            hashCode = 31 * hashCode + uri.hashCode();
1028            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1029            return hashCode;
1030        }
1031
1032        @Override
1033        public boolean equals(Object o) {
1034            if (o instanceof GrantUri) {
1035                GrantUri other = (GrantUri) o;
1036                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1037                        && prefix == other.prefix;
1038            }
1039            return false;
1040        }
1041
1042        @Override
1043        public String toString() {
1044            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1045            if (prefix) result += " [prefix]";
1046            return result;
1047        }
1048
1049        public String toSafeString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1056            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1057                    ContentProvider.getUriWithoutUserId(uri), false);
1058        }
1059    }
1060
1061    CoreSettingsObserver mCoreSettingsObserver;
1062
1063    FontScaleSettingObserver mFontScaleSettingObserver;
1064
1065    private final class FontScaleSettingObserver extends ContentObserver {
1066        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1067
1068        public FontScaleSettingObserver() {
1069            super(mHandler);
1070            ContentResolver resolver = mContext.getContentResolver();
1071            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1072        }
1073
1074        @Override
1075        public void onChange(boolean selfChange, Uri uri) {
1076            if (mFontScaleUri.equals(uri)) {
1077                updateFontScaleIfNeeded();
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Thread-local storage used to carry caller permissions over through
1084     * indirect content-provider access.
1085     */
1086    private class Identity {
1087        public final IBinder token;
1088        public final int pid;
1089        public final int uid;
1090
1091        Identity(IBinder _token, int _pid, int _uid) {
1092            token = _token;
1093            pid = _pid;
1094            uid = _uid;
1095        }
1096    }
1097
1098    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1099
1100    /**
1101     * All information we have collected about the runtime performance of
1102     * any user id that can impact battery performance.
1103     */
1104    final BatteryStatsService mBatteryStatsService;
1105
1106    /**
1107     * Information about component usage
1108     */
1109    UsageStatsManagerInternal mUsageStatsService;
1110
1111    /**
1112     * Access to DeviceIdleController service.
1113     */
1114    DeviceIdleController.LocalService mLocalDeviceIdleController;
1115
1116    /**
1117     * Information about and control over application operations
1118     */
1119    final AppOpsService mAppOpsService;
1120
1121    /**
1122     * Current configuration information.  HistoryRecord objects are given
1123     * a reference to this object to indicate which configuration they are
1124     * currently running in, so this object must be kept immutable.
1125     */
1126    Configuration mConfiguration = new Configuration();
1127
1128    /**
1129     * Current sequencing integer of the configuration, for skipping old
1130     * configurations.
1131     */
1132    int mConfigurationSeq = 0;
1133
1134    boolean mSuppressResizeConfigChanges = false;
1135
1136    /**
1137     * Hardware-reported OpenGLES version.
1138     */
1139    final int GL_ES_VERSION;
1140
1141    /**
1142     * List of initialization arguments to pass to all processes when binding applications to them.
1143     * For example, references to the commonly used services.
1144     */
1145    HashMap<String, IBinder> mAppBindArgs;
1146
1147    /**
1148     * Temporary to avoid allocations.  Protected by main lock.
1149     */
1150    final StringBuilder mStringBuilder = new StringBuilder(256);
1151
1152    /**
1153     * Used to control how we initialize the service.
1154     */
1155    ComponentName mTopComponent;
1156    String mTopAction = Intent.ACTION_MAIN;
1157    String mTopData;
1158
1159    volatile boolean mProcessesReady = false;
1160    volatile boolean mSystemReady = false;
1161    volatile boolean mOnBattery = false;
1162    volatile int mFactoryTest;
1163
1164    @GuardedBy("this") boolean mBooting = false;
1165    @GuardedBy("this") boolean mCallFinishBooting = false;
1166    @GuardedBy("this") boolean mBootAnimationComplete = false;
1167    @GuardedBy("this") boolean mLaunchWarningShown = false;
1168    @GuardedBy("this") boolean mCheckedForSetup = false;
1169
1170    Context mContext;
1171
1172    /**
1173     * The time at which we will allow normal application switches again,
1174     * after a call to {@link #stopAppSwitches()}.
1175     */
1176    long mAppSwitchesAllowedTime;
1177
1178    /**
1179     * This is set to true after the first switch after mAppSwitchesAllowedTime
1180     * is set; any switches after that will clear the time.
1181     */
1182    boolean mDidAppSwitch;
1183
1184    /**
1185     * Last time (in realtime) at which we checked for power usage.
1186     */
1187    long mLastPowerCheckRealtime;
1188
1189    /**
1190     * Last time (in uptime) at which we checked for power usage.
1191     */
1192    long mLastPowerCheckUptime;
1193
1194    /**
1195     * Set while we are wanting to sleep, to prevent any
1196     * activities from being started/resumed.
1197     */
1198    private boolean mSleeping = false;
1199
1200    /**
1201     * The process state used for processes that are running the top activities.
1202     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1203     */
1204    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1205
1206    /**
1207     * Set while we are running a voice interaction.  This overrides
1208     * sleeping while it is active.
1209     */
1210    private IVoiceInteractionSession mRunningVoice;
1211
1212    /**
1213     * For some direct access we need to power manager.
1214     */
1215    PowerManagerInternal mLocalPowerManager;
1216
1217    /**
1218     * We want to hold a wake lock while running a voice interaction session, since
1219     * this may happen with the screen off and we need to keep the CPU running to
1220     * be able to continue to interact with the user.
1221     */
1222    PowerManager.WakeLock mVoiceWakeLock;
1223
1224    /**
1225     * State of external calls telling us if the device is awake or asleep.
1226     */
1227    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1228
1229    /**
1230     * A list of tokens that cause the top activity to be put to sleep.
1231     * They are used by components that may hide and block interaction with underlying
1232     * activities.
1233     */
1234    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1235
1236    static final int LOCK_SCREEN_HIDDEN = 0;
1237    static final int LOCK_SCREEN_LEAVING = 1;
1238    static final int LOCK_SCREEN_SHOWN = 2;
1239    /**
1240     * State of external call telling us if the lock screen is shown.
1241     */
1242    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1243
1244    /**
1245     * Set if we are shutting down the system, similar to sleeping.
1246     */
1247    boolean mShuttingDown = false;
1248
1249    /**
1250     * Current sequence id for oom_adj computation traversal.
1251     */
1252    int mAdjSeq = 0;
1253
1254    /**
1255     * Current sequence id for process LRU updating.
1256     */
1257    int mLruSeq = 0;
1258
1259    /**
1260     * Keep track of the non-cached/empty process we last found, to help
1261     * determine how to distribute cached/empty processes next time.
1262     */
1263    int mNumNonCachedProcs = 0;
1264
1265    /**
1266     * Keep track of the number of cached hidden procs, to balance oom adj
1267     * distribution between those and empty procs.
1268     */
1269    int mNumCachedHiddenProcs = 0;
1270
1271    /**
1272     * Keep track of the number of service processes we last found, to
1273     * determine on the next iteration which should be B services.
1274     */
1275    int mNumServiceProcs = 0;
1276    int mNewNumAServiceProcs = 0;
1277    int mNewNumServiceProcs = 0;
1278
1279    /**
1280     * Allow the current computed overall memory level of the system to go down?
1281     * This is set to false when we are killing processes for reasons other than
1282     * memory management, so that the now smaller process list will not be taken as
1283     * an indication that memory is tighter.
1284     */
1285    boolean mAllowLowerMemLevel = false;
1286
1287    /**
1288     * The last computed memory level, for holding when we are in a state that
1289     * processes are going away for other reasons.
1290     */
1291    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1292
1293    /**
1294     * The last total number of process we have, to determine if changes actually look
1295     * like a shrinking number of process due to lower RAM.
1296     */
1297    int mLastNumProcesses;
1298
1299    /**
1300     * The uptime of the last time we performed idle maintenance.
1301     */
1302    long mLastIdleTime = SystemClock.uptimeMillis();
1303
1304    /**
1305     * Total time spent with RAM that has been added in the past since the last idle time.
1306     */
1307    long mLowRamTimeSinceLastIdle = 0;
1308
1309    /**
1310     * If RAM is currently low, when that horrible situation started.
1311     */
1312    long mLowRamStartTime = 0;
1313
1314    /**
1315     * For reporting to battery stats the current top application.
1316     */
1317    private String mCurResumedPackage = null;
1318    private int mCurResumedUid = -1;
1319
1320    /**
1321     * For reporting to battery stats the apps currently running foreground
1322     * service.  The ProcessMap is package/uid tuples; each of these contain
1323     * an array of the currently foreground processes.
1324     */
1325    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1326            = new ProcessMap<ArrayList<ProcessRecord>>();
1327
1328    /**
1329     * This is set if we had to do a delayed dexopt of an app before launching
1330     * it, to increase the ANR timeouts in that case.
1331     */
1332    boolean mDidDexOpt;
1333
1334    /**
1335     * Set if the systemServer made a call to enterSafeMode.
1336     */
1337    boolean mSafeMode;
1338
1339    /**
1340     * If true, we are running under a test environment so will sample PSS from processes
1341     * much more rapidly to try to collect better data when the tests are rapidly
1342     * running through apps.
1343     */
1344    boolean mTestPssMode = false;
1345
1346    String mDebugApp = null;
1347    boolean mWaitForDebugger = false;
1348    boolean mDebugTransient = false;
1349    String mOrigDebugApp = null;
1350    boolean mOrigWaitForDebugger = false;
1351    boolean mAlwaysFinishActivities = false;
1352    boolean mLenientBackgroundCheck = false;
1353    boolean mForceResizableActivities;
1354    boolean mSupportsMultiWindow;
1355    boolean mSupportsFreeformWindowManagement;
1356    boolean mSupportsPictureInPicture;
1357    boolean mSupportsLeanbackOnly;
1358    Rect mDefaultPinnedStackBounds;
1359    IActivityController mController = null;
1360    boolean mControllerIsAMonkey = false;
1361    String mProfileApp = null;
1362    ProcessRecord mProfileProc = null;
1363    String mProfileFile;
1364    ParcelFileDescriptor mProfileFd;
1365    int mSamplingInterval = 0;
1366    boolean mAutoStopProfiler = false;
1367    int mProfileType = 0;
1368    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1369    String mMemWatchDumpProcName;
1370    String mMemWatchDumpFile;
1371    int mMemWatchDumpPid;
1372    int mMemWatchDumpUid;
1373    String mTrackAllocationApp = null;
1374    String mNativeDebuggingApp = null;
1375
1376    final long[] mTmpLong = new long[2];
1377
1378    static final class ProcessChangeItem {
1379        static final int CHANGE_ACTIVITIES = 1<<0;
1380        static final int CHANGE_PROCESS_STATE = 1<<1;
1381        int changes;
1382        int uid;
1383        int pid;
1384        int processState;
1385        boolean foregroundActivities;
1386    }
1387
1388    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1389    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1390
1391    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1392    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1393
1394    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1395    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1396
1397    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1398    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1399
1400    /**
1401     * Runtime CPU use collection thread.  This object's lock is used to
1402     * perform synchronization with the thread (notifying it to run).
1403     */
1404    final Thread mProcessCpuThread;
1405
1406    /**
1407     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1408     * Must acquire this object's lock when accessing it.
1409     * NOTE: this lock will be held while doing long operations (trawling
1410     * through all processes in /proc), so it should never be acquired by
1411     * any critical paths such as when holding the main activity manager lock.
1412     */
1413    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1414            MONITOR_THREAD_CPU_USAGE);
1415    final AtomicLong mLastCpuTime = new AtomicLong(0);
1416    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1417
1418    long mLastWriteTime = 0;
1419
1420    /**
1421     * Used to retain an update lock when the foreground activity is in
1422     * immersive mode.
1423     */
1424    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1425
1426    /**
1427     * Set to true after the system has finished booting.
1428     */
1429    boolean mBooted = false;
1430
1431    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1432    int mProcessLimitOverride = -1;
1433
1434    WindowManagerService mWindowManager;
1435    final ActivityThread mSystemThread;
1436
1437    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1438        final ProcessRecord mApp;
1439        final int mPid;
1440        final IApplicationThread mAppThread;
1441
1442        AppDeathRecipient(ProcessRecord app, int pid,
1443                IApplicationThread thread) {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "New death recipient " + this
1446                + " for thread " + thread.asBinder());
1447            mApp = app;
1448            mPid = pid;
1449            mAppThread = thread;
1450        }
1451
1452        @Override
1453        public void binderDied() {
1454            if (DEBUG_ALL) Slog.v(
1455                TAG, "Death received in " + this
1456                + " for thread " + mAppThread.asBinder());
1457            synchronized(ActivityManagerService.this) {
1458                appDiedLocked(mApp, mPid, mAppThread, true);
1459            }
1460        }
1461    }
1462
1463    static final int SHOW_ERROR_UI_MSG = 1;
1464    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1465    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1466    static final int UPDATE_CONFIGURATION_MSG = 4;
1467    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1468    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1469    static final int SERVICE_TIMEOUT_MSG = 12;
1470    static final int UPDATE_TIME_ZONE = 13;
1471    static final int SHOW_UID_ERROR_UI_MSG = 14;
1472    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1473    static final int PROC_START_TIMEOUT_MSG = 20;
1474    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1475    static final int KILL_APPLICATION_MSG = 22;
1476    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1477    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1478    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1479    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1480    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1481    static final int CLEAR_DNS_CACHE_MSG = 28;
1482    static final int UPDATE_HTTP_PROXY_MSG = 29;
1483    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1484    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1485    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1486    static final int REPORT_MEM_USAGE_MSG = 33;
1487    static final int REPORT_USER_SWITCH_MSG = 34;
1488    static final int CONTINUE_USER_SWITCH_MSG = 35;
1489    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1490    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1491    static final int PERSIST_URI_GRANTS_MSG = 38;
1492    static final int REQUEST_ALL_PSS_MSG = 39;
1493    static final int START_PROFILES_MSG = 40;
1494    static final int UPDATE_TIME = 41;
1495    static final int SYSTEM_USER_START_MSG = 42;
1496    static final int SYSTEM_USER_CURRENT_MSG = 43;
1497    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1498    static final int FINISH_BOOTING_MSG = 45;
1499    static final int START_USER_SWITCH_UI_MSG = 46;
1500    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1501    static final int DISMISS_DIALOG_UI_MSG = 48;
1502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1503    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1504    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1505    static final int DELETE_DUMPHEAP_MSG = 52;
1506    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1507    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1508    static final int REPORT_TIME_TRACKER_MSG = 55;
1509    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1510    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1511    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1513    static final int IDLE_UIDS_MSG = 60;
1514    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1515    static final int LOG_STACK_STATE = 62;
1516    static final int VR_MODE_CHANGE_MSG = 63;
1517    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1518    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1519    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1520    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1521    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1522    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1523    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1524
1525    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1526    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1527    static final int FIRST_COMPAT_MODE_MSG = 300;
1528    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1529
1530    static ServiceThread sKillThread = null;
1531    static KillHandler sKillHandler = null;
1532
1533    CompatModeDialog mCompatModeDialog;
1534    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1535    long mLastMemUsageReportTime = 0;
1536
1537    /**
1538     * Flag whether the current user is a "monkey", i.e. whether
1539     * the UI is driven by a UI automation tool.
1540     */
1541    private boolean mUserIsMonkey;
1542
1543    /** Flag whether the device has a Recents UI */
1544    boolean mHasRecents;
1545
1546    /** The dimensions of the thumbnails in the Recents UI. */
1547    int mThumbnailWidth;
1548    int mThumbnailHeight;
1549    float mFullscreenThumbnailScale;
1550
1551    final ServiceThread mHandlerThread;
1552    final MainHandler mHandler;
1553    final UiHandler mUiHandler;
1554
1555    PackageManagerInternal mPackageManagerInt;
1556
1557    // VoiceInteraction session ID that changes for each new request except when
1558    // being called for multiwindow assist in a single session.
1559    private int mViSessionId = 1000;
1560
1561    final boolean mPermissionReviewRequired;
1562
1563    final class KillHandler extends Handler {
1564        static final int KILL_PROCESS_GROUP_MSG = 4000;
1565
1566        public KillHandler(Looper looper) {
1567            super(looper, null, true);
1568        }
1569
1570        @Override
1571        public void handleMessage(Message msg) {
1572            switch (msg.what) {
1573                case KILL_PROCESS_GROUP_MSG:
1574                {
1575                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1576                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1577                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1578                }
1579                break;
1580
1581                default:
1582                    super.handleMessage(msg);
1583            }
1584        }
1585    }
1586
1587    final class UiHandler extends Handler {
1588        public UiHandler() {
1589            super(com.android.server.UiThread.get().getLooper(), null, true);
1590        }
1591
1592        @Override
1593        public void handleMessage(Message msg) {
1594            switch (msg.what) {
1595            case SHOW_ERROR_UI_MSG: {
1596                mAppErrors.handleShowAppErrorUi(msg);
1597                ensureBootCompleted();
1598            } break;
1599            case SHOW_NOT_RESPONDING_UI_MSG: {
1600                mAppErrors.handleShowAnrUi(msg);
1601                ensureBootCompleted();
1602            } break;
1603            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605                synchronized (ActivityManagerService.this) {
1606                    ProcessRecord proc = (ProcessRecord) data.get("app");
1607                    if (proc == null) {
1608                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1609                        break;
1610                    }
1611                    if (proc.crashDialog != null) {
1612                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1613                        return;
1614                    }
1615                    AppErrorResult res = (AppErrorResult) data.get("result");
1616                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617                        Dialog d = new StrictModeViolationDialog(mContext,
1618                                ActivityManagerService.this, res, proc);
1619                        d.show();
1620                        proc.crashDialog = d;
1621                    } else {
1622                        // The device is asleep, so just pretend that the user
1623                        // saw a crash dialog and hit "force quit".
1624                        res.set(0);
1625                    }
1626                }
1627                ensureBootCompleted();
1628            } break;
1629            case SHOW_FACTORY_ERROR_UI_MSG: {
1630                Dialog d = new FactoryErrorDialog(
1631                    mContext, msg.getData().getCharSequence("msg"));
1632                d.show();
1633                ensureBootCompleted();
1634            } break;
1635            case WAIT_FOR_DEBUGGER_UI_MSG: {
1636                synchronized (ActivityManagerService.this) {
1637                    ProcessRecord app = (ProcessRecord)msg.obj;
1638                    if (msg.arg1 != 0) {
1639                        if (!app.waitedForDebugger) {
1640                            Dialog d = new AppWaitingForDebuggerDialog(
1641                                    ActivityManagerService.this,
1642                                    mContext, app);
1643                            app.waitDialog = d;
1644                            app.waitedForDebugger = true;
1645                            d.show();
1646                        }
1647                    } else {
1648                        if (app.waitDialog != null) {
1649                            app.waitDialog.dismiss();
1650                            app.waitDialog = null;
1651                        }
1652                    }
1653                }
1654            } break;
1655            case SHOW_UID_ERROR_UI_MSG: {
1656                if (mShowDialogs) {
1657                    AlertDialog d = new BaseErrorDialog(mContext);
1658                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659                    d.setCancelable(false);
1660                    d.setTitle(mContext.getText(R.string.android_system_label));
1661                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1664                    d.show();
1665                }
1666            } break;
1667            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1668                if (mShowDialogs) {
1669                    AlertDialog d = new BaseErrorDialog(mContext);
1670                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671                    d.setCancelable(false);
1672                    d.setTitle(mContext.getText(R.string.android_system_label));
1673                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1676                    d.show();
1677                }
1678            } break;
1679            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680                synchronized (ActivityManagerService.this) {
1681                    ActivityRecord ar = (ActivityRecord) msg.obj;
1682                    if (mCompatModeDialog != null) {
1683                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1684                                ar.info.applicationInfo.packageName)) {
1685                            return;
1686                        }
1687                        mCompatModeDialog.dismiss();
1688                        mCompatModeDialog = null;
1689                    }
1690                    if (ar != null && false) {
1691                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1692                                ar.packageName)) {
1693                            int mode = mCompatModePackages.computeCompatModeLocked(
1694                                    ar.info.applicationInfo);
1695                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697                                mCompatModeDialog = new CompatModeDialog(
1698                                        ActivityManagerService.this, mContext,
1699                                        ar.info.applicationInfo);
1700                                mCompatModeDialog.show();
1701                            }
1702                        }
1703                    }
1704                }
1705                break;
1706            }
1707            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1708                synchronized (ActivityManagerService.this) {
1709                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1710                    if (mUnsupportedDisplaySizeDialog != null) {
1711                        mUnsupportedDisplaySizeDialog.dismiss();
1712                        mUnsupportedDisplaySizeDialog = null;
1713                    }
1714                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1715                            ar.packageName)) {
1716                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1717                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1718                        mUnsupportedDisplaySizeDialog.show();
1719                    }
1720                }
1721                break;
1722            }
1723            case START_USER_SWITCH_UI_MSG: {
1724                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1725                break;
1726            }
1727            case DISMISS_DIALOG_UI_MSG: {
1728                final Dialog d = (Dialog) msg.obj;
1729                d.dismiss();
1730                break;
1731            }
1732            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1733                dispatchProcessesChanged();
1734                break;
1735            }
1736            case DISPATCH_PROCESS_DIED_UI_MSG: {
1737                final int pid = msg.arg1;
1738                final int uid = msg.arg2;
1739                dispatchProcessDied(pid, uid);
1740                break;
1741            }
1742            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1743                dispatchUidsChanged();
1744            } break;
1745            }
1746        }
1747    }
1748
1749    final class MainHandler extends Handler {
1750        public MainHandler(Looper looper) {
1751            super(looper, null, true);
1752        }
1753
1754        @Override
1755        public void handleMessage(Message msg) {
1756            switch (msg.what) {
1757            case UPDATE_CONFIGURATION_MSG: {
1758                final ContentResolver resolver = mContext.getContentResolver();
1759                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1760                        msg.arg1);
1761            } break;
1762            case GC_BACKGROUND_PROCESSES_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    performAppGcsIfAppropriateLocked();
1765                }
1766            } break;
1767            case SERVICE_TIMEOUT_MSG: {
1768                if (mDidDexOpt) {
1769                    mDidDexOpt = false;
1770                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1771                    nmsg.obj = msg.obj;
1772                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1773                    return;
1774                }
1775                mServices.serviceTimeout((ProcessRecord)msg.obj);
1776            } break;
1777            case UPDATE_TIME_ZONE: {
1778                synchronized (ActivityManagerService.this) {
1779                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1780                        ProcessRecord r = mLruProcesses.get(i);
1781                        if (r.thread != null) {
1782                            try {
1783                                r.thread.updateTimeZone();
1784                            } catch (RemoteException ex) {
1785                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1786                            }
1787                        }
1788                    }
1789                }
1790            } break;
1791            case CLEAR_DNS_CACHE_MSG: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.clearDnsCache();
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804            } break;
1805            case UPDATE_HTTP_PROXY_MSG: {
1806                ProxyInfo proxy = (ProxyInfo)msg.obj;
1807                String host = "";
1808                String port = "";
1809                String exclList = "";
1810                Uri pacFileUrl = Uri.EMPTY;
1811                if (proxy != null) {
1812                    host = proxy.getHost();
1813                    port = Integer.toString(proxy.getPort());
1814                    exclList = proxy.getExclusionListAsString();
1815                    pacFileUrl = proxy.getPacFileUrl();
1816                }
1817                synchronized (ActivityManagerService.this) {
1818                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1819                        ProcessRecord r = mLruProcesses.get(i);
1820                        if (r.thread != null) {
1821                            try {
1822                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1823                            } catch (RemoteException ex) {
1824                                Slog.w(TAG, "Failed to update http proxy for: " +
1825                                        r.info.processName);
1826                            }
1827                        }
1828                    }
1829                }
1830            } break;
1831            case PROC_START_TIMEOUT_MSG: {
1832                if (mDidDexOpt) {
1833                    mDidDexOpt = false;
1834                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1835                    nmsg.obj = msg.obj;
1836                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1837                    return;
1838                }
1839                ProcessRecord app = (ProcessRecord)msg.obj;
1840                synchronized (ActivityManagerService.this) {
1841                    processStartTimedOutLocked(app);
1842                }
1843            } break;
1844            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1845                ProcessRecord app = (ProcessRecord)msg.obj;
1846                synchronized (ActivityManagerService.this) {
1847                    processContentProviderPublishTimedOutLocked(app);
1848                }
1849            } break;
1850            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1851                synchronized (ActivityManagerService.this) {
1852                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1853                }
1854            } break;
1855            case KILL_APPLICATION_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    final int appId = msg.arg1;
1858                    final int userId = msg.arg2;
1859                    Bundle bundle = (Bundle)msg.obj;
1860                    String pkg = bundle.getString("pkg");
1861                    String reason = bundle.getString("reason");
1862                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1863                            false, userId, reason);
1864                }
1865            } break;
1866            case FINALIZE_PENDING_INTENT_MSG: {
1867                ((PendingIntentRecord)msg.obj).completeFinalize();
1868            } break;
1869            case POST_HEAVY_NOTIFICATION_MSG: {
1870                INotificationManager inm = NotificationManager.getService();
1871                if (inm == null) {
1872                    return;
1873                }
1874
1875                ActivityRecord root = (ActivityRecord)msg.obj;
1876                ProcessRecord process = root.app;
1877                if (process == null) {
1878                    return;
1879                }
1880
1881                try {
1882                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1883                    String text = mContext.getString(R.string.heavy_weight_notification,
1884                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1885                    Notification notification = new Notification.Builder(context)
1886                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1887                            .setWhen(0)
1888                            .setOngoing(true)
1889                            .setTicker(text)
1890                            .setColor(mContext.getColor(
1891                                    com.android.internal.R.color.system_notification_accent_color))
1892                            .setContentTitle(text)
1893                            .setContentText(
1894                                    mContext.getText(R.string.heavy_weight_notification_detail))
1895                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1896                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1897                                    new UserHandle(root.userId)))
1898                            .build();
1899                    try {
1900                        int[] outId = new int[1];
1901                        inm.enqueueNotificationWithTag("android", "android", null,
1902                                R.string.heavy_weight_notification,
1903                                notification, outId, root.userId);
1904                    } catch (RuntimeException e) {
1905                        Slog.w(ActivityManagerService.TAG,
1906                                "Error showing notification for heavy-weight app", e);
1907                    } catch (RemoteException e) {
1908                    }
1909                } catch (NameNotFoundException e) {
1910                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1911                }
1912            } break;
1913            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1914                INotificationManager inm = NotificationManager.getService();
1915                if (inm == null) {
1916                    return;
1917                }
1918                try {
1919                    inm.cancelNotificationWithTag("android", null,
1920                            R.string.heavy_weight_notification,  msg.arg1);
1921                } catch (RuntimeException e) {
1922                    Slog.w(ActivityManagerService.TAG,
1923                            "Error canceling notification for service", e);
1924                } catch (RemoteException e) {
1925                }
1926            } break;
1927            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1928                synchronized (ActivityManagerService.this) {
1929                    checkExcessivePowerUsageLocked(true);
1930                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1932                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1933                }
1934            } break;
1935            case REPORT_MEM_USAGE_MSG: {
1936                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1937                Thread thread = new Thread() {
1938                    @Override public void run() {
1939                        reportMemUsage(memInfos);
1940                    }
1941                };
1942                thread.start();
1943                break;
1944            }
1945            case REPORT_USER_SWITCH_MSG: {
1946                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1947                break;
1948            }
1949            case CONTINUE_USER_SWITCH_MSG: {
1950                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1951                break;
1952            }
1953            case USER_SWITCH_TIMEOUT_MSG: {
1954                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1955                break;
1956            }
1957            case IMMERSIVE_MODE_LOCK_MSG: {
1958                final boolean nextState = (msg.arg1 != 0);
1959                if (mUpdateLock.isHeld() != nextState) {
1960                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1961                            "Applying new update lock state '" + nextState
1962                            + "' for " + (ActivityRecord)msg.obj);
1963                    if (nextState) {
1964                        mUpdateLock.acquire();
1965                    } else {
1966                        mUpdateLock.release();
1967                    }
1968                }
1969                break;
1970            }
1971            case PERSIST_URI_GRANTS_MSG: {
1972                writeGrantedUriPermissions();
1973                break;
1974            }
1975            case REQUEST_ALL_PSS_MSG: {
1976                synchronized (ActivityManagerService.this) {
1977                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1978                }
1979                break;
1980            }
1981            case START_PROFILES_MSG: {
1982                synchronized (ActivityManagerService.this) {
1983                    mUserController.startProfilesLocked();
1984                }
1985                break;
1986            }
1987            case UPDATE_TIME: {
1988                synchronized (ActivityManagerService.this) {
1989                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1990                        ProcessRecord r = mLruProcesses.get(i);
1991                        if (r.thread != null) {
1992                            try {
1993                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1994                            } catch (RemoteException ex) {
1995                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1996                            }
1997                        }
1998                    }
1999                }
2000                break;
2001            }
2002            case SYSTEM_USER_START_MSG: {
2003                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2004                        Integer.toString(msg.arg1), msg.arg1);
2005                mSystemServiceManager.startUser(msg.arg1);
2006                break;
2007            }
2008            case SYSTEM_USER_UNLOCK_MSG: {
2009                final int userId = msg.arg1;
2010                mSystemServiceManager.unlockUser(userId);
2011                synchronized (ActivityManagerService.this) {
2012                    mRecentTasks.loadUserRecentsLocked(userId);
2013                }
2014                if (userId == UserHandle.USER_SYSTEM) {
2015                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2016                }
2017                installEncryptionUnawareProviders(userId);
2018                mUserController.finishUserUnlocked((UserState) msg.obj);
2019                break;
2020            }
2021            case SYSTEM_USER_CURRENT_MSG: {
2022                mBatteryStatsService.noteEvent(
2023                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2024                        Integer.toString(msg.arg2), msg.arg2);
2025                mBatteryStatsService.noteEvent(
2026                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2027                        Integer.toString(msg.arg1), msg.arg1);
2028                mSystemServiceManager.switchUser(msg.arg1);
2029                break;
2030            }
2031            case ENTER_ANIMATION_COMPLETE_MSG: {
2032                synchronized (ActivityManagerService.this) {
2033                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2034                    if (r != null && r.app != null && r.app.thread != null) {
2035                        try {
2036                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2037                        } catch (RemoteException e) {
2038                        }
2039                    }
2040                }
2041                break;
2042            }
2043            case FINISH_BOOTING_MSG: {
2044                if (msg.arg1 != 0) {
2045                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2046                    finishBooting();
2047                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2048                }
2049                if (msg.arg2 != 0) {
2050                    enableScreenAfterBoot();
2051                }
2052                break;
2053            }
2054            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2055                try {
2056                    Locale l = (Locale) msg.obj;
2057                    IBinder service = ServiceManager.getService("mount");
2058                    IMountService mountService = IMountService.Stub.asInterface(service);
2059                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2060                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2061                } catch (RemoteException e) {
2062                    Log.e(TAG, "Error storing locale for decryption UI", e);
2063                }
2064                break;
2065            }
2066            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2067                synchronized (ActivityManagerService.this) {
2068                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2069                        try {
2070                            // Make a one-way callback to the listener
2071                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2072                        } catch (RemoteException e){
2073                            // Handled by the RemoteCallbackList
2074                        }
2075                    }
2076                    mTaskStackListeners.finishBroadcast();
2077                }
2078                break;
2079            }
2080            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2081                synchronized (ActivityManagerService.this) {
2082                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2083                        try {
2084                            // Make a one-way callback to the listener
2085                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2086                        } catch (RemoteException e){
2087                            // Handled by the RemoteCallbackList
2088                        }
2089                    }
2090                    mTaskStackListeners.finishBroadcast();
2091                }
2092                break;
2093            }
2094            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2095                synchronized (ActivityManagerService.this) {
2096                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097                        try {
2098                            // Make a one-way callback to the listener
2099                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2100                        } catch (RemoteException e){
2101                            // Handled by the RemoteCallbackList
2102                        }
2103                    }
2104                    mTaskStackListeners.finishBroadcast();
2105                }
2106                break;
2107            }
2108            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2109                synchronized (ActivityManagerService.this) {
2110                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111                        try {
2112                            // Make a one-way callback to the listener
2113                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2114                        } catch (RemoteException e){
2115                            // Handled by the RemoteCallbackList
2116                        }
2117                    }
2118                    mTaskStackListeners.finishBroadcast();
2119                }
2120                break;
2121            }
2122            case NOTIFY_FORCED_RESIZABLE_MSG: {
2123                synchronized (ActivityManagerService.this) {
2124                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2125                        try {
2126                            // Make a one-way callback to the listener
2127                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2128                                    (String) msg.obj, msg.arg1);
2129                        } catch (RemoteException e){
2130                            // Handled by the RemoteCallbackList
2131                        }
2132                    }
2133                    mTaskStackListeners.finishBroadcast();
2134                }
2135                break;
2136            }
2137                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2138                    synchronized (ActivityManagerService.this) {
2139                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2140                            try {
2141                                // Make a one-way callback to the listener
2142                                mTaskStackListeners.getBroadcastItem(i)
2143                                        .onActivityDismissingDockedStack();
2144                            } catch (RemoteException e){
2145                                // Handled by the RemoteCallbackList
2146                            }
2147                        }
2148                        mTaskStackListeners.finishBroadcast();
2149                    }
2150                    break;
2151                }
2152            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2153                final int uid = msg.arg1;
2154                final byte[] firstPacket = (byte[]) msg.obj;
2155
2156                synchronized (mPidsSelfLocked) {
2157                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2158                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2159                        if (p.uid == uid) {
2160                            try {
2161                                p.thread.notifyCleartextNetwork(firstPacket);
2162                            } catch (RemoteException ignored) {
2163                            }
2164                        }
2165                    }
2166                }
2167                break;
2168            }
2169            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2170                final String procName;
2171                final int uid;
2172                final long memLimit;
2173                final String reportPackage;
2174                synchronized (ActivityManagerService.this) {
2175                    procName = mMemWatchDumpProcName;
2176                    uid = mMemWatchDumpUid;
2177                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2178                    if (val == null) {
2179                        val = mMemWatchProcesses.get(procName, 0);
2180                    }
2181                    if (val != null) {
2182                        memLimit = val.first;
2183                        reportPackage = val.second;
2184                    } else {
2185                        memLimit = 0;
2186                        reportPackage = null;
2187                    }
2188                }
2189                if (procName == null) {
2190                    return;
2191                }
2192
2193                if (DEBUG_PSS) Slog.d(TAG_PSS,
2194                        "Showing dump heap notification from " + procName + "/" + uid);
2195
2196                INotificationManager inm = NotificationManager.getService();
2197                if (inm == null) {
2198                    return;
2199                }
2200
2201                String text = mContext.getString(R.string.dump_heap_notification, procName);
2202
2203
2204                Intent deleteIntent = new Intent();
2205                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2206                Intent intent = new Intent();
2207                intent.setClassName("android", DumpHeapActivity.class.getName());
2208                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2209                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2210                if (reportPackage != null) {
2211                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2212                }
2213                int userId = UserHandle.getUserId(uid);
2214                Notification notification = new Notification.Builder(mContext)
2215                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2216                        .setWhen(0)
2217                        .setOngoing(true)
2218                        .setAutoCancel(true)
2219                        .setTicker(text)
2220                        .setColor(mContext.getColor(
2221                                com.android.internal.R.color.system_notification_accent_color))
2222                        .setContentTitle(text)
2223                        .setContentText(
2224                                mContext.getText(R.string.dump_heap_notification_detail))
2225                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2226                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2227                                new UserHandle(userId)))
2228                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2229                                deleteIntent, 0, UserHandle.SYSTEM))
2230                        .build();
2231
2232                try {
2233                    int[] outId = new int[1];
2234                    inm.enqueueNotificationWithTag("android", "android", null,
2235                            R.string.dump_heap_notification,
2236                            notification, outId, userId);
2237                } catch (RuntimeException e) {
2238                    Slog.w(ActivityManagerService.TAG,
2239                            "Error showing notification for dump heap", e);
2240                } catch (RemoteException e) {
2241                }
2242            } break;
2243            case DELETE_DUMPHEAP_MSG: {
2244                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2245                        DumpHeapActivity.JAVA_URI,
2246                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2247                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2248                        UserHandle.myUserId());
2249                synchronized (ActivityManagerService.this) {
2250                    mMemWatchDumpFile = null;
2251                    mMemWatchDumpProcName = null;
2252                    mMemWatchDumpPid = -1;
2253                    mMemWatchDumpUid = -1;
2254                }
2255            } break;
2256            case FOREGROUND_PROFILE_CHANGED_MSG: {
2257                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2258            } break;
2259            case REPORT_TIME_TRACKER_MSG: {
2260                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2261                tracker.deliverResult(mContext);
2262            } break;
2263            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2264                mUserController.dispatchUserSwitchComplete(msg.arg1);
2265            } break;
2266            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2267                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2268                try {
2269                    connection.shutdown();
2270                } catch (RemoteException e) {
2271                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2272                }
2273                // Only a UiAutomation can set this flag and now that
2274                // it is finished we make sure it is reset to its default.
2275                mUserIsMonkey = false;
2276            } break;
2277            case APP_BOOST_DEACTIVATE_MSG: {
2278                synchronized(ActivityManagerService.this) {
2279                    if (mIsBoosted) {
2280                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2281                            nativeMigrateFromBoost();
2282                            mIsBoosted = false;
2283                            mBoostStartTime = 0;
2284                        } else {
2285                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2286                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2287                        }
2288                    }
2289                }
2290            } break;
2291            case IDLE_UIDS_MSG: {
2292                idleUids();
2293            } break;
2294            case LOG_STACK_STATE: {
2295                synchronized (ActivityManagerService.this) {
2296                    mStackSupervisor.logStackState();
2297                }
2298            } break;
2299            case VR_MODE_CHANGE_MSG: {
2300                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2301                final ActivityRecord r = (ActivityRecord) msg.obj;
2302                boolean vrMode;
2303                ComponentName requestedPackage;
2304                ComponentName callingPackage;
2305                int userId;
2306                synchronized (ActivityManagerService.this) {
2307                    vrMode = r.requestedVrComponent != null;
2308                    requestedPackage = r.requestedVrComponent;
2309                    userId = r.userId;
2310                    callingPackage = r.info.getComponentName();
2311                    if (mInVrMode != vrMode) {
2312                        mInVrMode = vrMode;
2313                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2314                    }
2315                }
2316                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2317            } break;
2318            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2319                final ActivityRecord r = (ActivityRecord) msg.obj;
2320                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2321                if (needsVrMode) {
2322                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2323                            r.info.getComponentName(), false);
2324                }
2325            } break;
2326            }
2327        }
2328    };
2329
2330    static final int COLLECT_PSS_BG_MSG = 1;
2331
2332    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2333        @Override
2334        public void handleMessage(Message msg) {
2335            switch (msg.what) {
2336            case COLLECT_PSS_BG_MSG: {
2337                long start = SystemClock.uptimeMillis();
2338                MemInfoReader memInfo = null;
2339                synchronized (ActivityManagerService.this) {
2340                    if (mFullPssPending) {
2341                        mFullPssPending = false;
2342                        memInfo = new MemInfoReader();
2343                    }
2344                }
2345                if (memInfo != null) {
2346                    updateCpuStatsNow();
2347                    long nativeTotalPss = 0;
2348                    synchronized (mProcessCpuTracker) {
2349                        final int N = mProcessCpuTracker.countStats();
2350                        for (int j=0; j<N; j++) {
2351                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2352                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2353                                // This is definitely an application process; skip it.
2354                                continue;
2355                            }
2356                            synchronized (mPidsSelfLocked) {
2357                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2358                                    // This is one of our own processes; skip it.
2359                                    continue;
2360                                }
2361                            }
2362                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2363                        }
2364                    }
2365                    memInfo.readMemInfo();
2366                    synchronized (ActivityManagerService.this) {
2367                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2368                                + (SystemClock.uptimeMillis()-start) + "ms");
2369                        final long cachedKb = memInfo.getCachedSizeKb();
2370                        final long freeKb = memInfo.getFreeSizeKb();
2371                        final long zramKb = memInfo.getZramTotalSizeKb();
2372                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2373                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2374                                kernelKb*1024, nativeTotalPss*1024);
2375                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2376                                nativeTotalPss);
2377                    }
2378                }
2379
2380                int num = 0;
2381                long[] tmp = new long[2];
2382                do {
2383                    ProcessRecord proc;
2384                    int procState;
2385                    int pid;
2386                    long lastPssTime;
2387                    synchronized (ActivityManagerService.this) {
2388                        if (mPendingPssProcesses.size() <= 0) {
2389                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2390                                    "Collected PSS of " + num + " processes in "
2391                                    + (SystemClock.uptimeMillis() - start) + "ms");
2392                            mPendingPssProcesses.clear();
2393                            return;
2394                        }
2395                        proc = mPendingPssProcesses.remove(0);
2396                        procState = proc.pssProcState;
2397                        lastPssTime = proc.lastPssTime;
2398                        if (proc.thread != null && procState == proc.setProcState
2399                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2400                                        < SystemClock.uptimeMillis()) {
2401                            pid = proc.pid;
2402                        } else {
2403                            proc = null;
2404                            pid = 0;
2405                        }
2406                    }
2407                    if (proc != null) {
2408                        long pss = Debug.getPss(pid, tmp, null);
2409                        synchronized (ActivityManagerService.this) {
2410                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2411                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2412                                num++;
2413                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2414                                        SystemClock.uptimeMillis());
2415                            }
2416                        }
2417                    }
2418                } while (true);
2419            }
2420            }
2421        }
2422    };
2423
2424    public void setSystemProcess() {
2425        try {
2426            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2427            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2428            ServiceManager.addService("meminfo", new MemBinder(this));
2429            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2430            ServiceManager.addService("dbinfo", new DbBinder(this));
2431            if (MONITOR_CPU_USAGE) {
2432                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2433            }
2434            ServiceManager.addService("permission", new PermissionController(this));
2435            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2436
2437            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2438                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2439            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2440
2441            synchronized (this) {
2442                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2443                app.persistent = true;
2444                app.pid = MY_PID;
2445                app.maxAdj = ProcessList.SYSTEM_ADJ;
2446                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2447                synchronized (mPidsSelfLocked) {
2448                    mPidsSelfLocked.put(app.pid, app);
2449                }
2450                updateLruProcessLocked(app, false, null);
2451                updateOomAdjLocked();
2452            }
2453        } catch (PackageManager.NameNotFoundException e) {
2454            throw new RuntimeException(
2455                    "Unable to find android system package", e);
2456        }
2457    }
2458
2459    public void setWindowManager(WindowManagerService wm) {
2460        mWindowManager = wm;
2461        mStackSupervisor.setWindowManager(wm);
2462        mActivityStarter.setWindowManager(wm);
2463    }
2464
2465    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2466        mUsageStatsService = usageStatsManager;
2467    }
2468
2469    public void startObservingNativeCrashes() {
2470        final NativeCrashListener ncl = new NativeCrashListener(this);
2471        ncl.start();
2472    }
2473
2474    public IAppOpsService getAppOpsService() {
2475        return mAppOpsService;
2476    }
2477
2478    static class MemBinder extends Binder {
2479        ActivityManagerService mActivityManagerService;
2480        MemBinder(ActivityManagerService activityManagerService) {
2481            mActivityManagerService = activityManagerService;
2482        }
2483
2484        @Override
2485        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2486            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2487                    != PackageManager.PERMISSION_GRANTED) {
2488                pw.println("Permission Denial: can't dump meminfo from from pid="
2489                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2490                        + " without permission " + android.Manifest.permission.DUMP);
2491                return;
2492            }
2493
2494            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2495        }
2496    }
2497
2498    static class GraphicsBinder extends Binder {
2499        ActivityManagerService mActivityManagerService;
2500        GraphicsBinder(ActivityManagerService activityManagerService) {
2501            mActivityManagerService = activityManagerService;
2502        }
2503
2504        @Override
2505        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2506            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2507                    != PackageManager.PERMISSION_GRANTED) {
2508                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2509                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2510                        + " without permission " + android.Manifest.permission.DUMP);
2511                return;
2512            }
2513
2514            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2515        }
2516    }
2517
2518    static class DbBinder extends Binder {
2519        ActivityManagerService mActivityManagerService;
2520        DbBinder(ActivityManagerService activityManagerService) {
2521            mActivityManagerService = activityManagerService;
2522        }
2523
2524        @Override
2525        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2526            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2527                    != PackageManager.PERMISSION_GRANTED) {
2528                pw.println("Permission Denial: can't dump dbinfo from from pid="
2529                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2530                        + " without permission " + android.Manifest.permission.DUMP);
2531                return;
2532            }
2533
2534            mActivityManagerService.dumpDbInfo(fd, pw, args);
2535        }
2536    }
2537
2538    static class CpuBinder extends Binder {
2539        ActivityManagerService mActivityManagerService;
2540        CpuBinder(ActivityManagerService activityManagerService) {
2541            mActivityManagerService = activityManagerService;
2542        }
2543
2544        @Override
2545        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2546            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2547                    != PackageManager.PERMISSION_GRANTED) {
2548                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2549                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2550                        + " without permission " + android.Manifest.permission.DUMP);
2551                return;
2552            }
2553
2554            synchronized (mActivityManagerService.mProcessCpuTracker) {
2555                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2556                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2557                        SystemClock.uptimeMillis()));
2558            }
2559        }
2560    }
2561
2562    public static final class Lifecycle extends SystemService {
2563        private final ActivityManagerService mService;
2564
2565        public Lifecycle(Context context) {
2566            super(context);
2567            mService = new ActivityManagerService(context);
2568        }
2569
2570        @Override
2571        public void onStart() {
2572            mService.start();
2573        }
2574
2575        public ActivityManagerService getService() {
2576            return mService;
2577        }
2578    }
2579
2580    // Note: This method is invoked on the main thread but may need to attach various
2581    // handlers to other threads.  So take care to be explicit about the looper.
2582    public ActivityManagerService(Context systemContext) {
2583        mContext = systemContext;
2584        mFactoryTest = FactoryTest.getMode();
2585        mSystemThread = ActivityThread.currentActivityThread();
2586
2587        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2588
2589        mPermissionReviewRequired = mContext.getResources().getBoolean(
2590                com.android.internal.R.bool.config_permissionReviewRequired);
2591
2592        mHandlerThread = new ServiceThread(TAG,
2593                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2594        mHandlerThread.start();
2595        mHandler = new MainHandler(mHandlerThread.getLooper());
2596        mUiHandler = new UiHandler();
2597
2598        /* static; one-time init here */
2599        if (sKillHandler == null) {
2600            sKillThread = new ServiceThread(TAG + ":kill",
2601                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2602            sKillThread.start();
2603            sKillHandler = new KillHandler(sKillThread.getLooper());
2604        }
2605
2606        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2607                "foreground", BROADCAST_FG_TIMEOUT, false);
2608        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2609                "background", BROADCAST_BG_TIMEOUT, true);
2610        mBroadcastQueues[0] = mFgBroadcastQueue;
2611        mBroadcastQueues[1] = mBgBroadcastQueue;
2612
2613        mServices = new ActiveServices(this);
2614        mProviderMap = new ProviderMap(this);
2615        mAppErrors = new AppErrors(mContext, this);
2616
2617        // TODO: Move creation of battery stats service outside of activity manager service.
2618        File dataDir = Environment.getDataDirectory();
2619        File systemDir = new File(dataDir, "system");
2620        systemDir.mkdirs();
2621        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2622        mBatteryStatsService.getActiveStatistics().readLocked();
2623        mBatteryStatsService.scheduleWriteToDisk();
2624        mOnBattery = DEBUG_POWER ? true
2625                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2626        mBatteryStatsService.getActiveStatistics().setCallback(this);
2627
2628        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2629
2630        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2631        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2632                new IAppOpsCallback.Stub() {
2633                    @Override public void opChanged(int op, int uid, String packageName) {
2634                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2635                            if (mAppOpsService.checkOperation(op, uid, packageName)
2636                                    != AppOpsManager.MODE_ALLOWED) {
2637                                runInBackgroundDisabled(uid);
2638                            }
2639                        }
2640                    }
2641                });
2642
2643        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2644
2645        mUserController = new UserController(this);
2646
2647        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2648            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2649
2650        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2651
2652        mConfiguration.setToDefaults();
2653        mConfiguration.setLocales(LocaleList.getDefault());
2654
2655        mConfigurationSeq = mConfiguration.seq = 1;
2656        mProcessCpuTracker.init();
2657
2658        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2659        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2660        mStackSupervisor = new ActivityStackSupervisor(this);
2661        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2662        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2663
2664        mProcessCpuThread = new Thread("CpuTracker") {
2665            @Override
2666            public void run() {
2667                while (true) {
2668                    try {
2669                        try {
2670                            synchronized(this) {
2671                                final long now = SystemClock.uptimeMillis();
2672                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2673                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2674                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2675                                //        + ", write delay=" + nextWriteDelay);
2676                                if (nextWriteDelay < nextCpuDelay) {
2677                                    nextCpuDelay = nextWriteDelay;
2678                                }
2679                                if (nextCpuDelay > 0) {
2680                                    mProcessCpuMutexFree.set(true);
2681                                    this.wait(nextCpuDelay);
2682                                }
2683                            }
2684                        } catch (InterruptedException e) {
2685                        }
2686                        updateCpuStatsNow();
2687                    } catch (Exception e) {
2688                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2689                    }
2690                }
2691            }
2692        };
2693
2694        Watchdog.getInstance().addMonitor(this);
2695        Watchdog.getInstance().addThread(mHandler);
2696    }
2697
2698    public void setSystemServiceManager(SystemServiceManager mgr) {
2699        mSystemServiceManager = mgr;
2700    }
2701
2702    public void setInstaller(Installer installer) {
2703        mInstaller = installer;
2704    }
2705
2706    private void start() {
2707        Process.removeAllProcessGroups();
2708        mProcessCpuThread.start();
2709
2710        mBatteryStatsService.publish(mContext);
2711        mAppOpsService.publish(mContext);
2712        Slog.d("AppOps", "AppOpsService published");
2713        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2714    }
2715
2716    void onUserStoppedLocked(int userId) {
2717        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2718    }
2719
2720    public void initPowerManagement() {
2721        mStackSupervisor.initPowerManagement();
2722        mBatteryStatsService.initPowerManagement();
2723        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2724        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2725        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2726        mVoiceWakeLock.setReferenceCounted(false);
2727    }
2728
2729    @Override
2730    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2731            throws RemoteException {
2732        if (code == SYSPROPS_TRANSACTION) {
2733            // We need to tell all apps about the system property change.
2734            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2735            synchronized(this) {
2736                final int NP = mProcessNames.getMap().size();
2737                for (int ip=0; ip<NP; ip++) {
2738                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2739                    final int NA = apps.size();
2740                    for (int ia=0; ia<NA; ia++) {
2741                        ProcessRecord app = apps.valueAt(ia);
2742                        if (app.thread != null) {
2743                            procs.add(app.thread.asBinder());
2744                        }
2745                    }
2746                }
2747            }
2748
2749            int N = procs.size();
2750            for (int i=0; i<N; i++) {
2751                Parcel data2 = Parcel.obtain();
2752                try {
2753                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2754                } catch (RemoteException e) {
2755                }
2756                data2.recycle();
2757            }
2758        }
2759        try {
2760            return super.onTransact(code, data, reply, flags);
2761        } catch (RuntimeException e) {
2762            // The activity manager only throws security exceptions, so let's
2763            // log all others.
2764            if (!(e instanceof SecurityException)) {
2765                Slog.wtf(TAG, "Activity Manager Crash", e);
2766            }
2767            throw e;
2768        }
2769    }
2770
2771    void updateCpuStats() {
2772        final long now = SystemClock.uptimeMillis();
2773        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2774            return;
2775        }
2776        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2777            synchronized (mProcessCpuThread) {
2778                mProcessCpuThread.notify();
2779            }
2780        }
2781    }
2782
2783    void updateCpuStatsNow() {
2784        synchronized (mProcessCpuTracker) {
2785            mProcessCpuMutexFree.set(false);
2786            final long now = SystemClock.uptimeMillis();
2787            boolean haveNewCpuStats = false;
2788
2789            if (MONITOR_CPU_USAGE &&
2790                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2791                mLastCpuTime.set(now);
2792                mProcessCpuTracker.update();
2793                if (mProcessCpuTracker.hasGoodLastStats()) {
2794                    haveNewCpuStats = true;
2795                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2796                    //Slog.i(TAG, "Total CPU usage: "
2797                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2798
2799                    // Slog the cpu usage if the property is set.
2800                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2801                        int user = mProcessCpuTracker.getLastUserTime();
2802                        int system = mProcessCpuTracker.getLastSystemTime();
2803                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2804                        int irq = mProcessCpuTracker.getLastIrqTime();
2805                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2806                        int idle = mProcessCpuTracker.getLastIdleTime();
2807
2808                        int total = user + system + iowait + irq + softIrq + idle;
2809                        if (total == 0) total = 1;
2810
2811                        EventLog.writeEvent(EventLogTags.CPU,
2812                                ((user+system+iowait+irq+softIrq) * 100) / total,
2813                                (user * 100) / total,
2814                                (system * 100) / total,
2815                                (iowait * 100) / total,
2816                                (irq * 100) / total,
2817                                (softIrq * 100) / total);
2818                    }
2819                }
2820            }
2821
2822            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2823            synchronized(bstats) {
2824                synchronized(mPidsSelfLocked) {
2825                    if (haveNewCpuStats) {
2826                        if (bstats.startAddingCpuLocked()) {
2827                            int totalUTime = 0;
2828                            int totalSTime = 0;
2829                            final int N = mProcessCpuTracker.countStats();
2830                            for (int i=0; i<N; i++) {
2831                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2832                                if (!st.working) {
2833                                    continue;
2834                                }
2835                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2836                                totalUTime += st.rel_utime;
2837                                totalSTime += st.rel_stime;
2838                                if (pr != null) {
2839                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2840                                    if (ps == null || !ps.isActive()) {
2841                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2842                                                pr.info.uid, pr.processName);
2843                                    }
2844                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2845                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2846                                } else {
2847                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2848                                    if (ps == null || !ps.isActive()) {
2849                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2850                                                bstats.mapUid(st.uid), st.name);
2851                                    }
2852                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2853                                }
2854                            }
2855                            final int userTime = mProcessCpuTracker.getLastUserTime();
2856                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2857                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2858                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2859                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2860                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2861                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2862                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2863                        }
2864                    }
2865                }
2866
2867                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2868                    mLastWriteTime = now;
2869                    mBatteryStatsService.scheduleWriteToDisk();
2870                }
2871            }
2872        }
2873    }
2874
2875    @Override
2876    public void batteryNeedsCpuUpdate() {
2877        updateCpuStatsNow();
2878    }
2879
2880    @Override
2881    public void batteryPowerChanged(boolean onBattery) {
2882        // When plugging in, update the CPU stats first before changing
2883        // the plug state.
2884        updateCpuStatsNow();
2885        synchronized (this) {
2886            synchronized(mPidsSelfLocked) {
2887                mOnBattery = DEBUG_POWER ? true : onBattery;
2888            }
2889        }
2890    }
2891
2892    @Override
2893    public void batterySendBroadcast(Intent intent) {
2894        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2895                AppOpsManager.OP_NONE, null, false, false,
2896                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2897    }
2898
2899    /**
2900     * Initialize the application bind args. These are passed to each
2901     * process when the bindApplication() IPC is sent to the process. They're
2902     * lazily setup to make sure the services are running when they're asked for.
2903     */
2904    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2905        if (mAppBindArgs == null) {
2906            mAppBindArgs = new HashMap<>();
2907
2908            // Isolated processes won't get this optimization, so that we don't
2909            // violate the rules about which services they have access to.
2910            if (!isolated) {
2911                // Setup the application init args
2912                mAppBindArgs.put("package", ServiceManager.getService("package"));
2913                mAppBindArgs.put("window", ServiceManager.getService("window"));
2914                mAppBindArgs.put(Context.ALARM_SERVICE,
2915                        ServiceManager.getService(Context.ALARM_SERVICE));
2916            }
2917        }
2918        return mAppBindArgs;
2919    }
2920
2921    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2922        if (r == null || mFocusedActivity == r) {
2923            return false;
2924        }
2925
2926        if (!r.isFocusable()) {
2927            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2928            return false;
2929        }
2930
2931        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2932
2933        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2934        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2935                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2936        mDoingSetFocusedActivity = true;
2937
2938        final ActivityRecord last = mFocusedActivity;
2939        mFocusedActivity = r;
2940        if (r.task.isApplicationTask()) {
2941            if (mCurAppTimeTracker != r.appTimeTracker) {
2942                // We are switching app tracking.  Complete the current one.
2943                if (mCurAppTimeTracker != null) {
2944                    mCurAppTimeTracker.stop();
2945                    mHandler.obtainMessage(
2946                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2947                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2948                    mCurAppTimeTracker = null;
2949                }
2950                if (r.appTimeTracker != null) {
2951                    mCurAppTimeTracker = r.appTimeTracker;
2952                    startTimeTrackingFocusedActivityLocked();
2953                }
2954            } else {
2955                startTimeTrackingFocusedActivityLocked();
2956            }
2957        } else {
2958            r.appTimeTracker = null;
2959        }
2960        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2961        // TODO: Probably not, because we don't want to resume voice on switching
2962        // back to this activity
2963        if (r.task.voiceInteractor != null) {
2964            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2965        } else {
2966            finishRunningVoiceLocked();
2967            IVoiceInteractionSession session;
2968            if (last != null && ((session = last.task.voiceSession) != null
2969                    || (session = last.voiceSession) != null)) {
2970                // We had been in a voice interaction session, but now focused has
2971                // move to something different.  Just finish the session, we can't
2972                // return to it and retain the proper state and synchronization with
2973                // the voice interaction service.
2974                finishVoiceTask(session);
2975            }
2976        }
2977        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2978            mWindowManager.setFocusedApp(r.appToken, true);
2979        }
2980        applyUpdateLockStateLocked(r);
2981        applyUpdateVrModeLocked(r);
2982        if (mFocusedActivity.userId != mLastFocusedUserId) {
2983            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2984            mHandler.obtainMessage(
2985                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2986            mLastFocusedUserId = mFocusedActivity.userId;
2987        }
2988
2989        // Log a warning if the focused app is changed during the process. This could
2990        // indicate a problem of the focus setting logic!
2991        if (mFocusedActivity != r) Slog.w(TAG,
2992                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2993        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2994
2995        EventLogTags.writeAmFocusedActivity(
2996                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2997                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2998                reason);
2999        return true;
3000    }
3001
3002    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3003        if (mFocusedActivity != goingAway) {
3004            return;
3005        }
3006
3007        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3008        if (focusedStack != null) {
3009            final ActivityRecord top = focusedStack.topActivity();
3010            if (top != null && top.userId != mLastFocusedUserId) {
3011                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3012                mHandler.sendMessage(
3013                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3014                mLastFocusedUserId = top.userId;
3015            }
3016        }
3017
3018        // Try to move focus to another activity if possible.
3019        if (setFocusedActivityLocked(
3020                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3021            return;
3022        }
3023
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3025                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3026        mFocusedActivity = null;
3027        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3028    }
3029
3030    @Override
3031    public void setFocusedStack(int stackId) {
3032        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3033        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3034        final long callingId = Binder.clearCallingIdentity();
3035        try {
3036            synchronized (this) {
3037                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3038                if (stack == null) {
3039                    return;
3040                }
3041                final ActivityRecord r = stack.topRunningActivityLocked();
3042                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3043                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3044                }
3045            }
3046        } finally {
3047            Binder.restoreCallingIdentity(callingId);
3048        }
3049    }
3050
3051    @Override
3052    public void setFocusedTask(int taskId) {
3053        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3054        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3055        final long callingId = Binder.clearCallingIdentity();
3056        try {
3057            synchronized (this) {
3058                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3059                if (task == null) {
3060                    return;
3061                }
3062                final ActivityRecord r = task.topRunningActivityLocked();
3063                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3064                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3065                }
3066            }
3067        } finally {
3068            Binder.restoreCallingIdentity(callingId);
3069        }
3070    }
3071
3072    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3073    @Override
3074    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3075        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3076        synchronized (this) {
3077            if (listener != null) {
3078                mTaskStackListeners.register(listener);
3079            }
3080        }
3081    }
3082
3083    @Override
3084    public void notifyActivityDrawn(IBinder token) {
3085        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3086        synchronized (this) {
3087            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3088            if (r != null) {
3089                r.task.stack.notifyActivityDrawnLocked(r);
3090            }
3091        }
3092    }
3093
3094    final void applyUpdateLockStateLocked(ActivityRecord r) {
3095        // Modifications to the UpdateLock state are done on our handler, outside
3096        // the activity manager's locks.  The new state is determined based on the
3097        // state *now* of the relevant activity record.  The object is passed to
3098        // the handler solely for logging detail, not to be consulted/modified.
3099        final boolean nextState = r != null && r.immersive;
3100        mHandler.sendMessage(
3101                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3102    }
3103
3104    final void applyUpdateVrModeLocked(ActivityRecord r) {
3105        mHandler.sendMessage(
3106                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3107    }
3108
3109    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3110        mHandler.sendMessage(
3111                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3112    }
3113
3114    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3115            ComponentName callingPackage, boolean immediate) {
3116        VrManagerInternal vrService =
3117                LocalServices.getService(VrManagerInternal.class);
3118        if (immediate) {
3119            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3120        } else {
3121            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3122        }
3123    }
3124
3125    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3126        Message msg = Message.obtain();
3127        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3128        msg.obj = r.task.askedCompatMode ? null : r;
3129        mUiHandler.sendMessage(msg);
3130    }
3131
3132    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3133        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3134                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3135            final Message msg = Message.obtain();
3136            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3137            msg.obj = r;
3138            mUiHandler.sendMessage(msg);
3139        }
3140    }
3141
3142    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3143            String what, Object obj, ProcessRecord srcApp) {
3144        app.lastActivityTime = now;
3145
3146        if (app.activities.size() > 0) {
3147            // Don't want to touch dependent processes that are hosting activities.
3148            return index;
3149        }
3150
3151        int lrui = mLruProcesses.lastIndexOf(app);
3152        if (lrui < 0) {
3153            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3154                    + what + " " + obj + " from " + srcApp);
3155            return index;
3156        }
3157
3158        if (lrui >= index) {
3159            // Don't want to cause this to move dependent processes *back* in the
3160            // list as if they were less frequently used.
3161            return index;
3162        }
3163
3164        if (lrui >= mLruProcessActivityStart) {
3165            // Don't want to touch dependent processes that are hosting activities.
3166            return index;
3167        }
3168
3169        mLruProcesses.remove(lrui);
3170        if (index > 0) {
3171            index--;
3172        }
3173        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3174                + " in LRU list: " + app);
3175        mLruProcesses.add(index, app);
3176        return index;
3177    }
3178
3179    static void killProcessGroup(int uid, int pid) {
3180        if (sKillHandler != null) {
3181            sKillHandler.sendMessage(
3182                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3183        } else {
3184            Slog.w(TAG, "Asked to kill process group before system bringup!");
3185            Process.killProcessGroup(uid, pid);
3186        }
3187    }
3188
3189    final void removeLruProcessLocked(ProcessRecord app) {
3190        int lrui = mLruProcesses.lastIndexOf(app);
3191        if (lrui >= 0) {
3192            if (!app.killed) {
3193                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3194                Process.killProcessQuiet(app.pid);
3195                killProcessGroup(app.uid, app.pid);
3196            }
3197            if (lrui <= mLruProcessActivityStart) {
3198                mLruProcessActivityStart--;
3199            }
3200            if (lrui <= mLruProcessServiceStart) {
3201                mLruProcessServiceStart--;
3202            }
3203            mLruProcesses.remove(lrui);
3204        }
3205    }
3206
3207    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3208            ProcessRecord client) {
3209        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3210                || app.treatLikeActivity;
3211        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3212        if (!activityChange && hasActivity) {
3213            // The process has activities, so we are only allowing activity-based adjustments
3214            // to move it.  It should be kept in the front of the list with other
3215            // processes that have activities, and we don't want those to change their
3216            // order except due to activity operations.
3217            return;
3218        }
3219
3220        mLruSeq++;
3221        final long now = SystemClock.uptimeMillis();
3222        app.lastActivityTime = now;
3223
3224        // First a quick reject: if the app is already at the position we will
3225        // put it, then there is nothing to do.
3226        if (hasActivity) {
3227            final int N = mLruProcesses.size();
3228            if (N > 0 && mLruProcesses.get(N-1) == app) {
3229                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3230                return;
3231            }
3232        } else {
3233            if (mLruProcessServiceStart > 0
3234                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3235                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3236                return;
3237            }
3238        }
3239
3240        int lrui = mLruProcesses.lastIndexOf(app);
3241
3242        if (app.persistent && lrui >= 0) {
3243            // We don't care about the position of persistent processes, as long as
3244            // they are in the list.
3245            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3246            return;
3247        }
3248
3249        /* In progress: compute new position first, so we can avoid doing work
3250           if the process is not actually going to move.  Not yet working.
3251        int addIndex;
3252        int nextIndex;
3253        boolean inActivity = false, inService = false;
3254        if (hasActivity) {
3255            // Process has activities, put it at the very tipsy-top.
3256            addIndex = mLruProcesses.size();
3257            nextIndex = mLruProcessServiceStart;
3258            inActivity = true;
3259        } else if (hasService) {
3260            // Process has services, put it at the top of the service list.
3261            addIndex = mLruProcessActivityStart;
3262            nextIndex = mLruProcessServiceStart;
3263            inActivity = true;
3264            inService = true;
3265        } else  {
3266            // Process not otherwise of interest, it goes to the top of the non-service area.
3267            addIndex = mLruProcessServiceStart;
3268            if (client != null) {
3269                int clientIndex = mLruProcesses.lastIndexOf(client);
3270                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3271                        + app);
3272                if (clientIndex >= 0 && addIndex > clientIndex) {
3273                    addIndex = clientIndex;
3274                }
3275            }
3276            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3277        }
3278
3279        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3280                + mLruProcessActivityStart + "): " + app);
3281        */
3282
3283        if (lrui >= 0) {
3284            if (lrui < mLruProcessActivityStart) {
3285                mLruProcessActivityStart--;
3286            }
3287            if (lrui < mLruProcessServiceStart) {
3288                mLruProcessServiceStart--;
3289            }
3290            /*
3291            if (addIndex > lrui) {
3292                addIndex--;
3293            }
3294            if (nextIndex > lrui) {
3295                nextIndex--;
3296            }
3297            */
3298            mLruProcesses.remove(lrui);
3299        }
3300
3301        /*
3302        mLruProcesses.add(addIndex, app);
3303        if (inActivity) {
3304            mLruProcessActivityStart++;
3305        }
3306        if (inService) {
3307            mLruProcessActivityStart++;
3308        }
3309        */
3310
3311        int nextIndex;
3312        if (hasActivity) {
3313            final int N = mLruProcesses.size();
3314            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3315                // Process doesn't have activities, but has clients with
3316                // activities...  move it up, but one below the top (the top
3317                // should always have a real activity).
3318                if (DEBUG_LRU) Slog.d(TAG_LRU,
3319                        "Adding to second-top of LRU activity list: " + app);
3320                mLruProcesses.add(N - 1, app);
3321                // To keep it from spamming the LRU list (by making a bunch of clients),
3322                // we will push down any other entries owned by the app.
3323                final int uid = app.info.uid;
3324                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3325                    ProcessRecord subProc = mLruProcesses.get(i);
3326                    if (subProc.info.uid == uid) {
3327                        // We want to push this one down the list.  If the process after
3328                        // it is for the same uid, however, don't do so, because we don't
3329                        // want them internally to be re-ordered.
3330                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3331                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3332                                    "Pushing uid " + uid + " swapping at " + i + ": "
3333                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3334                            ProcessRecord tmp = mLruProcesses.get(i);
3335                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3336                            mLruProcesses.set(i - 1, tmp);
3337                            i--;
3338                        }
3339                    } else {
3340                        // A gap, we can stop here.
3341                        break;
3342                    }
3343                }
3344            } else {
3345                // Process has activities, put it at the very tipsy-top.
3346                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3347                mLruProcesses.add(app);
3348            }
3349            nextIndex = mLruProcessServiceStart;
3350        } else if (hasService) {
3351            // Process has services, put it at the top of the service list.
3352            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3353            mLruProcesses.add(mLruProcessActivityStart, app);
3354            nextIndex = mLruProcessServiceStart;
3355            mLruProcessActivityStart++;
3356        } else  {
3357            // Process not otherwise of interest, it goes to the top of the non-service area.
3358            int index = mLruProcessServiceStart;
3359            if (client != null) {
3360                // If there is a client, don't allow the process to be moved up higher
3361                // in the list than that client.
3362                int clientIndex = mLruProcesses.lastIndexOf(client);
3363                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3364                        + " when updating " + app);
3365                if (clientIndex <= lrui) {
3366                    // Don't allow the client index restriction to push it down farther in the
3367                    // list than it already is.
3368                    clientIndex = lrui;
3369                }
3370                if (clientIndex >= 0 && index > clientIndex) {
3371                    index = clientIndex;
3372                }
3373            }
3374            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3375            mLruProcesses.add(index, app);
3376            nextIndex = index-1;
3377            mLruProcessActivityStart++;
3378            mLruProcessServiceStart++;
3379        }
3380
3381        // If the app is currently using a content provider or service,
3382        // bump those processes as well.
3383        for (int j=app.connections.size()-1; j>=0; j--) {
3384            ConnectionRecord cr = app.connections.valueAt(j);
3385            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3386                    && cr.binding.service.app != null
3387                    && cr.binding.service.app.lruSeq != mLruSeq
3388                    && !cr.binding.service.app.persistent) {
3389                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3390                        "service connection", cr, app);
3391            }
3392        }
3393        for (int j=app.conProviders.size()-1; j>=0; j--) {
3394            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3395            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3396                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3397                        "provider reference", cpr, app);
3398            }
3399        }
3400    }
3401
3402    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3403        if (uid == Process.SYSTEM_UID) {
3404            // The system gets to run in any process.  If there are multiple
3405            // processes with the same uid, just pick the first (this
3406            // should never happen).
3407            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3408            if (procs == null) return null;
3409            final int procCount = procs.size();
3410            for (int i = 0; i < procCount; i++) {
3411                final int procUid = procs.keyAt(i);
3412                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3413                    // Don't use an app process or different user process for system component.
3414                    continue;
3415                }
3416                return procs.valueAt(i);
3417            }
3418        }
3419        ProcessRecord proc = mProcessNames.get(processName, uid);
3420        if (false && proc != null && !keepIfLarge
3421                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3422                && proc.lastCachedPss >= 4000) {
3423            // Turn this condition on to cause killing to happen regularly, for testing.
3424            if (proc.baseProcessTracker != null) {
3425                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3426            }
3427            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3428        } else if (proc != null && !keepIfLarge
3429                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3430                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3431            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3432            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3433                if (proc.baseProcessTracker != null) {
3434                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3435                }
3436                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3437            }
3438        }
3439        return proc;
3440    }
3441
3442    void notifyPackageUse(String packageName, int reason) {
3443        IPackageManager pm = AppGlobals.getPackageManager();
3444        try {
3445            pm.notifyPackageUse(packageName, reason);
3446        } catch (RemoteException e) {
3447        }
3448    }
3449
3450    boolean isNextTransitionForward() {
3451        int transit = mWindowManager.getPendingAppTransition();
3452        return transit == TRANSIT_ACTIVITY_OPEN
3453                || transit == TRANSIT_TASK_OPEN
3454                || transit == TRANSIT_TASK_TO_FRONT;
3455    }
3456
3457    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3458            String processName, String abiOverride, int uid, Runnable crashHandler) {
3459        synchronized(this) {
3460            ApplicationInfo info = new ApplicationInfo();
3461            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3462            // For isolated processes, the former contains the parent's uid and the latter the
3463            // actual uid of the isolated process.
3464            // In the special case introduced by this method (which is, starting an isolated
3465            // process directly from the SystemServer without an actual parent app process) the
3466            // closest thing to a parent's uid is SYSTEM_UID.
3467            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3468            // the |isolated| logic in the ProcessRecord constructor.
3469            info.uid = Process.SYSTEM_UID;
3470            info.processName = processName;
3471            info.className = entryPoint;
3472            info.packageName = "android";
3473            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3474                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3475                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3476                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3477                    crashHandler);
3478            return proc != null ? proc.pid : 0;
3479        }
3480    }
3481
3482    final ProcessRecord startProcessLocked(String processName,
3483            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3484            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3485            boolean isolated, boolean keepIfLarge) {
3486        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3487                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3488                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3489                null /* crashHandler */);
3490    }
3491
3492    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3493            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3494            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3495            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3496        long startTime = SystemClock.elapsedRealtime();
3497        ProcessRecord app;
3498        if (!isolated) {
3499            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3500            checkTime(startTime, "startProcess: after getProcessRecord");
3501
3502            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3503                // If we are in the background, then check to see if this process
3504                // is bad.  If so, we will just silently fail.
3505                if (mAppErrors.isBadProcessLocked(info)) {
3506                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3507                            + "/" + info.processName);
3508                    return null;
3509                }
3510            } else {
3511                // When the user is explicitly starting a process, then clear its
3512                // crash count so that we won't make it bad until they see at
3513                // least one crash dialog again, and make the process good again
3514                // if it had been bad.
3515                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3516                        + "/" + info.processName);
3517                mAppErrors.resetProcessCrashTimeLocked(info);
3518                if (mAppErrors.isBadProcessLocked(info)) {
3519                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3520                            UserHandle.getUserId(info.uid), info.uid,
3521                            info.processName);
3522                    mAppErrors.clearBadProcessLocked(info);
3523                    if (app != null) {
3524                        app.bad = false;
3525                    }
3526                }
3527            }
3528        } else {
3529            // If this is an isolated process, it can't re-use an existing process.
3530            app = null;
3531        }
3532
3533        // app launch boost for big.little configurations
3534        // use cpusets to migrate freshly launched tasks to big cores
3535        nativeMigrateToBoost();
3536        mIsBoosted = true;
3537        mBoostStartTime = SystemClock.uptimeMillis();
3538        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3539        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3540
3541        // We don't have to do anything more if:
3542        // (1) There is an existing application record; and
3543        // (2) The caller doesn't think it is dead, OR there is no thread
3544        //     object attached to it so we know it couldn't have crashed; and
3545        // (3) There is a pid assigned to it, so it is either starting or
3546        //     already running.
3547        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3548                + " app=" + app + " knownToBeDead=" + knownToBeDead
3549                + " thread=" + (app != null ? app.thread : null)
3550                + " pid=" + (app != null ? app.pid : -1));
3551        if (app != null && app.pid > 0) {
3552            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3553                // We already have the app running, or are waiting for it to
3554                // come up (we have a pid but not yet its thread), so keep it.
3555                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3556                // If this is a new package in the process, add the package to the list
3557                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3558                checkTime(startTime, "startProcess: done, added package to proc");
3559                return app;
3560            }
3561
3562            // An application record is attached to a previous process,
3563            // clean it up now.
3564            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3565            checkTime(startTime, "startProcess: bad proc running, killing");
3566            killProcessGroup(app.uid, app.pid);
3567            handleAppDiedLocked(app, true, true);
3568            checkTime(startTime, "startProcess: done killing old proc");
3569        }
3570
3571        String hostingNameStr = hostingName != null
3572                ? hostingName.flattenToShortString() : null;
3573
3574        if (app == null) {
3575            checkTime(startTime, "startProcess: creating new process record");
3576            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3577            if (app == null) {
3578                Slog.w(TAG, "Failed making new process record for "
3579                        + processName + "/" + info.uid + " isolated=" + isolated);
3580                return null;
3581            }
3582            app.crashHandler = crashHandler;
3583            checkTime(startTime, "startProcess: done creating new process record");
3584        } else {
3585            // If this is a new package in the process, add the package to the list
3586            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3587            checkTime(startTime, "startProcess: added package to existing proc");
3588        }
3589
3590        // If the system is not ready yet, then hold off on starting this
3591        // process until it is.
3592        if (!mProcessesReady
3593                && !isAllowedWhileBooting(info)
3594                && !allowWhileBooting) {
3595            if (!mProcessesOnHold.contains(app)) {
3596                mProcessesOnHold.add(app);
3597            }
3598            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3599                    "System not ready, putting on hold: " + app);
3600            checkTime(startTime, "startProcess: returning with proc on hold");
3601            return app;
3602        }
3603
3604        checkTime(startTime, "startProcess: stepping in to startProcess");
3605        startProcessLocked(
3606                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3607        checkTime(startTime, "startProcess: done starting proc!");
3608        return (app.pid != 0) ? app : null;
3609    }
3610
3611    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3612        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3613    }
3614
3615    private final void startProcessLocked(ProcessRecord app,
3616            String hostingType, String hostingNameStr) {
3617        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3618                null /* entryPoint */, null /* entryPointArgs */);
3619    }
3620
3621    private final void startProcessLocked(ProcessRecord app, String hostingType,
3622            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3623        long startTime = SystemClock.elapsedRealtime();
3624        if (app.pid > 0 && app.pid != MY_PID) {
3625            checkTime(startTime, "startProcess: removing from pids map");
3626            synchronized (mPidsSelfLocked) {
3627                mPidsSelfLocked.remove(app.pid);
3628                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3629            }
3630            checkTime(startTime, "startProcess: done removing from pids map");
3631            app.setPid(0);
3632        }
3633
3634        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3635                "startProcessLocked removing on hold: " + app);
3636        mProcessesOnHold.remove(app);
3637
3638        checkTime(startTime, "startProcess: starting to update cpu stats");
3639        updateCpuStats();
3640        checkTime(startTime, "startProcess: done updating cpu stats");
3641
3642        try {
3643            try {
3644                final int userId = UserHandle.getUserId(app.uid);
3645                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3646            } catch (RemoteException e) {
3647                throw e.rethrowAsRuntimeException();
3648            }
3649
3650            int uid = app.uid;
3651            int[] gids = null;
3652            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3653            if (!app.isolated) {
3654                int[] permGids = null;
3655                try {
3656                    checkTime(startTime, "startProcess: getting gids from package manager");
3657                    final IPackageManager pm = AppGlobals.getPackageManager();
3658                    permGids = pm.getPackageGids(app.info.packageName,
3659                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3660                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3661                            MountServiceInternal.class);
3662                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3663                            app.info.packageName);
3664                } catch (RemoteException e) {
3665                    throw e.rethrowAsRuntimeException();
3666                }
3667
3668                /*
3669                 * Add shared application and profile GIDs so applications can share some
3670                 * resources like shared libraries and access user-wide resources
3671                 */
3672                if (ArrayUtils.isEmpty(permGids)) {
3673                    gids = new int[2];
3674                } else {
3675                    gids = new int[permGids.length + 2];
3676                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3677                }
3678                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3679                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3680            }
3681            checkTime(startTime, "startProcess: building args");
3682            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3683                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3684                        && mTopComponent != null
3685                        && app.processName.equals(mTopComponent.getPackageName())) {
3686                    uid = 0;
3687                }
3688                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3689                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3690                    uid = 0;
3691                }
3692            }
3693            int debugFlags = 0;
3694            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3695                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3696                // Also turn on CheckJNI for debuggable apps. It's quite
3697                // awkward to turn on otherwise.
3698                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3699            }
3700            // Run the app in safe mode if its manifest requests so or the
3701            // system is booted in safe mode.
3702            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3703                mSafeMode == true) {
3704                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3705            }
3706            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3707                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3708            }
3709            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3710            if ("true".equals(genDebugInfoProperty)) {
3711                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3712            }
3713            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3714                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3715            }
3716            if ("1".equals(SystemProperties.get("debug.assert"))) {
3717                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3718            }
3719            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3720                // Enable all debug flags required by the native debugger.
3721                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3722                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3723                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3724                mNativeDebuggingApp = null;
3725            }
3726
3727            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3728            if (requiredAbi == null) {
3729                requiredAbi = Build.SUPPORTED_ABIS[0];
3730            }
3731
3732            String instructionSet = null;
3733            if (app.info.primaryCpuAbi != null) {
3734                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3735            }
3736
3737            app.gids = gids;
3738            app.requiredAbi = requiredAbi;
3739            app.instructionSet = instructionSet;
3740
3741            // Start the process.  It will either succeed and return a result containing
3742            // the PID of the new process, or else throw a RuntimeException.
3743            boolean isActivityProcess = (entryPoint == null);
3744            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3745            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3746                    app.processName);
3747            checkTime(startTime, "startProcess: asking zygote to start proc");
3748            Process.ProcessStartResult startResult = Process.start(entryPoint,
3749                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3750                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3751                    app.info.dataDir, entryPointArgs);
3752            checkTime(startTime, "startProcess: returned from zygote!");
3753            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3754
3755            if (app.isolated) {
3756                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3757            }
3758            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3759            checkTime(startTime, "startProcess: done updating battery stats");
3760
3761            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3762                    UserHandle.getUserId(uid), startResult.pid, uid,
3763                    app.processName, hostingType,
3764                    hostingNameStr != null ? hostingNameStr : "");
3765
3766            try {
3767                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3768                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3769            } catch (RemoteException ex) {
3770                // Ignore
3771            }
3772
3773            if (app.persistent) {
3774                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3775            }
3776
3777            checkTime(startTime, "startProcess: building log message");
3778            StringBuilder buf = mStringBuilder;
3779            buf.setLength(0);
3780            buf.append("Start proc ");
3781            buf.append(startResult.pid);
3782            buf.append(':');
3783            buf.append(app.processName);
3784            buf.append('/');
3785            UserHandle.formatUid(buf, uid);
3786            if (!isActivityProcess) {
3787                buf.append(" [");
3788                buf.append(entryPoint);
3789                buf.append("]");
3790            }
3791            buf.append(" for ");
3792            buf.append(hostingType);
3793            if (hostingNameStr != null) {
3794                buf.append(" ");
3795                buf.append(hostingNameStr);
3796            }
3797            Slog.i(TAG, buf.toString());
3798            app.setPid(startResult.pid);
3799            app.usingWrapper = startResult.usingWrapper;
3800            app.removed = false;
3801            app.killed = false;
3802            app.killedByAm = false;
3803            checkTime(startTime, "startProcess: starting to update pids map");
3804            synchronized (mPidsSelfLocked) {
3805                this.mPidsSelfLocked.put(startResult.pid, app);
3806                if (isActivityProcess) {
3807                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3808                    msg.obj = app;
3809                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3810                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3811                }
3812            }
3813            checkTime(startTime, "startProcess: done updating pids map");
3814        } catch (RuntimeException e) {
3815            Slog.e(TAG, "Failure starting process " + app.processName, e);
3816
3817            // Something went very wrong while trying to start this process; one
3818            // common case is when the package is frozen due to an active
3819            // upgrade. To recover, clean up any active bookkeeping related to
3820            // starting this process. (We already invoked this method once when
3821            // the package was initially frozen through KILL_APPLICATION_MSG, so
3822            // it doesn't hurt to use it again.)
3823            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3824                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3825        }
3826    }
3827
3828    void updateUsageStats(ActivityRecord component, boolean resumed) {
3829        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3830                "updateUsageStats: comp=" + component + "res=" + resumed);
3831        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3832        if (resumed) {
3833            if (mUsageStatsService != null) {
3834                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3835                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3836            }
3837            synchronized (stats) {
3838                stats.noteActivityResumedLocked(component.app.uid);
3839            }
3840        } else {
3841            if (mUsageStatsService != null) {
3842                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3843                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3844            }
3845            synchronized (stats) {
3846                stats.noteActivityPausedLocked(component.app.uid);
3847            }
3848        }
3849    }
3850
3851    Intent getHomeIntent() {
3852        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3853        intent.setComponent(mTopComponent);
3854        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3855        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3856            intent.addCategory(Intent.CATEGORY_HOME);
3857        }
3858        return intent;
3859    }
3860
3861    boolean startHomeActivityLocked(int userId, String reason) {
3862        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3863                && mTopAction == null) {
3864            // We are running in factory test mode, but unable to find
3865            // the factory test app, so just sit around displaying the
3866            // error message and don't try to start anything.
3867            return false;
3868        }
3869        Intent intent = getHomeIntent();
3870        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3871        if (aInfo != null) {
3872            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3873            // Don't do this if the home app is currently being
3874            // instrumented.
3875            aInfo = new ActivityInfo(aInfo);
3876            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3877            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3878                    aInfo.applicationInfo.uid, true);
3879            if (app == null || app.instrumentationClass == null) {
3880                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3881                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3882            }
3883        } else {
3884            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3885        }
3886
3887        return true;
3888    }
3889
3890    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3891        ActivityInfo ai = null;
3892        ComponentName comp = intent.getComponent();
3893        try {
3894            if (comp != null) {
3895                // Factory test.
3896                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3897            } else {
3898                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3899                        intent,
3900                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3901                        flags, userId);
3902
3903                if (info != null) {
3904                    ai = info.activityInfo;
3905                }
3906            }
3907        } catch (RemoteException e) {
3908            // ignore
3909        }
3910
3911        return ai;
3912    }
3913
3914    /**
3915     * Starts the "new version setup screen" if appropriate.
3916     */
3917    void startSetupActivityLocked() {
3918        // Only do this once per boot.
3919        if (mCheckedForSetup) {
3920            return;
3921        }
3922
3923        // We will show this screen if the current one is a different
3924        // version than the last one shown, and we are not running in
3925        // low-level factory test mode.
3926        final ContentResolver resolver = mContext.getContentResolver();
3927        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3928                Settings.Global.getInt(resolver,
3929                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3930            mCheckedForSetup = true;
3931
3932            // See if we should be showing the platform update setup UI.
3933            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3934            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3935                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3936            if (!ris.isEmpty()) {
3937                final ResolveInfo ri = ris.get(0);
3938                String vers = ri.activityInfo.metaData != null
3939                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3940                        : null;
3941                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3942                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3943                            Intent.METADATA_SETUP_VERSION);
3944                }
3945                String lastVers = Settings.Secure.getString(
3946                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3947                if (vers != null && !vers.equals(lastVers)) {
3948                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3949                    intent.setComponent(new ComponentName(
3950                            ri.activityInfo.packageName, ri.activityInfo.name));
3951                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3952                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3953                            null, 0, 0, 0, null, false, false, null, null, null);
3954                }
3955            }
3956        }
3957    }
3958
3959    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3960        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3961    }
3962
3963    void enforceNotIsolatedCaller(String caller) {
3964        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3965            throw new SecurityException("Isolated process not allowed to call " + caller);
3966        }
3967    }
3968
3969    void enforceShellRestriction(String restriction, int userHandle) {
3970        if (Binder.getCallingUid() == Process.SHELL_UID) {
3971            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3972                throw new SecurityException("Shell does not have permission to access user "
3973                        + userHandle);
3974            }
3975        }
3976    }
3977
3978    @Override
3979    public int getFrontActivityScreenCompatMode() {
3980        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3981        synchronized (this) {
3982            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3983        }
3984    }
3985
3986    @Override
3987    public void setFrontActivityScreenCompatMode(int mode) {
3988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3989                "setFrontActivityScreenCompatMode");
3990        synchronized (this) {
3991            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3992        }
3993    }
3994
3995    @Override
3996    public int getPackageScreenCompatMode(String packageName) {
3997        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3998        synchronized (this) {
3999            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4000        }
4001    }
4002
4003    @Override
4004    public void setPackageScreenCompatMode(String packageName, int mode) {
4005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4006                "setPackageScreenCompatMode");
4007        synchronized (this) {
4008            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4009        }
4010    }
4011
4012    @Override
4013    public boolean getPackageAskScreenCompat(String packageName) {
4014        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4015        synchronized (this) {
4016            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4017        }
4018    }
4019
4020    @Override
4021    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4022        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4023                "setPackageAskScreenCompat");
4024        synchronized (this) {
4025            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4026        }
4027    }
4028
4029    private boolean hasUsageStatsPermission(String callingPackage) {
4030        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4031                Binder.getCallingUid(), callingPackage);
4032        if (mode == AppOpsManager.MODE_DEFAULT) {
4033            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4034                    == PackageManager.PERMISSION_GRANTED;
4035        }
4036        return mode == AppOpsManager.MODE_ALLOWED;
4037    }
4038
4039    @Override
4040    public int getPackageProcessState(String packageName, String callingPackage) {
4041        if (!hasUsageStatsPermission(callingPackage)) {
4042            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4043                    "getPackageProcessState");
4044        }
4045
4046        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4047        synchronized (this) {
4048            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4049                final ProcessRecord proc = mLruProcesses.get(i);
4050                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4051                        || procState > proc.setProcState) {
4052                    boolean found = false;
4053                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4054                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4055                            procState = proc.setProcState;
4056                            found = true;
4057                        }
4058                    }
4059                    if (proc.pkgDeps != null && !found) {
4060                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4061                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4062                                procState = proc.setProcState;
4063                                break;
4064                            }
4065                        }
4066                    }
4067                }
4068            }
4069        }
4070        return procState;
4071    }
4072
4073    @Override
4074    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4075        synchronized (this) {
4076            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4077            if (app == null) {
4078                return false;
4079            }
4080            if (app.trimMemoryLevel < level && app.thread != null &&
4081                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4082                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4083                try {
4084                    app.thread.scheduleTrimMemory(level);
4085                    app.trimMemoryLevel = level;
4086                    return true;
4087                } catch (RemoteException e) {
4088                    // Fallthrough to failure case.
4089                }
4090            }
4091        }
4092        return false;
4093    }
4094
4095    private void dispatchProcessesChanged() {
4096        int N;
4097        synchronized (this) {
4098            N = mPendingProcessChanges.size();
4099            if (mActiveProcessChanges.length < N) {
4100                mActiveProcessChanges = new ProcessChangeItem[N];
4101            }
4102            mPendingProcessChanges.toArray(mActiveProcessChanges);
4103            mPendingProcessChanges.clear();
4104            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4105                    "*** Delivering " + N + " process changes");
4106        }
4107
4108        int i = mProcessObservers.beginBroadcast();
4109        while (i > 0) {
4110            i--;
4111            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4112            if (observer != null) {
4113                try {
4114                    for (int j=0; j<N; j++) {
4115                        ProcessChangeItem item = mActiveProcessChanges[j];
4116                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4117                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4118                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4119                                    + item.uid + ": " + item.foregroundActivities);
4120                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4121                                    item.foregroundActivities);
4122                        }
4123                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4124                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4125                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4126                                    + ": " + item.processState);
4127                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4128                        }
4129                    }
4130                } catch (RemoteException e) {
4131                }
4132            }
4133        }
4134        mProcessObservers.finishBroadcast();
4135
4136        synchronized (this) {
4137            for (int j=0; j<N; j++) {
4138                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4139            }
4140        }
4141    }
4142
4143    private void dispatchProcessDied(int pid, int uid) {
4144        int i = mProcessObservers.beginBroadcast();
4145        while (i > 0) {
4146            i--;
4147            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4148            if (observer != null) {
4149                try {
4150                    observer.onProcessDied(pid, uid);
4151                } catch (RemoteException e) {
4152                }
4153            }
4154        }
4155        mProcessObservers.finishBroadcast();
4156    }
4157
4158    private void dispatchUidsChanged() {
4159        int N;
4160        synchronized (this) {
4161            N = mPendingUidChanges.size();
4162            if (mActiveUidChanges.length < N) {
4163                mActiveUidChanges = new UidRecord.ChangeItem[N];
4164            }
4165            for (int i=0; i<N; i++) {
4166                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4167                mActiveUidChanges[i] = change;
4168                if (change.uidRecord != null) {
4169                    change.uidRecord.pendingChange = null;
4170                    change.uidRecord = null;
4171                }
4172            }
4173            mPendingUidChanges.clear();
4174            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                    "*** Delivering " + N + " uid changes");
4176        }
4177
4178        if (mLocalPowerManager != null) {
4179            for (int j=0; j<N; j++) {
4180                UidRecord.ChangeItem item = mActiveUidChanges[j];
4181                if (item.change == UidRecord.CHANGE_GONE
4182                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4183                    mLocalPowerManager.uidGone(item.uid);
4184                } else {
4185                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4186                }
4187            }
4188        }
4189
4190        int i = mUidObservers.beginBroadcast();
4191        while (i > 0) {
4192            i--;
4193            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4194            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4195            if (observer != null) {
4196                try {
4197                    for (int j=0; j<N; j++) {
4198                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4199                        final int change = item.change;
4200                        UidRecord validateUid = null;
4201                        if (VALIDATE_UID_STATES && i == 0) {
4202                            validateUid = mValidateUids.get(item.uid);
4203                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4204                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4205                                validateUid = new UidRecord(item.uid);
4206                                mValidateUids.put(item.uid, validateUid);
4207                            }
4208                        }
4209                        if (change == UidRecord.CHANGE_IDLE
4210                                || change == UidRecord.CHANGE_GONE_IDLE) {
4211                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4212                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4213                                        "UID idle uid=" + item.uid);
4214                                observer.onUidIdle(item.uid);
4215                            }
4216                            if (VALIDATE_UID_STATES && i == 0) {
4217                                if (validateUid != null) {
4218                                    validateUid.idle = true;
4219                                }
4220                            }
4221                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4222                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4223                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4224                                        "UID active uid=" + item.uid);
4225                                observer.onUidActive(item.uid);
4226                            }
4227                            if (VALIDATE_UID_STATES && i == 0) {
4228                                validateUid.idle = false;
4229                            }
4230                        }
4231                        if (change == UidRecord.CHANGE_GONE
4232                                || change == UidRecord.CHANGE_GONE_IDLE) {
4233                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4234                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4235                                        "UID gone uid=" + item.uid);
4236                                observer.onUidGone(item.uid);
4237                            }
4238                            if (VALIDATE_UID_STATES && i == 0) {
4239                                if (validateUid != null) {
4240                                    mValidateUids.remove(item.uid);
4241                                }
4242                            }
4243                        } else {
4244                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4245                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4246                                        "UID CHANGED uid=" + item.uid
4247                                                + ": " + item.processState);
4248                                observer.onUidStateChanged(item.uid, item.processState);
4249                            }
4250                            if (VALIDATE_UID_STATES && i == 0) {
4251                                validateUid.curProcState = validateUid.setProcState
4252                                        = item.processState;
4253                            }
4254                        }
4255                    }
4256                } catch (RemoteException e) {
4257                }
4258            }
4259        }
4260        mUidObservers.finishBroadcast();
4261
4262        synchronized (this) {
4263            for (int j=0; j<N; j++) {
4264                mAvailUidChanges.add(mActiveUidChanges[j]);
4265            }
4266        }
4267    }
4268
4269    @Override
4270    public final int startActivity(IApplicationThread caller, String callingPackage,
4271            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4272            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4273        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4274                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4275                UserHandle.getCallingUserId());
4276    }
4277
4278    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4279        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4280        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4281                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4282                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4283
4284        // TODO: Switch to user app stacks here.
4285        String mimeType = intent.getType();
4286        final Uri data = intent.getData();
4287        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4288            mimeType = getProviderMimeType(data, userId);
4289        }
4290        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4291
4292        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4293        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4294                null, 0, 0, null, null, null, null, false, userId, container, null);
4295    }
4296
4297    @Override
4298    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4300            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4301        enforceNotIsolatedCaller("startActivity");
4302        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4303                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4304        // TODO: Switch to user app stacks here.
4305        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4306                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4307                profilerInfo, null, null, bOptions, false, userId, null, null);
4308    }
4309
4310    @Override
4311    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4312            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4313            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4314            int userId) {
4315
4316        // This is very dangerous -- it allows you to perform a start activity (including
4317        // permission grants) as any app that may launch one of your own activities.  So
4318        // we will only allow this to be done from activities that are part of the core framework,
4319        // and then only when they are running as the system.
4320        final ActivityRecord sourceRecord;
4321        final int targetUid;
4322        final String targetPackage;
4323        synchronized (this) {
4324            if (resultTo == null) {
4325                throw new SecurityException("Must be called from an activity");
4326            }
4327            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4328            if (sourceRecord == null) {
4329                throw new SecurityException("Called with bad activity token: " + resultTo);
4330            }
4331            if (!sourceRecord.info.packageName.equals("android")) {
4332                throw new SecurityException(
4333                        "Must be called from an activity that is declared in the android package");
4334            }
4335            if (sourceRecord.app == null) {
4336                throw new SecurityException("Called without a process attached to activity");
4337            }
4338            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4339                // This is still okay, as long as this activity is running under the
4340                // uid of the original calling activity.
4341                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4342                    throw new SecurityException(
4343                            "Calling activity in uid " + sourceRecord.app.uid
4344                                    + " must be system uid or original calling uid "
4345                                    + sourceRecord.launchedFromUid);
4346                }
4347            }
4348            if (ignoreTargetSecurity) {
4349                if (intent.getComponent() == null) {
4350                    throw new SecurityException(
4351                            "Component must be specified with ignoreTargetSecurity");
4352                }
4353                if (intent.getSelector() != null) {
4354                    throw new SecurityException(
4355                            "Selector not allowed with ignoreTargetSecurity");
4356                }
4357            }
4358            targetUid = sourceRecord.launchedFromUid;
4359            targetPackage = sourceRecord.launchedFromPackage;
4360        }
4361
4362        if (userId == UserHandle.USER_NULL) {
4363            userId = UserHandle.getUserId(sourceRecord.app.uid);
4364        }
4365
4366        // TODO: Switch to user app stacks here.
4367        try {
4368            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4369                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4370                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4371            return ret;
4372        } catch (SecurityException e) {
4373            // XXX need to figure out how to propagate to original app.
4374            // A SecurityException here is generally actually a fault of the original
4375            // calling activity (such as a fairly granting permissions), so propagate it
4376            // back to them.
4377            /*
4378            StringBuilder msg = new StringBuilder();
4379            msg.append("While launching");
4380            msg.append(intent.toString());
4381            msg.append(": ");
4382            msg.append(e.getMessage());
4383            */
4384            throw e;
4385        }
4386    }
4387
4388    @Override
4389    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4390            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4391            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4392        enforceNotIsolatedCaller("startActivityAndWait");
4393        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4394                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4395        WaitResult res = new WaitResult();
4396        // TODO: Switch to user app stacks here.
4397        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4398                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4399                bOptions, false, userId, null, null);
4400        return res;
4401    }
4402
4403    @Override
4404    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4405            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4406            int startFlags, Configuration config, Bundle bOptions, int userId) {
4407        enforceNotIsolatedCaller("startActivityWithConfig");
4408        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4409                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4410        // TODO: Switch to user app stacks here.
4411        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4412                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4413                null, null, config, bOptions, false, userId, null, null);
4414        return ret;
4415    }
4416
4417    @Override
4418    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4419            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4420            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4421            throws TransactionTooLargeException {
4422        enforceNotIsolatedCaller("startActivityIntentSender");
4423        // Refuse possible leaked file descriptors
4424        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4425            throw new IllegalArgumentException("File descriptors passed in Intent");
4426        }
4427
4428        IIntentSender sender = intent.getTarget();
4429        if (!(sender instanceof PendingIntentRecord)) {
4430            throw new IllegalArgumentException("Bad PendingIntent object");
4431        }
4432
4433        PendingIntentRecord pir = (PendingIntentRecord)sender;
4434
4435        synchronized (this) {
4436            // If this is coming from the currently resumed activity, it is
4437            // effectively saying that app switches are allowed at this point.
4438            final ActivityStack stack = getFocusedStack();
4439            if (stack.mResumedActivity != null &&
4440                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4441                mAppSwitchesAllowedTime = 0;
4442            }
4443        }
4444        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4445                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4446        return ret;
4447    }
4448
4449    @Override
4450    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4451            Intent intent, String resolvedType, IVoiceInteractionSession session,
4452            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4453            Bundle bOptions, int userId) {
4454        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4455                != PackageManager.PERMISSION_GRANTED) {
4456            String msg = "Permission Denial: startVoiceActivity() from pid="
4457                    + Binder.getCallingPid()
4458                    + ", uid=" + Binder.getCallingUid()
4459                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4460            Slog.w(TAG, msg);
4461            throw new SecurityException(msg);
4462        }
4463        if (session == null || interactor == null) {
4464            throw new NullPointerException("null session or interactor");
4465        }
4466        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4467                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4468        // TODO: Switch to user app stacks here.
4469        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4470                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4471                null, bOptions, false, userId, null, null);
4472    }
4473
4474    @Override
4475    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4476            throws RemoteException {
4477        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4478        synchronized (this) {
4479            ActivityRecord activity = getFocusedStack().topActivity();
4480            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4481                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4482            }
4483            if (mRunningVoice != null || activity.task.voiceSession != null
4484                    || activity.voiceSession != null) {
4485                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4486                return;
4487            }
4488            if (activity.pendingVoiceInteractionStart) {
4489                Slog.w(TAG, "Pending start of voice interaction already.");
4490                return;
4491            }
4492            activity.pendingVoiceInteractionStart = true;
4493        }
4494        LocalServices.getService(VoiceInteractionManagerInternal.class)
4495                .startLocalVoiceInteraction(callingActivity, options);
4496    }
4497
4498    @Override
4499    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4500        LocalServices.getService(VoiceInteractionManagerInternal.class)
4501                .stopLocalVoiceInteraction(callingActivity);
4502    }
4503
4504    @Override
4505    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4506        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4507                .supportsLocalVoiceInteraction();
4508    }
4509
4510    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4511            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4512        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4513        if (activityToCallback == null) return;
4514        activityToCallback.setVoiceSessionLocked(voiceSession);
4515
4516        // Inform the activity
4517        try {
4518            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4519                    voiceInteractor);
4520            long token = Binder.clearCallingIdentity();
4521            try {
4522                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4523            } finally {
4524                Binder.restoreCallingIdentity(token);
4525            }
4526            // TODO: VI Should we cache the activity so that it's easier to find later
4527            // rather than scan through all the stacks and activities?
4528        } catch (RemoteException re) {
4529            activityToCallback.clearVoiceSessionLocked();
4530            // TODO: VI Should this terminate the voice session?
4531        }
4532    }
4533
4534    @Override
4535    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4536        synchronized (this) {
4537            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4538                if (keepAwake) {
4539                    mVoiceWakeLock.acquire();
4540                } else {
4541                    mVoiceWakeLock.release();
4542                }
4543            }
4544        }
4545    }
4546
4547    @Override
4548    public boolean startNextMatchingActivity(IBinder callingActivity,
4549            Intent intent, Bundle bOptions) {
4550        // Refuse possible leaked file descriptors
4551        if (intent != null && intent.hasFileDescriptors() == true) {
4552            throw new IllegalArgumentException("File descriptors passed in Intent");
4553        }
4554        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4555
4556        synchronized (this) {
4557            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4558            if (r == null) {
4559                ActivityOptions.abort(options);
4560                return false;
4561            }
4562            if (r.app == null || r.app.thread == null) {
4563                // The caller is not running...  d'oh!
4564                ActivityOptions.abort(options);
4565                return false;
4566            }
4567            intent = new Intent(intent);
4568            // The caller is not allowed to change the data.
4569            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4570            // And we are resetting to find the next component...
4571            intent.setComponent(null);
4572
4573            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4574
4575            ActivityInfo aInfo = null;
4576            try {
4577                List<ResolveInfo> resolves =
4578                    AppGlobals.getPackageManager().queryIntentActivities(
4579                            intent, r.resolvedType,
4580                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4581                            UserHandle.getCallingUserId()).getList();
4582
4583                // Look for the original activity in the list...
4584                final int N = resolves != null ? resolves.size() : 0;
4585                for (int i=0; i<N; i++) {
4586                    ResolveInfo rInfo = resolves.get(i);
4587                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4588                            && rInfo.activityInfo.name.equals(r.info.name)) {
4589                        // We found the current one...  the next matching is
4590                        // after it.
4591                        i++;
4592                        if (i<N) {
4593                            aInfo = resolves.get(i).activityInfo;
4594                        }
4595                        if (debug) {
4596                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4597                                    + "/" + r.info.name);
4598                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4599                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4600                        }
4601                        break;
4602                    }
4603                }
4604            } catch (RemoteException e) {
4605            }
4606
4607            if (aInfo == null) {
4608                // Nobody who is next!
4609                ActivityOptions.abort(options);
4610                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4611                return false;
4612            }
4613
4614            intent.setComponent(new ComponentName(
4615                    aInfo.applicationInfo.packageName, aInfo.name));
4616            intent.setFlags(intent.getFlags()&~(
4617                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4618                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4619                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4620                    Intent.FLAG_ACTIVITY_NEW_TASK));
4621
4622            // Okay now we need to start the new activity, replacing the
4623            // currently running activity.  This is a little tricky because
4624            // we want to start the new one as if the current one is finished,
4625            // but not finish the current one first so that there is no flicker.
4626            // And thus...
4627            final boolean wasFinishing = r.finishing;
4628            r.finishing = true;
4629
4630            // Propagate reply information over to the new activity.
4631            final ActivityRecord resultTo = r.resultTo;
4632            final String resultWho = r.resultWho;
4633            final int requestCode = r.requestCode;
4634            r.resultTo = null;
4635            if (resultTo != null) {
4636                resultTo.removeResultsLocked(r, resultWho, requestCode);
4637            }
4638
4639            final long origId = Binder.clearCallingIdentity();
4640            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4641                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4642                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4643                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4644                    false, false, null, null, null);
4645            Binder.restoreCallingIdentity(origId);
4646
4647            r.finishing = wasFinishing;
4648            if (res != ActivityManager.START_SUCCESS) {
4649                return false;
4650            }
4651            return true;
4652        }
4653    }
4654
4655    @Override
4656    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4657        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4658            String msg = "Permission Denial: startActivityFromRecents called without " +
4659                    START_TASKS_FROM_RECENTS;
4660            Slog.w(TAG, msg);
4661            throw new SecurityException(msg);
4662        }
4663        final long origId = Binder.clearCallingIdentity();
4664        try {
4665            synchronized (this) {
4666                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4667            }
4668        } finally {
4669            Binder.restoreCallingIdentity(origId);
4670        }
4671    }
4672
4673    final int startActivityInPackage(int uid, String callingPackage,
4674            Intent intent, String resolvedType, IBinder resultTo,
4675            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4676            IActivityContainer container, TaskRecord inTask) {
4677
4678        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4679                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4680
4681        // TODO: Switch to user app stacks here.
4682        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4683                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4684                null, null, null, bOptions, false, userId, container, inTask);
4685        return ret;
4686    }
4687
4688    @Override
4689    public final int startActivities(IApplicationThread caller, String callingPackage,
4690            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4691            int userId) {
4692        enforceNotIsolatedCaller("startActivities");
4693        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4694                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4695        // TODO: Switch to user app stacks here.
4696        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4697                resolvedTypes, resultTo, bOptions, userId);
4698        return ret;
4699    }
4700
4701    final int startActivitiesInPackage(int uid, String callingPackage,
4702            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4703            Bundle bOptions, int userId) {
4704
4705        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4706                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4707        // TODO: Switch to user app stacks here.
4708        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4709                resultTo, bOptions, userId);
4710        return ret;
4711    }
4712
4713    @Override
4714    public void reportActivityFullyDrawn(IBinder token) {
4715        synchronized (this) {
4716            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4717            if (r == null) {
4718                return;
4719            }
4720            r.reportFullyDrawnLocked();
4721        }
4722    }
4723
4724    @Override
4725    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4726        synchronized (this) {
4727            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4728            if (r == null) {
4729                return;
4730            }
4731            TaskRecord task = r.task;
4732            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4733                // Fixed screen orientation isn't supported when activities aren't in full screen
4734                // mode.
4735                return;
4736            }
4737            final long origId = Binder.clearCallingIdentity();
4738            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4739            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4740                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4741            if (config != null) {
4742                r.frozenBeforeDestroy = true;
4743                if (!updateConfigurationLocked(config, r, false)) {
4744                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4745                }
4746            }
4747            Binder.restoreCallingIdentity(origId);
4748        }
4749    }
4750
4751    @Override
4752    public int getRequestedOrientation(IBinder token) {
4753        synchronized (this) {
4754            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4755            if (r == null) {
4756                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4757            }
4758            return mWindowManager.getAppOrientation(r.appToken);
4759        }
4760    }
4761
4762    /**
4763     * This is the internal entry point for handling Activity.finish().
4764     *
4765     * @param token The Binder token referencing the Activity we want to finish.
4766     * @param resultCode Result code, if any, from this Activity.
4767     * @param resultData Result data (Intent), if any, from this Activity.
4768     * @param finishTask Whether to finish the task associated with this Activity.
4769     *
4770     * @return Returns true if the activity successfully finished, or false if it is still running.
4771     */
4772    @Override
4773    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4774            int finishTask) {
4775        // Refuse possible leaked file descriptors
4776        if (resultData != null && resultData.hasFileDescriptors() == true) {
4777            throw new IllegalArgumentException("File descriptors passed in Intent");
4778        }
4779
4780        synchronized(this) {
4781            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4782            if (r == null) {
4783                return true;
4784            }
4785            // Keep track of the root activity of the task before we finish it
4786            TaskRecord tr = r.task;
4787            ActivityRecord rootR = tr.getRootActivity();
4788            if (rootR == null) {
4789                Slog.w(TAG, "Finishing task with all activities already finished");
4790            }
4791            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4792            // finish.
4793            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4794                    mStackSupervisor.isLastLockedTask(tr)) {
4795                Slog.i(TAG, "Not finishing task in lock task mode");
4796                mStackSupervisor.showLockTaskToast();
4797                return false;
4798            }
4799            if (mController != null) {
4800                // Find the first activity that is not finishing.
4801                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4802                if (next != null) {
4803                    // ask watcher if this is allowed
4804                    boolean resumeOK = true;
4805                    try {
4806                        resumeOK = mController.activityResuming(next.packageName);
4807                    } catch (RemoteException e) {
4808                        mController = null;
4809                        Watchdog.getInstance().setActivityController(null);
4810                    }
4811
4812                    if (!resumeOK) {
4813                        Slog.i(TAG, "Not finishing activity because controller resumed");
4814                        return false;
4815                    }
4816                }
4817            }
4818            final long origId = Binder.clearCallingIdentity();
4819            try {
4820                boolean res;
4821                final boolean finishWithRootActivity =
4822                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4823                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4824                        || (finishWithRootActivity && r == rootR)) {
4825                    // If requested, remove the task that is associated to this activity only if it
4826                    // was the root activity in the task. The result code and data is ignored
4827                    // because we don't support returning them across task boundaries. Also, to
4828                    // keep backwards compatibility we remove the task from recents when finishing
4829                    // task with root activity.
4830                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4831                    if (!res) {
4832                        Slog.i(TAG, "Removing task failed to finish activity");
4833                    }
4834                } else {
4835                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4836                            resultData, "app-request", true);
4837                    if (!res) {
4838                        Slog.i(TAG, "Failed to finish by app-request");
4839                    }
4840                }
4841                return res;
4842            } finally {
4843                Binder.restoreCallingIdentity(origId);
4844            }
4845        }
4846    }
4847
4848    @Override
4849    public final void finishHeavyWeightApp() {
4850        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4851                != PackageManager.PERMISSION_GRANTED) {
4852            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4853                    + Binder.getCallingPid()
4854                    + ", uid=" + Binder.getCallingUid()
4855                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4856            Slog.w(TAG, msg);
4857            throw new SecurityException(msg);
4858        }
4859
4860        synchronized(this) {
4861            if (mHeavyWeightProcess == null) {
4862                return;
4863            }
4864
4865            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4866            for (int i = 0; i < activities.size(); i++) {
4867                ActivityRecord r = activities.get(i);
4868                if (!r.finishing && r.isInStackLocked()) {
4869                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4870                            null, "finish-heavy", true);
4871                }
4872            }
4873
4874            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4875                    mHeavyWeightProcess.userId, 0));
4876            mHeavyWeightProcess = null;
4877        }
4878    }
4879
4880    @Override
4881    public void crashApplication(int uid, int initialPid, String packageName,
4882            String message) {
4883        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4884                != PackageManager.PERMISSION_GRANTED) {
4885            String msg = "Permission Denial: crashApplication() from pid="
4886                    + Binder.getCallingPid()
4887                    + ", uid=" + Binder.getCallingUid()
4888                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4889            Slog.w(TAG, msg);
4890            throw new SecurityException(msg);
4891        }
4892
4893        synchronized(this) {
4894            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4895        }
4896    }
4897
4898    @Override
4899    public final void finishSubActivity(IBinder token, String resultWho,
4900            int requestCode) {
4901        synchronized(this) {
4902            final long origId = Binder.clearCallingIdentity();
4903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4904            if (r != null) {
4905                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4906            }
4907            Binder.restoreCallingIdentity(origId);
4908        }
4909    }
4910
4911    @Override
4912    public boolean finishActivityAffinity(IBinder token) {
4913        synchronized(this) {
4914            final long origId = Binder.clearCallingIdentity();
4915            try {
4916                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4917                if (r == null) {
4918                    return false;
4919                }
4920
4921                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4922                // can finish.
4923                final TaskRecord task = r.task;
4924                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4925                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4926                    mStackSupervisor.showLockTaskToast();
4927                    return false;
4928                }
4929                return task.stack.finishActivityAffinityLocked(r);
4930            } finally {
4931                Binder.restoreCallingIdentity(origId);
4932            }
4933        }
4934    }
4935
4936    @Override
4937    public void finishVoiceTask(IVoiceInteractionSession session) {
4938        synchronized (this) {
4939            final long origId = Binder.clearCallingIdentity();
4940            try {
4941                // TODO: VI Consider treating local voice interactions and voice tasks
4942                // differently here
4943                mStackSupervisor.finishVoiceTask(session);
4944            } finally {
4945                Binder.restoreCallingIdentity(origId);
4946            }
4947        }
4948
4949    }
4950
4951    @Override
4952    public boolean releaseActivityInstance(IBinder token) {
4953        synchronized(this) {
4954            final long origId = Binder.clearCallingIdentity();
4955            try {
4956                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4957                if (r == null) {
4958                    return false;
4959                }
4960                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4961            } finally {
4962                Binder.restoreCallingIdentity(origId);
4963            }
4964        }
4965    }
4966
4967    @Override
4968    public void releaseSomeActivities(IApplicationThread appInt) {
4969        synchronized(this) {
4970            final long origId = Binder.clearCallingIdentity();
4971            try {
4972                ProcessRecord app = getRecordForAppLocked(appInt);
4973                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4974            } finally {
4975                Binder.restoreCallingIdentity(origId);
4976            }
4977        }
4978    }
4979
4980    @Override
4981    public boolean willActivityBeVisible(IBinder token) {
4982        synchronized(this) {
4983            ActivityStack stack = ActivityRecord.getStackLocked(token);
4984            if (stack != null) {
4985                return stack.willActivityBeVisibleLocked(token);
4986            }
4987            return false;
4988        }
4989    }
4990
4991    @Override
4992    public void overridePendingTransition(IBinder token, String packageName,
4993            int enterAnim, int exitAnim) {
4994        synchronized(this) {
4995            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4996            if (self == null) {
4997                return;
4998            }
4999
5000            final long origId = Binder.clearCallingIdentity();
5001
5002            if (self.state == ActivityState.RESUMED
5003                    || self.state == ActivityState.PAUSING) {
5004                mWindowManager.overridePendingAppTransition(packageName,
5005                        enterAnim, exitAnim, null);
5006            }
5007
5008            Binder.restoreCallingIdentity(origId);
5009        }
5010    }
5011
5012    /**
5013     * Main function for removing an existing process from the activity manager
5014     * as a result of that process going away.  Clears out all connections
5015     * to the process.
5016     */
5017    private final void handleAppDiedLocked(ProcessRecord app,
5018            boolean restarting, boolean allowRestart) {
5019        int pid = app.pid;
5020        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5021        if (!kept && !restarting) {
5022            removeLruProcessLocked(app);
5023            if (pid > 0) {
5024                ProcessList.remove(pid);
5025            }
5026        }
5027
5028        if (mProfileProc == app) {
5029            clearProfilerLocked();
5030        }
5031
5032        // Remove this application's activities from active lists.
5033        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5034
5035        app.activities.clear();
5036
5037        if (app.instrumentationClass != null) {
5038            Slog.w(TAG, "Crash of app " + app.processName
5039                  + " running instrumentation " + app.instrumentationClass);
5040            Bundle info = new Bundle();
5041            info.putString("shortMsg", "Process crashed.");
5042            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5043        }
5044
5045        if (!restarting && hasVisibleActivities
5046                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5047            // If there was nothing to resume, and we are not already restarting this process, but
5048            // there is a visible activity that is hosted by the process...  then make sure all
5049            // visible activities are running, taking care of restarting this process.
5050            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5051        }
5052    }
5053
5054    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5055        IBinder threadBinder = thread.asBinder();
5056        // Find the application record.
5057        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5058            ProcessRecord rec = mLruProcesses.get(i);
5059            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5060                return i;
5061            }
5062        }
5063        return -1;
5064    }
5065
5066    final ProcessRecord getRecordForAppLocked(
5067            IApplicationThread thread) {
5068        if (thread == null) {
5069            return null;
5070        }
5071
5072        int appIndex = getLRURecordIndexForAppLocked(thread);
5073        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5074    }
5075
5076    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5077        // If there are no longer any background processes running,
5078        // and the app that died was not running instrumentation,
5079        // then tell everyone we are now low on memory.
5080        boolean haveBg = false;
5081        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5082            ProcessRecord rec = mLruProcesses.get(i);
5083            if (rec.thread != null
5084                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5085                haveBg = true;
5086                break;
5087            }
5088        }
5089
5090        if (!haveBg) {
5091            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5092            if (doReport) {
5093                long now = SystemClock.uptimeMillis();
5094                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5095                    doReport = false;
5096                } else {
5097                    mLastMemUsageReportTime = now;
5098                }
5099            }
5100            final ArrayList<ProcessMemInfo> memInfos
5101                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5102            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5103            long now = SystemClock.uptimeMillis();
5104            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5105                ProcessRecord rec = mLruProcesses.get(i);
5106                if (rec == dyingProc || rec.thread == null) {
5107                    continue;
5108                }
5109                if (doReport) {
5110                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5111                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5112                }
5113                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5114                    // The low memory report is overriding any current
5115                    // state for a GC request.  Make sure to do
5116                    // heavy/important/visible/foreground processes first.
5117                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5118                        rec.lastRequestedGc = 0;
5119                    } else {
5120                        rec.lastRequestedGc = rec.lastLowMemory;
5121                    }
5122                    rec.reportLowMemory = true;
5123                    rec.lastLowMemory = now;
5124                    mProcessesToGc.remove(rec);
5125                    addProcessToGcListLocked(rec);
5126                }
5127            }
5128            if (doReport) {
5129                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5130                mHandler.sendMessage(msg);
5131            }
5132            scheduleAppGcsLocked();
5133        }
5134    }
5135
5136    final void appDiedLocked(ProcessRecord app) {
5137       appDiedLocked(app, app.pid, app.thread, false);
5138    }
5139
5140    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5141            boolean fromBinderDied) {
5142        // First check if this ProcessRecord is actually active for the pid.
5143        synchronized (mPidsSelfLocked) {
5144            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5145            if (curProc != app) {
5146                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5147                return;
5148            }
5149        }
5150
5151        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5152        synchronized (stats) {
5153            stats.noteProcessDiedLocked(app.info.uid, pid);
5154        }
5155
5156        if (!app.killed) {
5157            if (!fromBinderDied) {
5158                Process.killProcessQuiet(pid);
5159            }
5160            killProcessGroup(app.uid, pid);
5161            app.killed = true;
5162        }
5163
5164        // Clean up already done if the process has been re-started.
5165        if (app.pid == pid && app.thread != null &&
5166                app.thread.asBinder() == thread.asBinder()) {
5167            boolean doLowMem = app.instrumentationClass == null;
5168            boolean doOomAdj = doLowMem;
5169            if (!app.killedByAm) {
5170                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5171                        + ") has died");
5172                mAllowLowerMemLevel = true;
5173            } else {
5174                // Note that we always want to do oom adj to update our state with the
5175                // new number of procs.
5176                mAllowLowerMemLevel = false;
5177                doLowMem = false;
5178            }
5179            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5180            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5181                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5182            handleAppDiedLocked(app, false, true);
5183
5184            if (doOomAdj) {
5185                updateOomAdjLocked();
5186            }
5187            if (doLowMem) {
5188                doLowMemReportIfNeededLocked(app);
5189            }
5190        } else if (app.pid != pid) {
5191            // A new process has already been started.
5192            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5193                    + ") has died and restarted (pid " + app.pid + ").");
5194            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5195        } else if (DEBUG_PROCESSES) {
5196            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5197                    + thread.asBinder());
5198        }
5199    }
5200
5201    /**
5202     * If a stack trace dump file is configured, dump process stack traces.
5203     * @param clearTraces causes the dump file to be erased prior to the new
5204     *    traces being written, if true; when false, the new traces will be
5205     *    appended to any existing file content.
5206     * @param firstPids of dalvik VM processes to dump stack traces for first
5207     * @param lastPids of dalvik VM processes to dump stack traces for last
5208     * @param nativeProcs optional list of native process names to dump stack crawls
5209     * @return file containing stack traces, or null if no dump file is configured
5210     */
5211    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5212            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5213        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5214        if (tracesPath == null || tracesPath.length() == 0) {
5215            return null;
5216        }
5217
5218        File tracesFile = new File(tracesPath);
5219        try {
5220            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5221            tracesFile.createNewFile();
5222            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5223        } catch (IOException e) {
5224            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5225            return null;
5226        }
5227
5228        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5229        return tracesFile;
5230    }
5231
5232    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5233            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5234        // Use a FileObserver to detect when traces finish writing.
5235        // The order of traces is considered important to maintain for legibility.
5236        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5237            @Override
5238            public synchronized void onEvent(int event, String path) { notify(); }
5239        };
5240
5241        try {
5242            observer.startWatching();
5243
5244            // First collect all of the stacks of the most important pids.
5245            if (firstPids != null) {
5246                try {
5247                    int num = firstPids.size();
5248                    for (int i = 0; i < num; i++) {
5249                        synchronized (observer) {
5250                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5251                                    + firstPids.get(i));
5252                            final long sime = SystemClock.elapsedRealtime();
5253                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5254                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5255                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5256                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5257                        }
5258                    }
5259                } catch (InterruptedException e) {
5260                    Slog.wtf(TAG, e);
5261                }
5262            }
5263
5264            // Next collect the stacks of the native pids
5265            if (nativeProcs != null) {
5266                int[] pids = Process.getPidsForCommands(nativeProcs);
5267                if (pids != null) {
5268                    for (int pid : pids) {
5269                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5270                        final long sime = SystemClock.elapsedRealtime();
5271                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5272                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5273                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5274                    }
5275                }
5276            }
5277
5278            // Lastly, measure CPU usage.
5279            if (processCpuTracker != null) {
5280                processCpuTracker.init();
5281                System.gc();
5282                processCpuTracker.update();
5283                try {
5284                    synchronized (processCpuTracker) {
5285                        processCpuTracker.wait(500); // measure over 1/2 second.
5286                    }
5287                } catch (InterruptedException e) {
5288                }
5289                processCpuTracker.update();
5290
5291                // We'll take the stack crawls of just the top apps using CPU.
5292                final int N = processCpuTracker.countWorkingStats();
5293                int numProcs = 0;
5294                for (int i=0; i<N && numProcs<5; i++) {
5295                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5296                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5297                        numProcs++;
5298                        try {
5299                            synchronized (observer) {
5300                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5301                                        + stats.pid);
5302                                final long stime = SystemClock.elapsedRealtime();
5303                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5304                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5305                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5306                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5307                            }
5308                        } catch (InterruptedException e) {
5309                            Slog.wtf(TAG, e);
5310                        }
5311                    } else if (DEBUG_ANR) {
5312                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5313                                + stats.pid);
5314                    }
5315                }
5316            }
5317        } finally {
5318            observer.stopWatching();
5319        }
5320    }
5321
5322    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5323        if (true || IS_USER_BUILD) {
5324            return;
5325        }
5326        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5327        if (tracesPath == null || tracesPath.length() == 0) {
5328            return;
5329        }
5330
5331        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5332        StrictMode.allowThreadDiskWrites();
5333        try {
5334            final File tracesFile = new File(tracesPath);
5335            final File tracesDir = tracesFile.getParentFile();
5336            final File tracesTmp = new File(tracesDir, "__tmp__");
5337            try {
5338                if (tracesFile.exists()) {
5339                    tracesTmp.delete();
5340                    tracesFile.renameTo(tracesTmp);
5341                }
5342                StringBuilder sb = new StringBuilder();
5343                Time tobj = new Time();
5344                tobj.set(System.currentTimeMillis());
5345                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5346                sb.append(": ");
5347                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5348                sb.append(" since ");
5349                sb.append(msg);
5350                FileOutputStream fos = new FileOutputStream(tracesFile);
5351                fos.write(sb.toString().getBytes());
5352                if (app == null) {
5353                    fos.write("\n*** No application process!".getBytes());
5354                }
5355                fos.close();
5356                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5357            } catch (IOException e) {
5358                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5359                return;
5360            }
5361
5362            if (app != null) {
5363                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5364                firstPids.add(app.pid);
5365                dumpStackTraces(tracesPath, firstPids, null, null, null);
5366            }
5367
5368            File lastTracesFile = null;
5369            File curTracesFile = null;
5370            for (int i=9; i>=0; i--) {
5371                String name = String.format(Locale.US, "slow%02d.txt", i);
5372                curTracesFile = new File(tracesDir, name);
5373                if (curTracesFile.exists()) {
5374                    if (lastTracesFile != null) {
5375                        curTracesFile.renameTo(lastTracesFile);
5376                    } else {
5377                        curTracesFile.delete();
5378                    }
5379                }
5380                lastTracesFile = curTracesFile;
5381            }
5382            tracesFile.renameTo(curTracesFile);
5383            if (tracesTmp.exists()) {
5384                tracesTmp.renameTo(tracesFile);
5385            }
5386        } finally {
5387            StrictMode.setThreadPolicy(oldPolicy);
5388        }
5389    }
5390
5391    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5392        if (!mLaunchWarningShown) {
5393            mLaunchWarningShown = true;
5394            mUiHandler.post(new Runnable() {
5395                @Override
5396                public void run() {
5397                    synchronized (ActivityManagerService.this) {
5398                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5399                        d.show();
5400                        mUiHandler.postDelayed(new Runnable() {
5401                            @Override
5402                            public void run() {
5403                                synchronized (ActivityManagerService.this) {
5404                                    d.dismiss();
5405                                    mLaunchWarningShown = false;
5406                                }
5407                            }
5408                        }, 4000);
5409                    }
5410                }
5411            });
5412        }
5413    }
5414
5415    @Override
5416    public boolean clearApplicationUserData(final String packageName,
5417            final IPackageDataObserver observer, int userId) {
5418        enforceNotIsolatedCaller("clearApplicationUserData");
5419        int uid = Binder.getCallingUid();
5420        int pid = Binder.getCallingPid();
5421        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5422                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5423
5424
5425        long callingId = Binder.clearCallingIdentity();
5426        try {
5427            IPackageManager pm = AppGlobals.getPackageManager();
5428            int pkgUid = -1;
5429            synchronized(this) {
5430                if (getPackageManagerInternalLocked().canPackageBeWiped(
5431                        userId, packageName)) {
5432                    throw new SecurityException(
5433                            "Cannot clear data for a device owner or a profile owner");
5434                }
5435
5436                try {
5437                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5438                } catch (RemoteException e) {
5439                }
5440                if (pkgUid == -1) {
5441                    Slog.w(TAG, "Invalid packageName: " + packageName);
5442                    if (observer != null) {
5443                        try {
5444                            observer.onRemoveCompleted(packageName, false);
5445                        } catch (RemoteException e) {
5446                            Slog.i(TAG, "Observer no longer exists.");
5447                        }
5448                    }
5449                    return false;
5450                }
5451                if (uid == pkgUid || checkComponentPermission(
5452                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5453                        pid, uid, -1, true)
5454                        == PackageManager.PERMISSION_GRANTED) {
5455                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5456                } else {
5457                    throw new SecurityException("PID " + pid + " does not have permission "
5458                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5459                                    + " of package " + packageName);
5460                }
5461
5462                // Remove all tasks match the cleared application package and user
5463                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5464                    final TaskRecord tr = mRecentTasks.get(i);
5465                    final String taskPackageName =
5466                            tr.getBaseIntent().getComponent().getPackageName();
5467                    if (tr.userId != userId) continue;
5468                    if (!taskPackageName.equals(packageName)) continue;
5469                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5470                }
5471            }
5472
5473            final int pkgUidF = pkgUid;
5474            final int userIdF = userId;
5475            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5476                @Override
5477                public void onRemoveCompleted(String packageName, boolean succeeded)
5478                        throws RemoteException {
5479                    synchronized (ActivityManagerService.this) {
5480                        finishForceStopPackageLocked(packageName, pkgUidF);
5481                    }
5482
5483                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5484                            Uri.fromParts("package", packageName, null));
5485                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5486                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5487                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5488                            null, null, 0, null, null, null, null, false, false, userIdF);
5489
5490                    if (observer != null) {
5491                        observer.onRemoveCompleted(packageName, succeeded);
5492                    }
5493                }
5494            };
5495
5496            try {
5497                // Clear application user data
5498                pm.clearApplicationUserData(packageName, localObserver, userId);
5499
5500                synchronized(this) {
5501                    // Remove all permissions granted from/to this package
5502                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5503                }
5504
5505                // Remove all zen rules created by this package; revoke it's zen access.
5506                INotificationManager inm = NotificationManager.getService();
5507                inm.removeAutomaticZenRules(packageName);
5508                inm.setNotificationPolicyAccessGranted(packageName, false);
5509
5510            } catch (RemoteException e) {
5511            }
5512        } finally {
5513            Binder.restoreCallingIdentity(callingId);
5514        }
5515        return true;
5516    }
5517
5518    @Override
5519    public void killBackgroundProcesses(final String packageName, int userId) {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED &&
5522                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5523                        != PackageManager.PERMISSION_GRANTED) {
5524            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5525                    + Binder.getCallingPid()
5526                    + ", uid=" + Binder.getCallingUid()
5527                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5528            Slog.w(TAG, msg);
5529            throw new SecurityException(msg);
5530        }
5531
5532        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5533                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5534        long callingId = Binder.clearCallingIdentity();
5535        try {
5536            IPackageManager pm = AppGlobals.getPackageManager();
5537            synchronized(this) {
5538                int appId = -1;
5539                try {
5540                    appId = UserHandle.getAppId(
5541                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5542                } catch (RemoteException e) {
5543                }
5544                if (appId == -1) {
5545                    Slog.w(TAG, "Invalid packageName: " + packageName);
5546                    return;
5547                }
5548                killPackageProcessesLocked(packageName, appId, userId,
5549                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5550            }
5551        } finally {
5552            Binder.restoreCallingIdentity(callingId);
5553        }
5554    }
5555
5556    @Override
5557    public void killAllBackgroundProcesses() {
5558        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5559                != PackageManager.PERMISSION_GRANTED) {
5560            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5561                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5562                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5563            Slog.w(TAG, msg);
5564            throw new SecurityException(msg);
5565        }
5566
5567        final long callingId = Binder.clearCallingIdentity();
5568        try {
5569            synchronized (this) {
5570                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5571                final int NP = mProcessNames.getMap().size();
5572                for (int ip = 0; ip < NP; ip++) {
5573                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5574                    final int NA = apps.size();
5575                    for (int ia = 0; ia < NA; ia++) {
5576                        final ProcessRecord app = apps.valueAt(ia);
5577                        if (app.persistent) {
5578                            // We don't kill persistent processes.
5579                            continue;
5580                        }
5581                        if (app.removed) {
5582                            procs.add(app);
5583                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5584                            app.removed = true;
5585                            procs.add(app);
5586                        }
5587                    }
5588                }
5589
5590                final int N = procs.size();
5591                for (int i = 0; i < N; i++) {
5592                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5593                }
5594
5595                mAllowLowerMemLevel = true;
5596
5597                updateOomAdjLocked();
5598                doLowMemReportIfNeededLocked(null);
5599            }
5600        } finally {
5601            Binder.restoreCallingIdentity(callingId);
5602        }
5603    }
5604
5605    /**
5606     * Kills all background processes, except those matching any of the
5607     * specified properties.
5608     *
5609     * @param minTargetSdk the target SDK version at or above which to preserve
5610     *                     processes, or {@code -1} to ignore the target SDK
5611     * @param maxProcState the process state at or below which to preserve
5612     *                     processes, or {@code -1} to ignore the process state
5613     */
5614    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5615        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5616                != PackageManager.PERMISSION_GRANTED) {
5617            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5618                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5619                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5620            Slog.w(TAG, msg);
5621            throw new SecurityException(msg);
5622        }
5623
5624        final long callingId = Binder.clearCallingIdentity();
5625        try {
5626            synchronized (this) {
5627                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5628                final int NP = mProcessNames.getMap().size();
5629                for (int ip = 0; ip < NP; ip++) {
5630                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5631                    final int NA = apps.size();
5632                    for (int ia = 0; ia < NA; ia++) {
5633                        final ProcessRecord app = apps.valueAt(ia);
5634                        if (app.removed) {
5635                            procs.add(app);
5636                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5637                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5638                            app.removed = true;
5639                            procs.add(app);
5640                        }
5641                    }
5642                }
5643
5644                final int N = procs.size();
5645                for (int i = 0; i < N; i++) {
5646                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5647                }
5648            }
5649        } finally {
5650            Binder.restoreCallingIdentity(callingId);
5651        }
5652    }
5653
5654    @Override
5655    public void forceStopPackage(final String packageName, int userId) {
5656        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5657                != PackageManager.PERMISSION_GRANTED) {
5658            String msg = "Permission Denial: forceStopPackage() from pid="
5659                    + Binder.getCallingPid()
5660                    + ", uid=" + Binder.getCallingUid()
5661                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5662            Slog.w(TAG, msg);
5663            throw new SecurityException(msg);
5664        }
5665        final int callingPid = Binder.getCallingPid();
5666        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5667                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5668        long callingId = Binder.clearCallingIdentity();
5669        try {
5670            IPackageManager pm = AppGlobals.getPackageManager();
5671            synchronized(this) {
5672                int[] users = userId == UserHandle.USER_ALL
5673                        ? mUserController.getUsers() : new int[] { userId };
5674                for (int user : users) {
5675                    int pkgUid = -1;
5676                    try {
5677                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5678                                user);
5679                    } catch (RemoteException e) {
5680                    }
5681                    if (pkgUid == -1) {
5682                        Slog.w(TAG, "Invalid packageName: " + packageName);
5683                        continue;
5684                    }
5685                    try {
5686                        pm.setPackageStoppedState(packageName, true, user);
5687                    } catch (RemoteException e) {
5688                    } catch (IllegalArgumentException e) {
5689                        Slog.w(TAG, "Failed trying to unstop package "
5690                                + packageName + ": " + e);
5691                    }
5692                    if (mUserController.isUserRunningLocked(user, 0)) {
5693                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5694                        finishForceStopPackageLocked(packageName, pkgUid);
5695                    }
5696                }
5697            }
5698        } finally {
5699            Binder.restoreCallingIdentity(callingId);
5700        }
5701    }
5702
5703    @Override
5704    public void addPackageDependency(String packageName) {
5705        synchronized (this) {
5706            int callingPid = Binder.getCallingPid();
5707            if (callingPid == Process.myPid()) {
5708                //  Yeah, um, no.
5709                return;
5710            }
5711            ProcessRecord proc;
5712            synchronized (mPidsSelfLocked) {
5713                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5714            }
5715            if (proc != null) {
5716                if (proc.pkgDeps == null) {
5717                    proc.pkgDeps = new ArraySet<String>(1);
5718                }
5719                proc.pkgDeps.add(packageName);
5720            }
5721        }
5722    }
5723
5724    /*
5725     * The pkg name and app id have to be specified.
5726     */
5727    @Override
5728    public void killApplication(String pkg, int appId, int userId, String reason) {
5729        if (pkg == null) {
5730            return;
5731        }
5732        // Make sure the uid is valid.
5733        if (appId < 0) {
5734            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5735            return;
5736        }
5737        int callerUid = Binder.getCallingUid();
5738        // Only the system server can kill an application
5739        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5740            // Post an aysnc message to kill the application
5741            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5742            msg.arg1 = appId;
5743            msg.arg2 = userId;
5744            Bundle bundle = new Bundle();
5745            bundle.putString("pkg", pkg);
5746            bundle.putString("reason", reason);
5747            msg.obj = bundle;
5748            mHandler.sendMessage(msg);
5749        } else {
5750            throw new SecurityException(callerUid + " cannot kill pkg: " +
5751                    pkg);
5752        }
5753    }
5754
5755    @Override
5756    public void closeSystemDialogs(String reason) {
5757        enforceNotIsolatedCaller("closeSystemDialogs");
5758
5759        final int pid = Binder.getCallingPid();
5760        final int uid = Binder.getCallingUid();
5761        final long origId = Binder.clearCallingIdentity();
5762        try {
5763            synchronized (this) {
5764                // Only allow this from foreground processes, so that background
5765                // applications can't abuse it to prevent system UI from being shown.
5766                if (uid >= Process.FIRST_APPLICATION_UID) {
5767                    ProcessRecord proc;
5768                    synchronized (mPidsSelfLocked) {
5769                        proc = mPidsSelfLocked.get(pid);
5770                    }
5771                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5772                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5773                                + " from background process " + proc);
5774                        return;
5775                    }
5776                }
5777                closeSystemDialogsLocked(reason);
5778            }
5779        } finally {
5780            Binder.restoreCallingIdentity(origId);
5781        }
5782    }
5783
5784    void closeSystemDialogsLocked(String reason) {
5785        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5786        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5787                | Intent.FLAG_RECEIVER_FOREGROUND);
5788        if (reason != null) {
5789            intent.putExtra("reason", reason);
5790        }
5791        mWindowManager.closeSystemDialogs(reason);
5792
5793        mStackSupervisor.closeSystemDialogsLocked();
5794
5795        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5796                AppOpsManager.OP_NONE, null, false, false,
5797                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5798    }
5799
5800    @Override
5801    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5802        enforceNotIsolatedCaller("getProcessMemoryInfo");
5803        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5804        for (int i=pids.length-1; i>=0; i--) {
5805            ProcessRecord proc;
5806            int oomAdj;
5807            synchronized (this) {
5808                synchronized (mPidsSelfLocked) {
5809                    proc = mPidsSelfLocked.get(pids[i]);
5810                    oomAdj = proc != null ? proc.setAdj : 0;
5811                }
5812            }
5813            infos[i] = new Debug.MemoryInfo();
5814            Debug.getMemoryInfo(pids[i], infos[i]);
5815            if (proc != null) {
5816                synchronized (this) {
5817                    if (proc.thread != null && proc.setAdj == oomAdj) {
5818                        // Record this for posterity if the process has been stable.
5819                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5820                                infos[i].getTotalUss(), false, proc.pkgList);
5821                    }
5822                }
5823            }
5824        }
5825        return infos;
5826    }
5827
5828    @Override
5829    public long[] getProcessPss(int[] pids) {
5830        enforceNotIsolatedCaller("getProcessPss");
5831        long[] pss = new long[pids.length];
5832        for (int i=pids.length-1; i>=0; i--) {
5833            ProcessRecord proc;
5834            int oomAdj;
5835            synchronized (this) {
5836                synchronized (mPidsSelfLocked) {
5837                    proc = mPidsSelfLocked.get(pids[i]);
5838                    oomAdj = proc != null ? proc.setAdj : 0;
5839                }
5840            }
5841            long[] tmpUss = new long[1];
5842            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5843            if (proc != null) {
5844                synchronized (this) {
5845                    if (proc.thread != null && proc.setAdj == oomAdj) {
5846                        // Record this for posterity if the process has been stable.
5847                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5848                    }
5849                }
5850            }
5851        }
5852        return pss;
5853    }
5854
5855    @Override
5856    public void killApplicationProcess(String processName, int uid) {
5857        if (processName == null) {
5858            return;
5859        }
5860
5861        int callerUid = Binder.getCallingUid();
5862        // Only the system server can kill an application
5863        if (callerUid == Process.SYSTEM_UID) {
5864            synchronized (this) {
5865                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5866                if (app != null && app.thread != null) {
5867                    try {
5868                        app.thread.scheduleSuicide();
5869                    } catch (RemoteException e) {
5870                        // If the other end already died, then our work here is done.
5871                    }
5872                } else {
5873                    Slog.w(TAG, "Process/uid not found attempting kill of "
5874                            + processName + " / " + uid);
5875                }
5876            }
5877        } else {
5878            throw new SecurityException(callerUid + " cannot kill app process: " +
5879                    processName);
5880        }
5881    }
5882
5883    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5884        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5885                false, true, false, false, UserHandle.getUserId(uid), reason);
5886    }
5887
5888    private void finishForceStopPackageLocked(final String packageName, int uid) {
5889        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5890                Uri.fromParts("package", packageName, null));
5891        if (!mProcessesReady) {
5892            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5893                    | Intent.FLAG_RECEIVER_FOREGROUND);
5894        }
5895        intent.putExtra(Intent.EXTRA_UID, uid);
5896        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5897        broadcastIntentLocked(null, null, intent,
5898                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5899                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5900    }
5901
5902
5903    private final boolean killPackageProcessesLocked(String packageName, int appId,
5904            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5905            boolean doit, boolean evenPersistent, String reason) {
5906        ArrayList<ProcessRecord> procs = new ArrayList<>();
5907
5908        // Remove all processes this package may have touched: all with the
5909        // same UID (except for the system or root user), and all whose name
5910        // matches the package name.
5911        final int NP = mProcessNames.getMap().size();
5912        for (int ip=0; ip<NP; ip++) {
5913            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5914            final int NA = apps.size();
5915            for (int ia=0; ia<NA; ia++) {
5916                ProcessRecord app = apps.valueAt(ia);
5917                if (app.persistent && !evenPersistent) {
5918                    // we don't kill persistent processes
5919                    continue;
5920                }
5921                if (app.removed) {
5922                    if (doit) {
5923                        procs.add(app);
5924                    }
5925                    continue;
5926                }
5927
5928                // Skip process if it doesn't meet our oom adj requirement.
5929                if (app.setAdj < minOomAdj) {
5930                    continue;
5931                }
5932
5933                // If no package is specified, we call all processes under the
5934                // give user id.
5935                if (packageName == null) {
5936                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5937                        continue;
5938                    }
5939                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5940                        continue;
5941                    }
5942                // Package has been specified, we want to hit all processes
5943                // that match it.  We need to qualify this by the processes
5944                // that are running under the specified app and user ID.
5945                } else {
5946                    final boolean isDep = app.pkgDeps != null
5947                            && app.pkgDeps.contains(packageName);
5948                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5949                        continue;
5950                    }
5951                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5952                        continue;
5953                    }
5954                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5955                        continue;
5956                    }
5957                }
5958
5959                // Process has passed all conditions, kill it!
5960                if (!doit) {
5961                    return true;
5962                }
5963                app.removed = true;
5964                procs.add(app);
5965            }
5966        }
5967
5968        int N = procs.size();
5969        for (int i=0; i<N; i++) {
5970            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5971        }
5972        updateOomAdjLocked();
5973        return N > 0;
5974    }
5975
5976    private void cleanupDisabledPackageComponentsLocked(
5977            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5978
5979        Set<String> disabledClasses = null;
5980        boolean packageDisabled = false;
5981        IPackageManager pm = AppGlobals.getPackageManager();
5982
5983        if (changedClasses == null) {
5984            // Nothing changed...
5985            return;
5986        }
5987
5988        // Determine enable/disable state of the package and its components.
5989        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5990        for (int i = changedClasses.length - 1; i >= 0; i--) {
5991            final String changedClass = changedClasses[i];
5992
5993            if (changedClass.equals(packageName)) {
5994                try {
5995                    // Entire package setting changed
5996                    enabled = pm.getApplicationEnabledSetting(packageName,
5997                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5998                } catch (Exception e) {
5999                    // No such package/component; probably racing with uninstall.  In any
6000                    // event it means we have nothing further to do here.
6001                    return;
6002                }
6003                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6004                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6005                if (packageDisabled) {
6006                    // Entire package is disabled.
6007                    // No need to continue to check component states.
6008                    disabledClasses = null;
6009                    break;
6010                }
6011            } else {
6012                try {
6013                    enabled = pm.getComponentEnabledSetting(
6014                            new ComponentName(packageName, changedClass),
6015                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6016                } catch (Exception e) {
6017                    // As above, probably racing with uninstall.
6018                    return;
6019                }
6020                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6021                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6022                    if (disabledClasses == null) {
6023                        disabledClasses = new ArraySet<>(changedClasses.length);
6024                    }
6025                    disabledClasses.add(changedClass);
6026                }
6027            }
6028        }
6029
6030        if (!packageDisabled && disabledClasses == null) {
6031            // Nothing to do here...
6032            return;
6033        }
6034
6035        // Clean-up disabled activities.
6036        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6037                packageName, disabledClasses, true, false, userId) && mBooted) {
6038            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6039            mStackSupervisor.scheduleIdleLocked();
6040        }
6041
6042        // Clean-up disabled tasks
6043        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6044
6045        // Clean-up disabled services.
6046        mServices.bringDownDisabledPackageServicesLocked(
6047                packageName, disabledClasses, userId, false, killProcess, true);
6048
6049        // Clean-up disabled providers.
6050        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6051        mProviderMap.collectPackageProvidersLocked(
6052                packageName, disabledClasses, true, false, userId, providers);
6053        for (int i = providers.size() - 1; i >= 0; i--) {
6054            removeDyingProviderLocked(null, providers.get(i), true);
6055        }
6056
6057        // Clean-up disabled broadcast receivers.
6058        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6059            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6060                    packageName, disabledClasses, userId, true);
6061        }
6062
6063    }
6064
6065    final boolean clearBroadcastQueueForUserLocked(int userId) {
6066        boolean didSomething = false;
6067        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6068            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6069                    null, null, userId, true);
6070        }
6071        return didSomething;
6072    }
6073
6074    final boolean forceStopPackageLocked(String packageName, int appId,
6075            boolean callerWillRestart, boolean purgeCache, boolean doit,
6076            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6077        int i;
6078
6079        if (userId == UserHandle.USER_ALL && packageName == null) {
6080            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6081        }
6082
6083        if (appId < 0 && packageName != null) {
6084            try {
6085                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6086                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6087            } catch (RemoteException e) {
6088            }
6089        }
6090
6091        if (doit) {
6092            if (packageName != null) {
6093                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6094                        + " user=" + userId + ": " + reason);
6095            } else {
6096                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6097            }
6098
6099            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6100        }
6101
6102        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6103                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6104                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6105
6106        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6107
6108        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6109                packageName, null, doit, evenPersistent, userId)) {
6110            if (!doit) {
6111                return true;
6112            }
6113            didSomething = true;
6114        }
6115
6116        if (mServices.bringDownDisabledPackageServicesLocked(
6117                packageName, null, userId, evenPersistent, true, doit)) {
6118            if (!doit) {
6119                return true;
6120            }
6121            didSomething = true;
6122        }
6123
6124        if (packageName == null) {
6125            // Remove all sticky broadcasts from this user.
6126            mStickyBroadcasts.remove(userId);
6127        }
6128
6129        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6130        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6131                userId, providers)) {
6132            if (!doit) {
6133                return true;
6134            }
6135            didSomething = true;
6136        }
6137        for (i = providers.size() - 1; i >= 0; i--) {
6138            removeDyingProviderLocked(null, providers.get(i), true);
6139        }
6140
6141        // Remove transient permissions granted from/to this package/user
6142        removeUriPermissionsForPackageLocked(packageName, userId, false);
6143
6144        if (doit) {
6145            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6146                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6147                        packageName, null, userId, doit);
6148            }
6149        }
6150
6151        if (packageName == null || uninstalling) {
6152            // Remove pending intents.  For now we only do this when force
6153            // stopping users, because we have some problems when doing this
6154            // for packages -- app widgets are not currently cleaned up for
6155            // such packages, so they can be left with bad pending intents.
6156            if (mIntentSenderRecords.size() > 0) {
6157                Iterator<WeakReference<PendingIntentRecord>> it
6158                        = mIntentSenderRecords.values().iterator();
6159                while (it.hasNext()) {
6160                    WeakReference<PendingIntentRecord> wpir = it.next();
6161                    if (wpir == null) {
6162                        it.remove();
6163                        continue;
6164                    }
6165                    PendingIntentRecord pir = wpir.get();
6166                    if (pir == null) {
6167                        it.remove();
6168                        continue;
6169                    }
6170                    if (packageName == null) {
6171                        // Stopping user, remove all objects for the user.
6172                        if (pir.key.userId != userId) {
6173                            // Not the same user, skip it.
6174                            continue;
6175                        }
6176                    } else {
6177                        if (UserHandle.getAppId(pir.uid) != appId) {
6178                            // Different app id, skip it.
6179                            continue;
6180                        }
6181                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6182                            // Different user, skip it.
6183                            continue;
6184                        }
6185                        if (!pir.key.packageName.equals(packageName)) {
6186                            // Different package, skip it.
6187                            continue;
6188                        }
6189                    }
6190                    if (!doit) {
6191                        return true;
6192                    }
6193                    didSomething = true;
6194                    it.remove();
6195                    pir.canceled = true;
6196                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6197                        pir.key.activity.pendingResults.remove(pir.ref);
6198                    }
6199                }
6200            }
6201        }
6202
6203        if (doit) {
6204            if (purgeCache && packageName != null) {
6205                AttributeCache ac = AttributeCache.instance();
6206                if (ac != null) {
6207                    ac.removePackage(packageName);
6208                }
6209            }
6210            if (mBooted) {
6211                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6212                mStackSupervisor.scheduleIdleLocked();
6213            }
6214        }
6215
6216        return didSomething;
6217    }
6218
6219    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6220        ProcessRecord old = mProcessNames.remove(name, uid);
6221        if (old != null) {
6222            old.uidRecord.numProcs--;
6223            if (old.uidRecord.numProcs == 0) {
6224                // No more processes using this uid, tell clients it is gone.
6225                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6226                        "No more processes in " + old.uidRecord);
6227                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6228                mActiveUids.remove(uid);
6229                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6230            }
6231            old.uidRecord = null;
6232        }
6233        mIsolatedProcesses.remove(uid);
6234        return old;
6235    }
6236
6237    private final void addProcessNameLocked(ProcessRecord proc) {
6238        // We shouldn't already have a process under this name, but just in case we
6239        // need to clean up whatever may be there now.
6240        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6241        if (old == proc && proc.persistent) {
6242            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6243            Slog.w(TAG, "Re-adding persistent process " + proc);
6244        } else if (old != null) {
6245            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6246        }
6247        UidRecord uidRec = mActiveUids.get(proc.uid);
6248        if (uidRec == null) {
6249            uidRec = new UidRecord(proc.uid);
6250            // This is the first appearance of the uid, report it now!
6251            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6252                    "Creating new process uid: " + uidRec);
6253            mActiveUids.put(proc.uid, uidRec);
6254            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6255            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6256        }
6257        proc.uidRecord = uidRec;
6258        uidRec.numProcs++;
6259        mProcessNames.put(proc.processName, proc.uid, proc);
6260        if (proc.isolated) {
6261            mIsolatedProcesses.put(proc.uid, proc);
6262        }
6263    }
6264
6265    boolean removeProcessLocked(ProcessRecord app,
6266            boolean callerWillRestart, boolean allowRestart, String reason) {
6267        final String name = app.processName;
6268        final int uid = app.uid;
6269        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6270            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6271
6272        ProcessRecord old = mProcessNames.get(name, uid);
6273        if (old != app) {
6274            // This process is no longer active, so nothing to do.
6275            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6276            return false;
6277        }
6278        removeProcessNameLocked(name, uid);
6279        if (mHeavyWeightProcess == app) {
6280            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6281                    mHeavyWeightProcess.userId, 0));
6282            mHeavyWeightProcess = null;
6283        }
6284        boolean needRestart = false;
6285        if (app.pid > 0 && app.pid != MY_PID) {
6286            int pid = app.pid;
6287            synchronized (mPidsSelfLocked) {
6288                mPidsSelfLocked.remove(pid);
6289                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6290            }
6291            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6292            if (app.isolated) {
6293                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6294            }
6295            boolean willRestart = false;
6296            if (app.persistent && !app.isolated) {
6297                if (!callerWillRestart) {
6298                    willRestart = true;
6299                } else {
6300                    needRestart = true;
6301                }
6302            }
6303            app.kill(reason, true);
6304            handleAppDiedLocked(app, willRestart, allowRestart);
6305            if (willRestart) {
6306                removeLruProcessLocked(app);
6307                addAppLocked(app.info, false, null /* ABI override */);
6308            }
6309        } else {
6310            mRemovedProcesses.add(app);
6311        }
6312
6313        return needRestart;
6314    }
6315
6316    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6317        cleanupAppInLaunchingProvidersLocked(app, true);
6318        removeProcessLocked(app, false, true, "timeout publishing content providers");
6319    }
6320
6321    private final void processStartTimedOutLocked(ProcessRecord app) {
6322        final int pid = app.pid;
6323        boolean gone = false;
6324        synchronized (mPidsSelfLocked) {
6325            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6326            if (knownApp != null && knownApp.thread == null) {
6327                mPidsSelfLocked.remove(pid);
6328                gone = true;
6329            }
6330        }
6331
6332        if (gone) {
6333            Slog.w(TAG, "Process " + app + " failed to attach");
6334            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6335                    pid, app.uid, app.processName);
6336            removeProcessNameLocked(app.processName, app.uid);
6337            if (mHeavyWeightProcess == app) {
6338                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6339                        mHeavyWeightProcess.userId, 0));
6340                mHeavyWeightProcess = null;
6341            }
6342            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6343            if (app.isolated) {
6344                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6345            }
6346            // Take care of any launching providers waiting for this process.
6347            cleanupAppInLaunchingProvidersLocked(app, true);
6348            // Take care of any services that are waiting for the process.
6349            mServices.processStartTimedOutLocked(app);
6350            app.kill("start timeout", true);
6351            removeLruProcessLocked(app);
6352            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6353                Slog.w(TAG, "Unattached app died before backup, skipping");
6354                mHandler.post(new Runnable() {
6355                @Override
6356                    public void run(){
6357                        try {
6358                            IBackupManager bm = IBackupManager.Stub.asInterface(
6359                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6360                            bm.agentDisconnected(app.info.packageName);
6361                        } catch (RemoteException e) {
6362                            // Can't happen; the backup manager is local
6363                        }
6364                    }
6365                });
6366            }
6367            if (isPendingBroadcastProcessLocked(pid)) {
6368                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6369                skipPendingBroadcastLocked(pid);
6370            }
6371        } else {
6372            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6373        }
6374    }
6375
6376    private final boolean attachApplicationLocked(IApplicationThread thread,
6377            int pid) {
6378
6379        // Find the application record that is being attached...  either via
6380        // the pid if we are running in multiple processes, or just pull the
6381        // next app record if we are emulating process with anonymous threads.
6382        ProcessRecord app;
6383        if (pid != MY_PID && pid >= 0) {
6384            synchronized (mPidsSelfLocked) {
6385                app = mPidsSelfLocked.get(pid);
6386            }
6387        } else {
6388            app = null;
6389        }
6390
6391        if (app == null) {
6392            Slog.w(TAG, "No pending application record for pid " + pid
6393                    + " (IApplicationThread " + thread + "); dropping process");
6394            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6395            if (pid > 0 && pid != MY_PID) {
6396                Process.killProcessQuiet(pid);
6397                //TODO: killProcessGroup(app.info.uid, pid);
6398            } else {
6399                try {
6400                    thread.scheduleExit();
6401                } catch (Exception e) {
6402                    // Ignore exceptions.
6403                }
6404            }
6405            return false;
6406        }
6407
6408        // If this application record is still attached to a previous
6409        // process, clean it up now.
6410        if (app.thread != null) {
6411            handleAppDiedLocked(app, true, true);
6412        }
6413
6414        // Tell the process all about itself.
6415
6416        if (DEBUG_ALL) Slog.v(
6417                TAG, "Binding process pid " + pid + " to record " + app);
6418
6419        final String processName = app.processName;
6420        try {
6421            AppDeathRecipient adr = new AppDeathRecipient(
6422                    app, pid, thread);
6423            thread.asBinder().linkToDeath(adr, 0);
6424            app.deathRecipient = adr;
6425        } catch (RemoteException e) {
6426            app.resetPackageList(mProcessStats);
6427            startProcessLocked(app, "link fail", processName);
6428            return false;
6429        }
6430
6431        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6432
6433        app.makeActive(thread, mProcessStats);
6434        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6435        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6436        app.forcingToForeground = null;
6437        updateProcessForegroundLocked(app, false, false);
6438        app.hasShownUi = false;
6439        app.debugging = false;
6440        app.cached = false;
6441        app.killedByAm = false;
6442        app.killed = false;
6443
6444
6445        // We carefully use the same state that PackageManager uses for
6446        // filtering, since we use this flag to decide if we need to install
6447        // providers when user is unlocked later
6448        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6449
6450        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6451
6452        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6453        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6454
6455        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6456            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6457            msg.obj = app;
6458            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6459        }
6460
6461        if (!normalMode) {
6462            Slog.i(TAG, "Launching preboot mode app: " + app);
6463        }
6464
6465        if (DEBUG_ALL) Slog.v(
6466            TAG, "New app record " + app
6467            + " thread=" + thread.asBinder() + " pid=" + pid);
6468        try {
6469            int testMode = IApplicationThread.DEBUG_OFF;
6470            if (mDebugApp != null && mDebugApp.equals(processName)) {
6471                testMode = mWaitForDebugger
6472                    ? IApplicationThread.DEBUG_WAIT
6473                    : IApplicationThread.DEBUG_ON;
6474                app.debugging = true;
6475                if (mDebugTransient) {
6476                    mDebugApp = mOrigDebugApp;
6477                    mWaitForDebugger = mOrigWaitForDebugger;
6478                }
6479            }
6480            String profileFile = app.instrumentationProfileFile;
6481            ParcelFileDescriptor profileFd = null;
6482            int samplingInterval = 0;
6483            boolean profileAutoStop = false;
6484            if (mProfileApp != null && mProfileApp.equals(processName)) {
6485                mProfileProc = app;
6486                profileFile = mProfileFile;
6487                profileFd = mProfileFd;
6488                samplingInterval = mSamplingInterval;
6489                profileAutoStop = mAutoStopProfiler;
6490            }
6491            boolean enableTrackAllocation = false;
6492            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6493                enableTrackAllocation = true;
6494                mTrackAllocationApp = null;
6495            }
6496
6497            // If the app is being launched for restore or full backup, set it up specially
6498            boolean isRestrictedBackupMode = false;
6499            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6500                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6501                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6502                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6503                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6504            }
6505
6506            if (app.instrumentationClass != null) {
6507                notifyPackageUse(app.instrumentationClass.getPackageName(),
6508                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6509            }
6510            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6511                    + processName + " with config " + mConfiguration);
6512            ApplicationInfo appInfo = app.instrumentationInfo != null
6513                    ? app.instrumentationInfo : app.info;
6514            app.compat = compatibilityInfoForPackageLocked(appInfo);
6515            if (profileFd != null) {
6516                profileFd = profileFd.dup();
6517            }
6518            ProfilerInfo profilerInfo = profileFile == null ? null
6519                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6520            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6521                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6522                    app.instrumentationUiAutomationConnection, testMode,
6523                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6524                    isRestrictedBackupMode || !normalMode, app.persistent,
6525                    new Configuration(mConfiguration), app.compat,
6526                    getCommonServicesLocked(app.isolated),
6527                    mCoreSettingsObserver.getCoreSettingsLocked());
6528            updateLruProcessLocked(app, false, null);
6529            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6530        } catch (Exception e) {
6531            // todo: Yikes!  What should we do?  For now we will try to
6532            // start another process, but that could easily get us in
6533            // an infinite loop of restarting processes...
6534            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6535
6536            app.resetPackageList(mProcessStats);
6537            app.unlinkDeathRecipient();
6538            startProcessLocked(app, "bind fail", processName);
6539            return false;
6540        }
6541
6542        // Remove this record from the list of starting applications.
6543        mPersistentStartingProcesses.remove(app);
6544        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6545                "Attach application locked removing on hold: " + app);
6546        mProcessesOnHold.remove(app);
6547
6548        boolean badApp = false;
6549        boolean didSomething = false;
6550
6551        // See if the top visible activity is waiting to run in this process...
6552        if (normalMode) {
6553            try {
6554                if (mStackSupervisor.attachApplicationLocked(app)) {
6555                    didSomething = true;
6556                }
6557            } catch (Exception e) {
6558                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6559                badApp = true;
6560            }
6561        }
6562
6563        // Find any services that should be running in this process...
6564        if (!badApp) {
6565            try {
6566                didSomething |= mServices.attachApplicationLocked(app, processName);
6567            } catch (Exception e) {
6568                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6569                badApp = true;
6570            }
6571        }
6572
6573        // Check if a next-broadcast receiver is in this process...
6574        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6575            try {
6576                didSomething |= sendPendingBroadcastsLocked(app);
6577            } catch (Exception e) {
6578                // If the app died trying to launch the receiver we declare it 'bad'
6579                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6580                badApp = true;
6581            }
6582        }
6583
6584        // Check whether the next backup agent is in this process...
6585        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6586            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6587                    "New app is backup target, launching agent for " + app);
6588            notifyPackageUse(mBackupTarget.appInfo.packageName,
6589                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6590            try {
6591                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6592                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6593                        mBackupTarget.backupMode);
6594            } catch (Exception e) {
6595                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6596                badApp = true;
6597            }
6598        }
6599
6600        if (badApp) {
6601            app.kill("error during init", true);
6602            handleAppDiedLocked(app, false, true);
6603            return false;
6604        }
6605
6606        if (!didSomething) {
6607            updateOomAdjLocked();
6608        }
6609
6610        return true;
6611    }
6612
6613    @Override
6614    public final void attachApplication(IApplicationThread thread) {
6615        synchronized (this) {
6616            int callingPid = Binder.getCallingPid();
6617            final long origId = Binder.clearCallingIdentity();
6618            attachApplicationLocked(thread, callingPid);
6619            Binder.restoreCallingIdentity(origId);
6620        }
6621    }
6622
6623    @Override
6624    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6625        final long origId = Binder.clearCallingIdentity();
6626        synchronized (this) {
6627            ActivityStack stack = ActivityRecord.getStackLocked(token);
6628            if (stack != null) {
6629                ActivityRecord r =
6630                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6631                if (stopProfiling) {
6632                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6633                        try {
6634                            mProfileFd.close();
6635                        } catch (IOException e) {
6636                        }
6637                        clearProfilerLocked();
6638                    }
6639                }
6640            }
6641        }
6642        Binder.restoreCallingIdentity(origId);
6643    }
6644
6645    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6646        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6647                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6648    }
6649
6650    void enableScreenAfterBoot() {
6651        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6652                SystemClock.uptimeMillis());
6653        mWindowManager.enableScreenAfterBoot();
6654
6655        synchronized (this) {
6656            updateEventDispatchingLocked();
6657        }
6658    }
6659
6660    @Override
6661    public void showBootMessage(final CharSequence msg, final boolean always) {
6662        if (Binder.getCallingUid() != Process.myUid()) {
6663            // These days only the core system can call this, so apps can't get in
6664            // the way of what we show about running them.
6665        }
6666        mWindowManager.showBootMessage(msg, always);
6667    }
6668
6669    @Override
6670    public void keyguardWaitingForActivityDrawn() {
6671        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6672        final long token = Binder.clearCallingIdentity();
6673        try {
6674            synchronized (this) {
6675                if (DEBUG_LOCKSCREEN) logLockScreen("");
6676                mWindowManager.keyguardWaitingForActivityDrawn();
6677                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6678                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6679                    updateSleepIfNeededLocked();
6680                }
6681            }
6682        } finally {
6683            Binder.restoreCallingIdentity(token);
6684        }
6685    }
6686
6687    @Override
6688    public void keyguardGoingAway(int flags) {
6689        enforceNotIsolatedCaller("keyguardGoingAway");
6690        final long token = Binder.clearCallingIdentity();
6691        try {
6692            synchronized (this) {
6693                if (DEBUG_LOCKSCREEN) logLockScreen("");
6694                mWindowManager.keyguardGoingAway(flags);
6695                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6696                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6697                    updateSleepIfNeededLocked();
6698
6699                    // Some stack visibility might change (e.g. docked stack)
6700                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6701                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6702                }
6703            }
6704        } finally {
6705            Binder.restoreCallingIdentity(token);
6706        }
6707    }
6708
6709    final void finishBooting() {
6710        synchronized (this) {
6711            if (!mBootAnimationComplete) {
6712                mCallFinishBooting = true;
6713                return;
6714            }
6715            mCallFinishBooting = false;
6716        }
6717
6718        ArraySet<String> completedIsas = new ArraySet<String>();
6719        for (String abi : Build.SUPPORTED_ABIS) {
6720            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6721            final String instructionSet = VMRuntime.getInstructionSet(abi);
6722            if (!completedIsas.contains(instructionSet)) {
6723                try {
6724                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6725                } catch (InstallerException e) {
6726                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6727                            e.getMessage() +")");
6728                }
6729                completedIsas.add(instructionSet);
6730            }
6731        }
6732
6733        IntentFilter pkgFilter = new IntentFilter();
6734        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6735        pkgFilter.addDataScheme("package");
6736        mContext.registerReceiver(new BroadcastReceiver() {
6737            @Override
6738            public void onReceive(Context context, Intent intent) {
6739                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6740                if (pkgs != null) {
6741                    for (String pkg : pkgs) {
6742                        synchronized (ActivityManagerService.this) {
6743                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6744                                    0, "query restart")) {
6745                                setResultCode(Activity.RESULT_OK);
6746                                return;
6747                            }
6748                        }
6749                    }
6750                }
6751            }
6752        }, pkgFilter);
6753
6754        IntentFilter dumpheapFilter = new IntentFilter();
6755        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6756        mContext.registerReceiver(new BroadcastReceiver() {
6757            @Override
6758            public void onReceive(Context context, Intent intent) {
6759                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6760                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6761                } else {
6762                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6763                }
6764            }
6765        }, dumpheapFilter);
6766
6767        // Let system services know.
6768        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6769
6770        synchronized (this) {
6771            // Ensure that any processes we had put on hold are now started
6772            // up.
6773            final int NP = mProcessesOnHold.size();
6774            if (NP > 0) {
6775                ArrayList<ProcessRecord> procs =
6776                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6777                for (int ip=0; ip<NP; ip++) {
6778                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6779                            + procs.get(ip));
6780                    startProcessLocked(procs.get(ip), "on-hold", null);
6781                }
6782            }
6783
6784            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6785                // Start looking for apps that are abusing wake locks.
6786                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6787                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6788                // Tell anyone interested that we are done booting!
6789                SystemProperties.set("sys.boot_completed", "1");
6790
6791                // And trigger dev.bootcomplete if we are not showing encryption progress
6792                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6793                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6794                    SystemProperties.set("dev.bootcomplete", "1");
6795                }
6796                mUserController.sendBootCompletedLocked(
6797                        new IIntentReceiver.Stub() {
6798                            @Override
6799                            public void performReceive(Intent intent, int resultCode,
6800                                    String data, Bundle extras, boolean ordered,
6801                                    boolean sticky, int sendingUser) {
6802                                synchronized (ActivityManagerService.this) {
6803                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6804                                            true, false);
6805                                }
6806                            }
6807                        });
6808                scheduleStartProfilesLocked();
6809            }
6810        }
6811    }
6812
6813    @Override
6814    public void bootAnimationComplete() {
6815        final boolean callFinishBooting;
6816        synchronized (this) {
6817            callFinishBooting = mCallFinishBooting;
6818            mBootAnimationComplete = true;
6819        }
6820        if (callFinishBooting) {
6821            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6822            finishBooting();
6823            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6824        }
6825    }
6826
6827    final void ensureBootCompleted() {
6828        boolean booting;
6829        boolean enableScreen;
6830        synchronized (this) {
6831            booting = mBooting;
6832            mBooting = false;
6833            enableScreen = !mBooted;
6834            mBooted = true;
6835        }
6836
6837        if (booting) {
6838            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6839            finishBooting();
6840            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6841        }
6842
6843        if (enableScreen) {
6844            enableScreenAfterBoot();
6845        }
6846    }
6847
6848    @Override
6849    public final void activityResumed(IBinder token) {
6850        final long origId = Binder.clearCallingIdentity();
6851        synchronized(this) {
6852            ActivityStack stack = ActivityRecord.getStackLocked(token);
6853            if (stack != null) {
6854                stack.activityResumedLocked(token);
6855            }
6856        }
6857        Binder.restoreCallingIdentity(origId);
6858    }
6859
6860    @Override
6861    public final void activityPaused(IBinder token) {
6862        final long origId = Binder.clearCallingIdentity();
6863        synchronized(this) {
6864            ActivityStack stack = ActivityRecord.getStackLocked(token);
6865            if (stack != null) {
6866                stack.activityPausedLocked(token, false);
6867            }
6868        }
6869        Binder.restoreCallingIdentity(origId);
6870    }
6871
6872    @Override
6873    public final void activityStopped(IBinder token, Bundle icicle,
6874            PersistableBundle persistentState, CharSequence description) {
6875        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6876
6877        // Refuse possible leaked file descriptors
6878        if (icicle != null && icicle.hasFileDescriptors()) {
6879            throw new IllegalArgumentException("File descriptors passed in Bundle");
6880        }
6881
6882        final long origId = Binder.clearCallingIdentity();
6883
6884        synchronized (this) {
6885            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6886            if (r != null) {
6887                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6888            }
6889        }
6890
6891        trimApplications();
6892
6893        Binder.restoreCallingIdentity(origId);
6894    }
6895
6896    @Override
6897    public final void activityDestroyed(IBinder token) {
6898        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6899        synchronized (this) {
6900            ActivityStack stack = ActivityRecord.getStackLocked(token);
6901            if (stack != null) {
6902                stack.activityDestroyedLocked(token, "activityDestroyed");
6903            }
6904        }
6905    }
6906
6907    @Override
6908    public final void activityRelaunched(IBinder token) {
6909        final long origId = Binder.clearCallingIdentity();
6910        synchronized (this) {
6911            mStackSupervisor.activityRelaunchedLocked(token);
6912        }
6913        Binder.restoreCallingIdentity(origId);
6914    }
6915
6916    @Override
6917    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6918            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6919        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6920                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6921        synchronized (this) {
6922            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6923            if (record == null) {
6924                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6925                        + "found for: " + token);
6926            }
6927            record.setSizeConfigurations(horizontalSizeConfiguration,
6928                    verticalSizeConfigurations, smallestSizeConfigurations);
6929        }
6930    }
6931
6932    @Override
6933    public final void backgroundResourcesReleased(IBinder token) {
6934        final long origId = Binder.clearCallingIdentity();
6935        try {
6936            synchronized (this) {
6937                ActivityStack stack = ActivityRecord.getStackLocked(token);
6938                if (stack != null) {
6939                    stack.backgroundResourcesReleased();
6940                }
6941            }
6942        } finally {
6943            Binder.restoreCallingIdentity(origId);
6944        }
6945    }
6946
6947    @Override
6948    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6949        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6950    }
6951
6952    @Override
6953    public final void notifyEnterAnimationComplete(IBinder token) {
6954        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6955    }
6956
6957    @Override
6958    public String getCallingPackage(IBinder token) {
6959        synchronized (this) {
6960            ActivityRecord r = getCallingRecordLocked(token);
6961            return r != null ? r.info.packageName : null;
6962        }
6963    }
6964
6965    @Override
6966    public ComponentName getCallingActivity(IBinder token) {
6967        synchronized (this) {
6968            ActivityRecord r = getCallingRecordLocked(token);
6969            return r != null ? r.intent.getComponent() : null;
6970        }
6971    }
6972
6973    private ActivityRecord getCallingRecordLocked(IBinder token) {
6974        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6975        if (r == null) {
6976            return null;
6977        }
6978        return r.resultTo;
6979    }
6980
6981    @Override
6982    public ComponentName getActivityClassForToken(IBinder token) {
6983        synchronized(this) {
6984            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6985            if (r == null) {
6986                return null;
6987            }
6988            return r.intent.getComponent();
6989        }
6990    }
6991
6992    @Override
6993    public String getPackageForToken(IBinder token) {
6994        synchronized(this) {
6995            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6996            if (r == null) {
6997                return null;
6998            }
6999            return r.packageName;
7000        }
7001    }
7002
7003    @Override
7004    public boolean isRootVoiceInteraction(IBinder token) {
7005        synchronized(this) {
7006            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7007            if (r == null) {
7008                return false;
7009            }
7010            return r.rootVoiceInteraction;
7011        }
7012    }
7013
7014    @Override
7015    public IIntentSender getIntentSender(int type,
7016            String packageName, IBinder token, String resultWho,
7017            int requestCode, Intent[] intents, String[] resolvedTypes,
7018            int flags, Bundle bOptions, int userId) {
7019        enforceNotIsolatedCaller("getIntentSender");
7020        // Refuse possible leaked file descriptors
7021        if (intents != null) {
7022            if (intents.length < 1) {
7023                throw new IllegalArgumentException("Intents array length must be >= 1");
7024            }
7025            for (int i=0; i<intents.length; i++) {
7026                Intent intent = intents[i];
7027                if (intent != null) {
7028                    if (intent.hasFileDescriptors()) {
7029                        throw new IllegalArgumentException("File descriptors passed in Intent");
7030                    }
7031                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7032                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7033                        throw new IllegalArgumentException(
7034                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7035                    }
7036                    intents[i] = new Intent(intent);
7037                }
7038            }
7039            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7040                throw new IllegalArgumentException(
7041                        "Intent array length does not match resolvedTypes length");
7042            }
7043        }
7044        if (bOptions != null) {
7045            if (bOptions.hasFileDescriptors()) {
7046                throw new IllegalArgumentException("File descriptors passed in options");
7047            }
7048        }
7049
7050        synchronized(this) {
7051            int callingUid = Binder.getCallingUid();
7052            int origUserId = userId;
7053            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7054                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7055                    ALLOW_NON_FULL, "getIntentSender", null);
7056            if (origUserId == UserHandle.USER_CURRENT) {
7057                // We don't want to evaluate this until the pending intent is
7058                // actually executed.  However, we do want to always do the
7059                // security checking for it above.
7060                userId = UserHandle.USER_CURRENT;
7061            }
7062            try {
7063                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7064                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7065                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7066                    if (!UserHandle.isSameApp(callingUid, uid)) {
7067                        String msg = "Permission Denial: getIntentSender() from pid="
7068                            + Binder.getCallingPid()
7069                            + ", uid=" + Binder.getCallingUid()
7070                            + ", (need uid=" + uid + ")"
7071                            + " is not allowed to send as package " + packageName;
7072                        Slog.w(TAG, msg);
7073                        throw new SecurityException(msg);
7074                    }
7075                }
7076
7077                return getIntentSenderLocked(type, packageName, callingUid, userId,
7078                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7079
7080            } catch (RemoteException e) {
7081                throw new SecurityException(e);
7082            }
7083        }
7084    }
7085
7086    IIntentSender getIntentSenderLocked(int type, String packageName,
7087            int callingUid, int userId, IBinder token, String resultWho,
7088            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7089            Bundle bOptions) {
7090        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7091        ActivityRecord activity = null;
7092        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7093            activity = ActivityRecord.isInStackLocked(token);
7094            if (activity == null) {
7095                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7096                return null;
7097            }
7098            if (activity.finishing) {
7099                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7100                return null;
7101            }
7102        }
7103
7104        // We're going to be splicing together extras before sending, so we're
7105        // okay poking into any contained extras.
7106        if (intents != null) {
7107            for (int i = 0; i < intents.length; i++) {
7108                intents[i].setDefusable(true);
7109            }
7110        }
7111        Bundle.setDefusable(bOptions, true);
7112
7113        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7114        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7115        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7116        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7117                |PendingIntent.FLAG_UPDATE_CURRENT);
7118
7119        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7120                type, packageName, activity, resultWho,
7121                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7122        WeakReference<PendingIntentRecord> ref;
7123        ref = mIntentSenderRecords.get(key);
7124        PendingIntentRecord rec = ref != null ? ref.get() : null;
7125        if (rec != null) {
7126            if (!cancelCurrent) {
7127                if (updateCurrent) {
7128                    if (rec.key.requestIntent != null) {
7129                        rec.key.requestIntent.replaceExtras(intents != null ?
7130                                intents[intents.length - 1] : null);
7131                    }
7132                    if (intents != null) {
7133                        intents[intents.length-1] = rec.key.requestIntent;
7134                        rec.key.allIntents = intents;
7135                        rec.key.allResolvedTypes = resolvedTypes;
7136                    } else {
7137                        rec.key.allIntents = null;
7138                        rec.key.allResolvedTypes = null;
7139                    }
7140                }
7141                return rec;
7142            }
7143            rec.canceled = true;
7144            mIntentSenderRecords.remove(key);
7145        }
7146        if (noCreate) {
7147            return rec;
7148        }
7149        rec = new PendingIntentRecord(this, key, callingUid);
7150        mIntentSenderRecords.put(key, rec.ref);
7151        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7152            if (activity.pendingResults == null) {
7153                activity.pendingResults
7154                        = new HashSet<WeakReference<PendingIntentRecord>>();
7155            }
7156            activity.pendingResults.add(rec.ref);
7157        }
7158        return rec;
7159    }
7160
7161    @Override
7162    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7163            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7164        if (target instanceof PendingIntentRecord) {
7165            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7166                    finishedReceiver, requiredPermission, options);
7167        } else {
7168            if (intent == null) {
7169                // Weird case: someone has given us their own custom IIntentSender, and now
7170                // they have someone else trying to send to it but of course this isn't
7171                // really a PendingIntent, so there is no base Intent, and the caller isn't
7172                // supplying an Intent... but we never want to dispatch a null Intent to
7173                // a receiver, so um...  let's make something up.
7174                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7175                intent = new Intent(Intent.ACTION_MAIN);
7176            }
7177            try {
7178                target.send(code, intent, resolvedType, null, requiredPermission, options);
7179            } catch (RemoteException e) {
7180            }
7181            // Platform code can rely on getting a result back when the send is done, but if
7182            // this intent sender is from outside of the system we can't rely on it doing that.
7183            // So instead we don't give it the result receiver, and instead just directly
7184            // report the finish immediately.
7185            if (finishedReceiver != null) {
7186                try {
7187                    finishedReceiver.performReceive(intent, 0,
7188                            null, null, false, false, UserHandle.getCallingUserId());
7189                } catch (RemoteException e) {
7190                }
7191            }
7192            return 0;
7193        }
7194    }
7195
7196    /**
7197     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7198     *
7199     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7200     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7201     */
7202    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7203        if (DEBUG_WHITELISTS) {
7204            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7205                    + targetUid + ", " + duration + ")");
7206        }
7207        synchronized (mPidsSelfLocked) {
7208            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7209            if (pr == null) {
7210                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7211                return;
7212            }
7213            if (!pr.whitelistManager) {
7214                if (DEBUG_WHITELISTS) {
7215                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7216                            + callerPid + " is not allowed");
7217                }
7218                return;
7219            }
7220        }
7221
7222        final long token = Binder.clearCallingIdentity();
7223        try {
7224            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7225                    true, "pe from uid:" + callerUid);
7226        } finally {
7227            Binder.restoreCallingIdentity(token);
7228        }
7229    }
7230
7231    @Override
7232    public void cancelIntentSender(IIntentSender sender) {
7233        if (!(sender instanceof PendingIntentRecord)) {
7234            return;
7235        }
7236        synchronized(this) {
7237            PendingIntentRecord rec = (PendingIntentRecord)sender;
7238            try {
7239                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7240                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7241                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7242                    String msg = "Permission Denial: cancelIntentSender() from pid="
7243                        + Binder.getCallingPid()
7244                        + ", uid=" + Binder.getCallingUid()
7245                        + " is not allowed to cancel packges "
7246                        + rec.key.packageName;
7247                    Slog.w(TAG, msg);
7248                    throw new SecurityException(msg);
7249                }
7250            } catch (RemoteException e) {
7251                throw new SecurityException(e);
7252            }
7253            cancelIntentSenderLocked(rec, true);
7254        }
7255    }
7256
7257    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7258        rec.canceled = true;
7259        mIntentSenderRecords.remove(rec.key);
7260        if (cleanActivity && rec.key.activity != null) {
7261            rec.key.activity.pendingResults.remove(rec.ref);
7262        }
7263    }
7264
7265    @Override
7266    public String getPackageForIntentSender(IIntentSender pendingResult) {
7267        if (!(pendingResult instanceof PendingIntentRecord)) {
7268            return null;
7269        }
7270        try {
7271            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7272            return res.key.packageName;
7273        } catch (ClassCastException e) {
7274        }
7275        return null;
7276    }
7277
7278    @Override
7279    public int getUidForIntentSender(IIntentSender sender) {
7280        if (sender instanceof PendingIntentRecord) {
7281            try {
7282                PendingIntentRecord res = (PendingIntentRecord)sender;
7283                return res.uid;
7284            } catch (ClassCastException e) {
7285            }
7286        }
7287        return -1;
7288    }
7289
7290    @Override
7291    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7292        if (!(pendingResult instanceof PendingIntentRecord)) {
7293            return false;
7294        }
7295        try {
7296            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7297            if (res.key.allIntents == null) {
7298                return false;
7299            }
7300            for (int i=0; i<res.key.allIntents.length; i++) {
7301                Intent intent = res.key.allIntents[i];
7302                if (intent.getPackage() != null && intent.getComponent() != null) {
7303                    return false;
7304                }
7305            }
7306            return true;
7307        } catch (ClassCastException e) {
7308        }
7309        return false;
7310    }
7311
7312    @Override
7313    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7314        if (!(pendingResult instanceof PendingIntentRecord)) {
7315            return false;
7316        }
7317        try {
7318            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7319            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7320                return true;
7321            }
7322            return false;
7323        } catch (ClassCastException e) {
7324        }
7325        return false;
7326    }
7327
7328    @Override
7329    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7330        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7331                "getIntentForIntentSender()");
7332        if (!(pendingResult instanceof PendingIntentRecord)) {
7333            return null;
7334        }
7335        try {
7336            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7337            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7338        } catch (ClassCastException e) {
7339        }
7340        return null;
7341    }
7342
7343    @Override
7344    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7345        if (!(pendingResult instanceof PendingIntentRecord)) {
7346            return null;
7347        }
7348        try {
7349            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7350            synchronized (this) {
7351                return getTagForIntentSenderLocked(res, prefix);
7352            }
7353        } catch (ClassCastException e) {
7354        }
7355        return null;
7356    }
7357
7358    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7359        final Intent intent = res.key.requestIntent;
7360        if (intent != null) {
7361            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7362                    || res.lastTagPrefix.equals(prefix))) {
7363                return res.lastTag;
7364            }
7365            res.lastTagPrefix = prefix;
7366            final StringBuilder sb = new StringBuilder(128);
7367            if (prefix != null) {
7368                sb.append(prefix);
7369            }
7370            if (intent.getAction() != null) {
7371                sb.append(intent.getAction());
7372            } else if (intent.getComponent() != null) {
7373                intent.getComponent().appendShortString(sb);
7374            } else {
7375                sb.append("?");
7376            }
7377            return res.lastTag = sb.toString();
7378        }
7379        return null;
7380    }
7381
7382    @Override
7383    public void setProcessLimit(int max) {
7384        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7385                "setProcessLimit()");
7386        synchronized (this) {
7387            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7388            mProcessLimitOverride = max;
7389        }
7390        trimApplications();
7391    }
7392
7393    @Override
7394    public int getProcessLimit() {
7395        synchronized (this) {
7396            return mProcessLimitOverride;
7397        }
7398    }
7399
7400    void foregroundTokenDied(ForegroundToken token) {
7401        synchronized (ActivityManagerService.this) {
7402            synchronized (mPidsSelfLocked) {
7403                ForegroundToken cur
7404                    = mForegroundProcesses.get(token.pid);
7405                if (cur != token) {
7406                    return;
7407                }
7408                mForegroundProcesses.remove(token.pid);
7409                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7410                if (pr == null) {
7411                    return;
7412                }
7413                pr.forcingToForeground = null;
7414                updateProcessForegroundLocked(pr, false, false);
7415            }
7416            updateOomAdjLocked();
7417        }
7418    }
7419
7420    @Override
7421    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7422        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7423                "setProcessForeground()");
7424        synchronized(this) {
7425            boolean changed = false;
7426
7427            synchronized (mPidsSelfLocked) {
7428                ProcessRecord pr = mPidsSelfLocked.get(pid);
7429                if (pr == null && isForeground) {
7430                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7431                    return;
7432                }
7433                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7434                if (oldToken != null) {
7435                    oldToken.token.unlinkToDeath(oldToken, 0);
7436                    mForegroundProcesses.remove(pid);
7437                    if (pr != null) {
7438                        pr.forcingToForeground = null;
7439                    }
7440                    changed = true;
7441                }
7442                if (isForeground && token != null) {
7443                    ForegroundToken newToken = new ForegroundToken() {
7444                        @Override
7445                        public void binderDied() {
7446                            foregroundTokenDied(this);
7447                        }
7448                    };
7449                    newToken.pid = pid;
7450                    newToken.token = token;
7451                    try {
7452                        token.linkToDeath(newToken, 0);
7453                        mForegroundProcesses.put(pid, newToken);
7454                        pr.forcingToForeground = token;
7455                        changed = true;
7456                    } catch (RemoteException e) {
7457                        // If the process died while doing this, we will later
7458                        // do the cleanup with the process death link.
7459                    }
7460                }
7461            }
7462
7463            if (changed) {
7464                updateOomAdjLocked();
7465            }
7466        }
7467    }
7468
7469    @Override
7470    public boolean isAppForeground(int uid) throws RemoteException {
7471        synchronized (this) {
7472            UidRecord uidRec = mActiveUids.get(uid);
7473            if (uidRec == null || uidRec.idle) {
7474                return false;
7475            }
7476            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7477        }
7478    }
7479
7480    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7481    // be guarded by permission checking.
7482    int getUidState(int uid) {
7483        synchronized (this) {
7484            UidRecord uidRec = mActiveUids.get(uid);
7485            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7486        }
7487    }
7488
7489    @Override
7490    public boolean isInMultiWindowMode(IBinder token) {
7491        final long origId = Binder.clearCallingIdentity();
7492        try {
7493            synchronized(this) {
7494                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7495                if (r == null) {
7496                    return false;
7497                }
7498                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7499                return !r.task.mFullscreen;
7500            }
7501        } finally {
7502            Binder.restoreCallingIdentity(origId);
7503        }
7504    }
7505
7506    @Override
7507    public boolean isInPictureInPictureMode(IBinder token) {
7508        final long origId = Binder.clearCallingIdentity();
7509        try {
7510            synchronized(this) {
7511                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7512                if (stack == null) {
7513                    return false;
7514                }
7515                return stack.mStackId == PINNED_STACK_ID;
7516            }
7517        } finally {
7518            Binder.restoreCallingIdentity(origId);
7519        }
7520    }
7521
7522    @Override
7523    public void enterPictureInPictureMode(IBinder token) {
7524        final long origId = Binder.clearCallingIdentity();
7525        try {
7526            synchronized(this) {
7527                if (!mSupportsPictureInPicture) {
7528                    throw new IllegalStateException("enterPictureInPictureMode: "
7529                            + "Device doesn't support picture-in-picture mode.");
7530                }
7531
7532                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7533
7534                if (r == null) {
7535                    throw new IllegalStateException("enterPictureInPictureMode: "
7536                            + "Can't find activity for token=" + token);
7537                }
7538
7539                if (!r.supportsPictureInPicture()) {
7540                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7541                            + "Picture-In-Picture not supported for r=" + r);
7542                }
7543
7544                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7545                // current bounds.
7546                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7547                final Rect bounds = (pinnedStack != null)
7548                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7549
7550                mStackSupervisor.moveActivityToPinnedStackLocked(
7551                        r, "enterPictureInPictureMode", bounds);
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(origId);
7555        }
7556    }
7557
7558    // =========================================================
7559    // PROCESS INFO
7560    // =========================================================
7561
7562    static class ProcessInfoService extends IProcessInfoService.Stub {
7563        final ActivityManagerService mActivityManagerService;
7564        ProcessInfoService(ActivityManagerService activityManagerService) {
7565            mActivityManagerService = activityManagerService;
7566        }
7567
7568        @Override
7569        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7570            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7571                    /*in*/ pids, /*out*/ states, null);
7572        }
7573
7574        @Override
7575        public void getProcessStatesAndOomScoresFromPids(
7576                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7577            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7578                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7579        }
7580    }
7581
7582    /**
7583     * For each PID in the given input array, write the current process state
7584     * for that process into the states array, or -1 to indicate that no
7585     * process with the given PID exists. If scores array is provided, write
7586     * the oom score for the process into the scores array, with INVALID_ADJ
7587     * indicating the PID doesn't exist.
7588     */
7589    public void getProcessStatesAndOomScoresForPIDs(
7590            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7591        if (scores != null) {
7592            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7593                    "getProcessStatesAndOomScoresForPIDs()");
7594        }
7595
7596        if (pids == null) {
7597            throw new NullPointerException("pids");
7598        } else if (states == null) {
7599            throw new NullPointerException("states");
7600        } else if (pids.length != states.length) {
7601            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7602        } else if (scores != null && pids.length != scores.length) {
7603            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7604        }
7605
7606        synchronized (mPidsSelfLocked) {
7607            for (int i = 0; i < pids.length; i++) {
7608                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7609                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7610                        pr.curProcState;
7611                if (scores != null) {
7612                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7613                }
7614            }
7615        }
7616    }
7617
7618    // =========================================================
7619    // PERMISSIONS
7620    // =========================================================
7621
7622    static class PermissionController extends IPermissionController.Stub {
7623        ActivityManagerService mActivityManagerService;
7624        PermissionController(ActivityManagerService activityManagerService) {
7625            mActivityManagerService = activityManagerService;
7626        }
7627
7628        @Override
7629        public boolean checkPermission(String permission, int pid, int uid) {
7630            return mActivityManagerService.checkPermission(permission, pid,
7631                    uid) == PackageManager.PERMISSION_GRANTED;
7632        }
7633
7634        @Override
7635        public String[] getPackagesForUid(int uid) {
7636            return mActivityManagerService.mContext.getPackageManager()
7637                    .getPackagesForUid(uid);
7638        }
7639
7640        @Override
7641        public boolean isRuntimePermission(String permission) {
7642            try {
7643                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7644                        .getPermissionInfo(permission, 0);
7645                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7646            } catch (NameNotFoundException nnfe) {
7647                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7648            }
7649            return false;
7650        }
7651    }
7652
7653    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7654        @Override
7655        public int checkComponentPermission(String permission, int pid, int uid,
7656                int owningUid, boolean exported) {
7657            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7658                    owningUid, exported);
7659        }
7660
7661        @Override
7662        public Object getAMSLock() {
7663            return ActivityManagerService.this;
7664        }
7665    }
7666
7667    /**
7668     * This can be called with or without the global lock held.
7669     */
7670    int checkComponentPermission(String permission, int pid, int uid,
7671            int owningUid, boolean exported) {
7672        if (pid == MY_PID) {
7673            return PackageManager.PERMISSION_GRANTED;
7674        }
7675        return ActivityManager.checkComponentPermission(permission, uid,
7676                owningUid, exported);
7677    }
7678
7679    /**
7680     * As the only public entry point for permissions checking, this method
7681     * can enforce the semantic that requesting a check on a null global
7682     * permission is automatically denied.  (Internally a null permission
7683     * string is used when calling {@link #checkComponentPermission} in cases
7684     * when only uid-based security is needed.)
7685     *
7686     * This can be called with or without the global lock held.
7687     */
7688    @Override
7689    public int checkPermission(String permission, int pid, int uid) {
7690        if (permission == null) {
7691            return PackageManager.PERMISSION_DENIED;
7692        }
7693        return checkComponentPermission(permission, pid, uid, -1, true);
7694    }
7695
7696    @Override
7697    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7698        if (permission == null) {
7699            return PackageManager.PERMISSION_DENIED;
7700        }
7701
7702        // We might be performing an operation on behalf of an indirect binder
7703        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7704        // client identity accordingly before proceeding.
7705        Identity tlsIdentity = sCallerIdentity.get();
7706        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7707            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7708                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7709            uid = tlsIdentity.uid;
7710            pid = tlsIdentity.pid;
7711        }
7712
7713        return checkComponentPermission(permission, pid, uid, -1, true);
7714    }
7715
7716    /**
7717     * Binder IPC calls go through the public entry point.
7718     * This can be called with or without the global lock held.
7719     */
7720    int checkCallingPermission(String permission) {
7721        return checkPermission(permission,
7722                Binder.getCallingPid(),
7723                UserHandle.getAppId(Binder.getCallingUid()));
7724    }
7725
7726    /**
7727     * This can be called with or without the global lock held.
7728     */
7729    void enforceCallingPermission(String permission, String func) {
7730        if (checkCallingPermission(permission)
7731                == PackageManager.PERMISSION_GRANTED) {
7732            return;
7733        }
7734
7735        String msg = "Permission Denial: " + func + " from pid="
7736                + Binder.getCallingPid()
7737                + ", uid=" + Binder.getCallingUid()
7738                + " requires " + permission;
7739        Slog.w(TAG, msg);
7740        throw new SecurityException(msg);
7741    }
7742
7743    /**
7744     * Determine if UID is holding permissions required to access {@link Uri} in
7745     * the given {@link ProviderInfo}. Final permission checking is always done
7746     * in {@link ContentProvider}.
7747     */
7748    private final boolean checkHoldingPermissionsLocked(
7749            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7750        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7751                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7752        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7753            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7754                    != PERMISSION_GRANTED) {
7755                return false;
7756            }
7757        }
7758        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7759    }
7760
7761    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7762            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7763        if (pi.applicationInfo.uid == uid) {
7764            return true;
7765        } else if (!pi.exported) {
7766            return false;
7767        }
7768
7769        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7770        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7771        try {
7772            // check if target holds top-level <provider> permissions
7773            if (!readMet && pi.readPermission != null && considerUidPermissions
7774                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7775                readMet = true;
7776            }
7777            if (!writeMet && pi.writePermission != null && considerUidPermissions
7778                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7779                writeMet = true;
7780            }
7781
7782            // track if unprotected read/write is allowed; any denied
7783            // <path-permission> below removes this ability
7784            boolean allowDefaultRead = pi.readPermission == null;
7785            boolean allowDefaultWrite = pi.writePermission == null;
7786
7787            // check if target holds any <path-permission> that match uri
7788            final PathPermission[] pps = pi.pathPermissions;
7789            if (pps != null) {
7790                final String path = grantUri.uri.getPath();
7791                int i = pps.length;
7792                while (i > 0 && (!readMet || !writeMet)) {
7793                    i--;
7794                    PathPermission pp = pps[i];
7795                    if (pp.match(path)) {
7796                        if (!readMet) {
7797                            final String pprperm = pp.getReadPermission();
7798                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7799                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7800                                    + ": match=" + pp.match(path)
7801                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7802                            if (pprperm != null) {
7803                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7804                                        == PERMISSION_GRANTED) {
7805                                    readMet = true;
7806                                } else {
7807                                    allowDefaultRead = false;
7808                                }
7809                            }
7810                        }
7811                        if (!writeMet) {
7812                            final String ppwperm = pp.getWritePermission();
7813                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7814                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7815                                    + ": match=" + pp.match(path)
7816                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7817                            if (ppwperm != null) {
7818                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7819                                        == PERMISSION_GRANTED) {
7820                                    writeMet = true;
7821                                } else {
7822                                    allowDefaultWrite = false;
7823                                }
7824                            }
7825                        }
7826                    }
7827                }
7828            }
7829
7830            // grant unprotected <provider> read/write, if not blocked by
7831            // <path-permission> above
7832            if (allowDefaultRead) readMet = true;
7833            if (allowDefaultWrite) writeMet = true;
7834
7835        } catch (RemoteException e) {
7836            return false;
7837        }
7838
7839        return readMet && writeMet;
7840    }
7841
7842    public int getAppStartMode(int uid, String packageName) {
7843        synchronized (this) {
7844            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7845        }
7846    }
7847
7848    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7849            boolean allowWhenForeground) {
7850        UidRecord uidRec = mActiveUids.get(uid);
7851        if (!mLenientBackgroundCheck) {
7852            if (!allowWhenForeground || uidRec == null
7853                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7854                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7855                        packageName) != AppOpsManager.MODE_ALLOWED) {
7856                    return ActivityManager.APP_START_MODE_DELAYED;
7857                }
7858            }
7859
7860        } else if (uidRec == null || uidRec.idle) {
7861            if (callingPid >= 0) {
7862                ProcessRecord proc;
7863                synchronized (mPidsSelfLocked) {
7864                    proc = mPidsSelfLocked.get(callingPid);
7865                }
7866                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7867                    // Whoever is instigating this is in the foreground, so we will allow it
7868                    // to go through.
7869                    return ActivityManager.APP_START_MODE_NORMAL;
7870                }
7871            }
7872            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7873                    != AppOpsManager.MODE_ALLOWED) {
7874                return ActivityManager.APP_START_MODE_DELAYED;
7875            }
7876        }
7877        return ActivityManager.APP_START_MODE_NORMAL;
7878    }
7879
7880    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7881        ProviderInfo pi = null;
7882        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7883        if (cpr != null) {
7884            pi = cpr.info;
7885        } else {
7886            try {
7887                pi = AppGlobals.getPackageManager().resolveContentProvider(
7888                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7889                        userHandle);
7890            } catch (RemoteException ex) {
7891            }
7892        }
7893        return pi;
7894    }
7895
7896    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7897        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7898        if (targetUris != null) {
7899            return targetUris.get(grantUri);
7900        }
7901        return null;
7902    }
7903
7904    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7905            String targetPkg, int targetUid, GrantUri grantUri) {
7906        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7907        if (targetUris == null) {
7908            targetUris = Maps.newArrayMap();
7909            mGrantedUriPermissions.put(targetUid, targetUris);
7910        }
7911
7912        UriPermission perm = targetUris.get(grantUri);
7913        if (perm == null) {
7914            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7915            targetUris.put(grantUri, perm);
7916        }
7917
7918        return perm;
7919    }
7920
7921    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7922            final int modeFlags) {
7923        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7924        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7925                : UriPermission.STRENGTH_OWNED;
7926
7927        // Root gets to do everything.
7928        if (uid == 0) {
7929            return true;
7930        }
7931
7932        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7933        if (perms == null) return false;
7934
7935        // First look for exact match
7936        final UriPermission exactPerm = perms.get(grantUri);
7937        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7938            return true;
7939        }
7940
7941        // No exact match, look for prefixes
7942        final int N = perms.size();
7943        for (int i = 0; i < N; i++) {
7944            final UriPermission perm = perms.valueAt(i);
7945            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7946                    && perm.getStrength(modeFlags) >= minStrength) {
7947                return true;
7948            }
7949        }
7950
7951        return false;
7952    }
7953
7954    /**
7955     * @param uri This uri must NOT contain an embedded userId.
7956     * @param userId The userId in which the uri is to be resolved.
7957     */
7958    @Override
7959    public int checkUriPermission(Uri uri, int pid, int uid,
7960            final int modeFlags, int userId, IBinder callerToken) {
7961        enforceNotIsolatedCaller("checkUriPermission");
7962
7963        // Another redirected-binder-call permissions check as in
7964        // {@link checkPermissionWithToken}.
7965        Identity tlsIdentity = sCallerIdentity.get();
7966        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7967            uid = tlsIdentity.uid;
7968            pid = tlsIdentity.pid;
7969        }
7970
7971        // Our own process gets to do everything.
7972        if (pid == MY_PID) {
7973            return PackageManager.PERMISSION_GRANTED;
7974        }
7975        synchronized (this) {
7976            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7977                    ? PackageManager.PERMISSION_GRANTED
7978                    : PackageManager.PERMISSION_DENIED;
7979        }
7980    }
7981
7982    /**
7983     * Check if the targetPkg can be granted permission to access uri by
7984     * the callingUid using the given modeFlags.  Throws a security exception
7985     * if callingUid is not allowed to do this.  Returns the uid of the target
7986     * if the URI permission grant should be performed; returns -1 if it is not
7987     * needed (for example targetPkg already has permission to access the URI).
7988     * If you already know the uid of the target, you can supply it in
7989     * lastTargetUid else set that to -1.
7990     */
7991    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7992            final int modeFlags, int lastTargetUid) {
7993        if (!Intent.isAccessUriMode(modeFlags)) {
7994            return -1;
7995        }
7996
7997        if (targetPkg != null) {
7998            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7999                    "Checking grant " + targetPkg + " permission to " + grantUri);
8000        }
8001
8002        final IPackageManager pm = AppGlobals.getPackageManager();
8003
8004        // If this is not a content: uri, we can't do anything with it.
8005        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8006            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8007                    "Can't grant URI permission for non-content URI: " + grantUri);
8008            return -1;
8009        }
8010
8011        final String authority = grantUri.uri.getAuthority();
8012        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8013                MATCH_DEBUG_TRIAGED_MISSING);
8014        if (pi == null) {
8015            Slog.w(TAG, "No content provider found for permission check: " +
8016                    grantUri.uri.toSafeString());
8017            return -1;
8018        }
8019
8020        int targetUid = lastTargetUid;
8021        if (targetUid < 0 && targetPkg != null) {
8022            try {
8023                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8024                        UserHandle.getUserId(callingUid));
8025                if (targetUid < 0) {
8026                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8027                            "Can't grant URI permission no uid for: " + targetPkg);
8028                    return -1;
8029                }
8030            } catch (RemoteException ex) {
8031                return -1;
8032            }
8033        }
8034
8035        if (targetUid >= 0) {
8036            // First...  does the target actually need this permission?
8037            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8038                // No need to grant the target this permission.
8039                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8040                        "Target " + targetPkg + " already has full permission to " + grantUri);
8041                return -1;
8042            }
8043        } else {
8044            // First...  there is no target package, so can anyone access it?
8045            boolean allowed = pi.exported;
8046            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8047                if (pi.readPermission != null) {
8048                    allowed = false;
8049                }
8050            }
8051            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8052                if (pi.writePermission != null) {
8053                    allowed = false;
8054                }
8055            }
8056            if (allowed) {
8057                return -1;
8058            }
8059        }
8060
8061        /* There is a special cross user grant if:
8062         * - The target is on another user.
8063         * - Apps on the current user can access the uri without any uid permissions.
8064         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8065         * grant uri permissions.
8066         */
8067        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8068                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8069                modeFlags, false /*without considering the uid permissions*/);
8070
8071        // Second...  is the provider allowing granting of URI permissions?
8072        if (!specialCrossUserGrant) {
8073            if (!pi.grantUriPermissions) {
8074                throw new SecurityException("Provider " + pi.packageName
8075                        + "/" + pi.name
8076                        + " does not allow granting of Uri permissions (uri "
8077                        + grantUri + ")");
8078            }
8079            if (pi.uriPermissionPatterns != null) {
8080                final int N = pi.uriPermissionPatterns.length;
8081                boolean allowed = false;
8082                for (int i=0; i<N; i++) {
8083                    if (pi.uriPermissionPatterns[i] != null
8084                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8085                        allowed = true;
8086                        break;
8087                    }
8088                }
8089                if (!allowed) {
8090                    throw new SecurityException("Provider " + pi.packageName
8091                            + "/" + pi.name
8092                            + " does not allow granting of permission to path of Uri "
8093                            + grantUri);
8094                }
8095            }
8096        }
8097
8098        // Third...  does the caller itself have permission to access
8099        // this uri?
8100        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8101            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8102                // Require they hold a strong enough Uri permission
8103                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8104                    throw new SecurityException("Uid " + callingUid
8105                            + " does not have permission to uri " + grantUri);
8106                }
8107            }
8108        }
8109        return targetUid;
8110    }
8111
8112    /**
8113     * @param uri This uri must NOT contain an embedded userId.
8114     * @param userId The userId in which the uri is to be resolved.
8115     */
8116    @Override
8117    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8118            final int modeFlags, int userId) {
8119        enforceNotIsolatedCaller("checkGrantUriPermission");
8120        synchronized(this) {
8121            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8122                    new GrantUri(userId, uri, false), modeFlags, -1);
8123        }
8124    }
8125
8126    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8127            final int modeFlags, UriPermissionOwner owner) {
8128        if (!Intent.isAccessUriMode(modeFlags)) {
8129            return;
8130        }
8131
8132        // So here we are: the caller has the assumed permission
8133        // to the uri, and the target doesn't.  Let's now give this to
8134        // the target.
8135
8136        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8138
8139        final String authority = grantUri.uri.getAuthority();
8140        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8141                MATCH_DEBUG_TRIAGED_MISSING);
8142        if (pi == null) {
8143            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8144            return;
8145        }
8146
8147        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8148            grantUri.prefix = true;
8149        }
8150        final UriPermission perm = findOrCreateUriPermissionLocked(
8151                pi.packageName, targetPkg, targetUid, grantUri);
8152        perm.grantModes(modeFlags, owner);
8153    }
8154
8155    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8156            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8157        if (targetPkg == null) {
8158            throw new NullPointerException("targetPkg");
8159        }
8160        int targetUid;
8161        final IPackageManager pm = AppGlobals.getPackageManager();
8162        try {
8163            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8164        } catch (RemoteException ex) {
8165            return;
8166        }
8167
8168        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8169                targetUid);
8170        if (targetUid < 0) {
8171            return;
8172        }
8173
8174        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8175                owner);
8176    }
8177
8178    static class NeededUriGrants extends ArrayList<GrantUri> {
8179        final String targetPkg;
8180        final int targetUid;
8181        final int flags;
8182
8183        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8184            this.targetPkg = targetPkg;
8185            this.targetUid = targetUid;
8186            this.flags = flags;
8187        }
8188    }
8189
8190    /**
8191     * Like checkGrantUriPermissionLocked, but takes an Intent.
8192     */
8193    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8194            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8195        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8196                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8197                + " clip=" + (intent != null ? intent.getClipData() : null)
8198                + " from " + intent + "; flags=0x"
8199                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8200
8201        if (targetPkg == null) {
8202            throw new NullPointerException("targetPkg");
8203        }
8204
8205        if (intent == null) {
8206            return null;
8207        }
8208        Uri data = intent.getData();
8209        ClipData clip = intent.getClipData();
8210        if (data == null && clip == null) {
8211            return null;
8212        }
8213        // Default userId for uris in the intent (if they don't specify it themselves)
8214        int contentUserHint = intent.getContentUserHint();
8215        if (contentUserHint == UserHandle.USER_CURRENT) {
8216            contentUserHint = UserHandle.getUserId(callingUid);
8217        }
8218        final IPackageManager pm = AppGlobals.getPackageManager();
8219        int targetUid;
8220        if (needed != null) {
8221            targetUid = needed.targetUid;
8222        } else {
8223            try {
8224                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8225                        targetUserId);
8226            } catch (RemoteException ex) {
8227                return null;
8228            }
8229            if (targetUid < 0) {
8230                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8231                        "Can't grant URI permission no uid for: " + targetPkg
8232                        + " on user " + targetUserId);
8233                return null;
8234            }
8235        }
8236        if (data != null) {
8237            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8238            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8239                    targetUid);
8240            if (targetUid > 0) {
8241                if (needed == null) {
8242                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8243                }
8244                needed.add(grantUri);
8245            }
8246        }
8247        if (clip != null) {
8248            for (int i=0; i<clip.getItemCount(); i++) {
8249                Uri uri = clip.getItemAt(i).getUri();
8250                if (uri != null) {
8251                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8252                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8253                            targetUid);
8254                    if (targetUid > 0) {
8255                        if (needed == null) {
8256                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8257                        }
8258                        needed.add(grantUri);
8259                    }
8260                } else {
8261                    Intent clipIntent = clip.getItemAt(i).getIntent();
8262                    if (clipIntent != null) {
8263                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8264                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8265                        if (newNeeded != null) {
8266                            needed = newNeeded;
8267                        }
8268                    }
8269                }
8270            }
8271        }
8272
8273        return needed;
8274    }
8275
8276    /**
8277     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8278     */
8279    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8280            UriPermissionOwner owner) {
8281        if (needed != null) {
8282            for (int i=0; i<needed.size(); i++) {
8283                GrantUri grantUri = needed.get(i);
8284                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8285                        grantUri, needed.flags, owner);
8286            }
8287        }
8288    }
8289
8290    void grantUriPermissionFromIntentLocked(int callingUid,
8291            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8292        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8293                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8294        if (needed == null) {
8295            return;
8296        }
8297
8298        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8299    }
8300
8301    /**
8302     * @param uri This uri must NOT contain an embedded userId.
8303     * @param userId The userId in which the uri is to be resolved.
8304     */
8305    @Override
8306    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8307            final int modeFlags, int userId) {
8308        enforceNotIsolatedCaller("grantUriPermission");
8309        GrantUri grantUri = new GrantUri(userId, uri, false);
8310        synchronized(this) {
8311            final ProcessRecord r = getRecordForAppLocked(caller);
8312            if (r == null) {
8313                throw new SecurityException("Unable to find app for caller "
8314                        + caller
8315                        + " when granting permission to uri " + grantUri);
8316            }
8317            if (targetPkg == null) {
8318                throw new IllegalArgumentException("null target");
8319            }
8320            if (grantUri == null) {
8321                throw new IllegalArgumentException("null uri");
8322            }
8323
8324            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8325                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8326                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8327                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8328
8329            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8330                    UserHandle.getUserId(r.uid));
8331        }
8332    }
8333
8334    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8335        if (perm.modeFlags == 0) {
8336            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8337                    perm.targetUid);
8338            if (perms != null) {
8339                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8340                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8341
8342                perms.remove(perm.uri);
8343                if (perms.isEmpty()) {
8344                    mGrantedUriPermissions.remove(perm.targetUid);
8345                }
8346            }
8347        }
8348    }
8349
8350    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8351        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8352                "Revoking all granted permissions to " + grantUri);
8353
8354        final IPackageManager pm = AppGlobals.getPackageManager();
8355        final String authority = grantUri.uri.getAuthority();
8356        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8357                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8358        if (pi == null) {
8359            Slog.w(TAG, "No content provider found for permission revoke: "
8360                    + grantUri.toSafeString());
8361            return;
8362        }
8363
8364        // Does the caller have this permission on the URI?
8365        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8366            // If they don't have direct access to the URI, then revoke any
8367            // ownerless URI permissions that have been granted to them.
8368            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8369            if (perms != null) {
8370                boolean persistChanged = false;
8371                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8372                    final UriPermission perm = it.next();
8373                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8374                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8375                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8376                                "Revoking non-owned " + perm.targetUid
8377                                + " permission to " + perm.uri);
8378                        persistChanged |= perm.revokeModes(
8379                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8380                        if (perm.modeFlags == 0) {
8381                            it.remove();
8382                        }
8383                    }
8384                }
8385                if (perms.isEmpty()) {
8386                    mGrantedUriPermissions.remove(callingUid);
8387                }
8388                if (persistChanged) {
8389                    schedulePersistUriGrants();
8390                }
8391            }
8392            return;
8393        }
8394
8395        boolean persistChanged = false;
8396
8397        // Go through all of the permissions and remove any that match.
8398        int N = mGrantedUriPermissions.size();
8399        for (int i = 0; i < N; i++) {
8400            final int targetUid = mGrantedUriPermissions.keyAt(i);
8401            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8402
8403            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8404                final UriPermission perm = it.next();
8405                if (perm.uri.sourceUserId == grantUri.sourceUserId
8406                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8407                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8408                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8409                    persistChanged |= perm.revokeModes(
8410                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8411                    if (perm.modeFlags == 0) {
8412                        it.remove();
8413                    }
8414                }
8415            }
8416
8417            if (perms.isEmpty()) {
8418                mGrantedUriPermissions.remove(targetUid);
8419                N--;
8420                i--;
8421            }
8422        }
8423
8424        if (persistChanged) {
8425            schedulePersistUriGrants();
8426        }
8427    }
8428
8429    /**
8430     * @param uri This uri must NOT contain an embedded userId.
8431     * @param userId The userId in which the uri is to be resolved.
8432     */
8433    @Override
8434    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8435            int userId) {
8436        enforceNotIsolatedCaller("revokeUriPermission");
8437        synchronized(this) {
8438            final ProcessRecord r = getRecordForAppLocked(caller);
8439            if (r == null) {
8440                throw new SecurityException("Unable to find app for caller "
8441                        + caller
8442                        + " when revoking permission to uri " + uri);
8443            }
8444            if (uri == null) {
8445                Slog.w(TAG, "revokeUriPermission: null uri");
8446                return;
8447            }
8448
8449            if (!Intent.isAccessUriMode(modeFlags)) {
8450                return;
8451            }
8452
8453            final String authority = uri.getAuthority();
8454            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8455                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8456            if (pi == null) {
8457                Slog.w(TAG, "No content provider found for permission revoke: "
8458                        + uri.toSafeString());
8459                return;
8460            }
8461
8462            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8463        }
8464    }
8465
8466    /**
8467     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8468     * given package.
8469     *
8470     * @param packageName Package name to match, or {@code null} to apply to all
8471     *            packages.
8472     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8473     *            to all users.
8474     * @param persistable If persistable grants should be removed.
8475     */
8476    private void removeUriPermissionsForPackageLocked(
8477            String packageName, int userHandle, boolean persistable) {
8478        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8479            throw new IllegalArgumentException("Must narrow by either package or user");
8480        }
8481
8482        boolean persistChanged = false;
8483
8484        int N = mGrantedUriPermissions.size();
8485        for (int i = 0; i < N; i++) {
8486            final int targetUid = mGrantedUriPermissions.keyAt(i);
8487            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8488
8489            // Only inspect grants matching user
8490            if (userHandle == UserHandle.USER_ALL
8491                    || userHandle == UserHandle.getUserId(targetUid)) {
8492                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8493                    final UriPermission perm = it.next();
8494
8495                    // Only inspect grants matching package
8496                    if (packageName == null || perm.sourcePkg.equals(packageName)
8497                            || perm.targetPkg.equals(packageName)) {
8498                        persistChanged |= perm.revokeModes(persistable
8499                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8500
8501                        // Only remove when no modes remain; any persisted grants
8502                        // will keep this alive.
8503                        if (perm.modeFlags == 0) {
8504                            it.remove();
8505                        }
8506                    }
8507                }
8508
8509                if (perms.isEmpty()) {
8510                    mGrantedUriPermissions.remove(targetUid);
8511                    N--;
8512                    i--;
8513                }
8514            }
8515        }
8516
8517        if (persistChanged) {
8518            schedulePersistUriGrants();
8519        }
8520    }
8521
8522    @Override
8523    public IBinder newUriPermissionOwner(String name) {
8524        enforceNotIsolatedCaller("newUriPermissionOwner");
8525        synchronized(this) {
8526            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8527            return owner.getExternalTokenLocked();
8528        }
8529    }
8530
8531    @Override
8532    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8533        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8534        synchronized(this) {
8535            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8536            if (r == null) {
8537                throw new IllegalArgumentException("Activity does not exist; token="
8538                        + activityToken);
8539            }
8540            return r.getUriPermissionsLocked().getExternalTokenLocked();
8541        }
8542    }
8543    /**
8544     * @param uri This uri must NOT contain an embedded userId.
8545     * @param sourceUserId The userId in which the uri is to be resolved.
8546     * @param targetUserId The userId of the app that receives the grant.
8547     */
8548    @Override
8549    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8550            final int modeFlags, int sourceUserId, int targetUserId) {
8551        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8552                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8553                "grantUriPermissionFromOwner", null);
8554        synchronized(this) {
8555            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8556            if (owner == null) {
8557                throw new IllegalArgumentException("Unknown owner: " + token);
8558            }
8559            if (fromUid != Binder.getCallingUid()) {
8560                if (Binder.getCallingUid() != Process.myUid()) {
8561                    // Only system code can grant URI permissions on behalf
8562                    // of other users.
8563                    throw new SecurityException("nice try");
8564                }
8565            }
8566            if (targetPkg == null) {
8567                throw new IllegalArgumentException("null target");
8568            }
8569            if (uri == null) {
8570                throw new IllegalArgumentException("null uri");
8571            }
8572
8573            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8574                    modeFlags, owner, targetUserId);
8575        }
8576    }
8577
8578    /**
8579     * @param uri This uri must NOT contain an embedded userId.
8580     * @param userId The userId in which the uri is to be resolved.
8581     */
8582    @Override
8583    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8584        synchronized(this) {
8585            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8586            if (owner == null) {
8587                throw new IllegalArgumentException("Unknown owner: " + token);
8588            }
8589
8590            if (uri == null) {
8591                owner.removeUriPermissionsLocked(mode);
8592            } else {
8593                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8594            }
8595        }
8596    }
8597
8598    private void schedulePersistUriGrants() {
8599        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8600            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8601                    10 * DateUtils.SECOND_IN_MILLIS);
8602        }
8603    }
8604
8605    private void writeGrantedUriPermissions() {
8606        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8607
8608        // Snapshot permissions so we can persist without lock
8609        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8610        synchronized (this) {
8611            final int size = mGrantedUriPermissions.size();
8612            for (int i = 0; i < size; i++) {
8613                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8614                for (UriPermission perm : perms.values()) {
8615                    if (perm.persistedModeFlags != 0) {
8616                        persist.add(perm.snapshot());
8617                    }
8618                }
8619            }
8620        }
8621
8622        FileOutputStream fos = null;
8623        try {
8624            fos = mGrantFile.startWrite();
8625
8626            XmlSerializer out = new FastXmlSerializer();
8627            out.setOutput(fos, StandardCharsets.UTF_8.name());
8628            out.startDocument(null, true);
8629            out.startTag(null, TAG_URI_GRANTS);
8630            for (UriPermission.Snapshot perm : persist) {
8631                out.startTag(null, TAG_URI_GRANT);
8632                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8633                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8634                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8635                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8636                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8637                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8638                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8639                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8640                out.endTag(null, TAG_URI_GRANT);
8641            }
8642            out.endTag(null, TAG_URI_GRANTS);
8643            out.endDocument();
8644
8645            mGrantFile.finishWrite(fos);
8646        } catch (IOException e) {
8647            if (fos != null) {
8648                mGrantFile.failWrite(fos);
8649            }
8650        }
8651    }
8652
8653    private void readGrantedUriPermissionsLocked() {
8654        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8655
8656        final long now = System.currentTimeMillis();
8657
8658        FileInputStream fis = null;
8659        try {
8660            fis = mGrantFile.openRead();
8661            final XmlPullParser in = Xml.newPullParser();
8662            in.setInput(fis, StandardCharsets.UTF_8.name());
8663
8664            int type;
8665            while ((type = in.next()) != END_DOCUMENT) {
8666                final String tag = in.getName();
8667                if (type == START_TAG) {
8668                    if (TAG_URI_GRANT.equals(tag)) {
8669                        final int sourceUserId;
8670                        final int targetUserId;
8671                        final int userHandle = readIntAttribute(in,
8672                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8673                        if (userHandle != UserHandle.USER_NULL) {
8674                            // For backwards compatibility.
8675                            sourceUserId = userHandle;
8676                            targetUserId = userHandle;
8677                        } else {
8678                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8679                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8680                        }
8681                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8682                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8683                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8684                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8685                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8686                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8687
8688                        // Sanity check that provider still belongs to source package
8689                        // Both direct boot aware and unaware packages are fine as we
8690                        // will do filtering at query time to avoid multiple parsing.
8691                        final ProviderInfo pi = getProviderInfoLocked(
8692                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8693                                        | MATCH_DIRECT_BOOT_UNAWARE);
8694                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8695                            int targetUid = -1;
8696                            try {
8697                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8698                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8699                            } catch (RemoteException e) {
8700                            }
8701                            if (targetUid != -1) {
8702                                final UriPermission perm = findOrCreateUriPermissionLocked(
8703                                        sourcePkg, targetPkg, targetUid,
8704                                        new GrantUri(sourceUserId, uri, prefix));
8705                                perm.initPersistedModes(modeFlags, createdTime);
8706                            }
8707                        } else {
8708                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8709                                    + " but instead found " + pi);
8710                        }
8711                    }
8712                }
8713            }
8714        } catch (FileNotFoundException e) {
8715            // Missing grants is okay
8716        } catch (IOException e) {
8717            Slog.wtf(TAG, "Failed reading Uri grants", e);
8718        } catch (XmlPullParserException e) {
8719            Slog.wtf(TAG, "Failed reading Uri grants", e);
8720        } finally {
8721            IoUtils.closeQuietly(fis);
8722        }
8723    }
8724
8725    /**
8726     * @param uri This uri must NOT contain an embedded userId.
8727     * @param userId The userId in which the uri is to be resolved.
8728     */
8729    @Override
8730    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8731        enforceNotIsolatedCaller("takePersistableUriPermission");
8732
8733        Preconditions.checkFlagsArgument(modeFlags,
8734                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8735
8736        synchronized (this) {
8737            final int callingUid = Binder.getCallingUid();
8738            boolean persistChanged = false;
8739            GrantUri grantUri = new GrantUri(userId, uri, false);
8740
8741            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8742                    new GrantUri(userId, uri, false));
8743            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8744                    new GrantUri(userId, uri, true));
8745
8746            final boolean exactValid = (exactPerm != null)
8747                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8748            final boolean prefixValid = (prefixPerm != null)
8749                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8750
8751            if (!(exactValid || prefixValid)) {
8752                throw new SecurityException("No persistable permission grants found for UID "
8753                        + callingUid + " and Uri " + grantUri.toSafeString());
8754            }
8755
8756            if (exactValid) {
8757                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8758            }
8759            if (prefixValid) {
8760                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8761            }
8762
8763            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8764
8765            if (persistChanged) {
8766                schedulePersistUriGrants();
8767            }
8768        }
8769    }
8770
8771    /**
8772     * @param uri This uri must NOT contain an embedded userId.
8773     * @param userId The userId in which the uri is to be resolved.
8774     */
8775    @Override
8776    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8777        enforceNotIsolatedCaller("releasePersistableUriPermission");
8778
8779        Preconditions.checkFlagsArgument(modeFlags,
8780                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8781
8782        synchronized (this) {
8783            final int callingUid = Binder.getCallingUid();
8784            boolean persistChanged = false;
8785
8786            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8787                    new GrantUri(userId, uri, false));
8788            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8789                    new GrantUri(userId, uri, true));
8790            if (exactPerm == null && prefixPerm == null) {
8791                throw new SecurityException("No permission grants found for UID " + callingUid
8792                        + " and Uri " + uri.toSafeString());
8793            }
8794
8795            if (exactPerm != null) {
8796                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8797                removeUriPermissionIfNeededLocked(exactPerm);
8798            }
8799            if (prefixPerm != null) {
8800                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8801                removeUriPermissionIfNeededLocked(prefixPerm);
8802            }
8803
8804            if (persistChanged) {
8805                schedulePersistUriGrants();
8806            }
8807        }
8808    }
8809
8810    /**
8811     * Prune any older {@link UriPermission} for the given UID until outstanding
8812     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8813     *
8814     * @return if any mutations occured that require persisting.
8815     */
8816    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8817        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8818        if (perms == null) return false;
8819        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8820
8821        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8822        for (UriPermission perm : perms.values()) {
8823            if (perm.persistedModeFlags != 0) {
8824                persisted.add(perm);
8825            }
8826        }
8827
8828        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8829        if (trimCount <= 0) return false;
8830
8831        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8832        for (int i = 0; i < trimCount; i++) {
8833            final UriPermission perm = persisted.get(i);
8834
8835            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8836                    "Trimming grant created at " + perm.persistedCreateTime);
8837
8838            perm.releasePersistableModes(~0);
8839            removeUriPermissionIfNeededLocked(perm);
8840        }
8841
8842        return true;
8843    }
8844
8845    @Override
8846    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8847            String packageName, boolean incoming) {
8848        enforceNotIsolatedCaller("getPersistedUriPermissions");
8849        Preconditions.checkNotNull(packageName, "packageName");
8850
8851        final int callingUid = Binder.getCallingUid();
8852        final int callingUserId = UserHandle.getUserId(callingUid);
8853        final IPackageManager pm = AppGlobals.getPackageManager();
8854        try {
8855            final int packageUid = pm.getPackageUid(packageName,
8856                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8857            if (packageUid != callingUid) {
8858                throw new SecurityException(
8859                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8860            }
8861        } catch (RemoteException e) {
8862            throw new SecurityException("Failed to verify package name ownership");
8863        }
8864
8865        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8866        synchronized (this) {
8867            if (incoming) {
8868                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8869                        callingUid);
8870                if (perms == null) {
8871                    Slog.w(TAG, "No permission grants found for " + packageName);
8872                } else {
8873                    for (UriPermission perm : perms.values()) {
8874                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8875                            result.add(perm.buildPersistedPublicApiObject());
8876                        }
8877                    }
8878                }
8879            } else {
8880                final int size = mGrantedUriPermissions.size();
8881                for (int i = 0; i < size; i++) {
8882                    final ArrayMap<GrantUri, UriPermission> perms =
8883                            mGrantedUriPermissions.valueAt(i);
8884                    for (UriPermission perm : perms.values()) {
8885                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8886                            result.add(perm.buildPersistedPublicApiObject());
8887                        }
8888                    }
8889                }
8890            }
8891        }
8892        return new ParceledListSlice<android.content.UriPermission>(result);
8893    }
8894
8895    @Override
8896    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8897            String packageName, int userId) {
8898        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8899                "getGrantedUriPermissions");
8900
8901        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8902        synchronized (this) {
8903            final int size = mGrantedUriPermissions.size();
8904            for (int i = 0; i < size; i++) {
8905                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8906                for (UriPermission perm : perms.values()) {
8907                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8908                            && perm.persistedModeFlags != 0) {
8909                        result.add(perm.buildPersistedPublicApiObject());
8910                    }
8911                }
8912            }
8913        }
8914        return new ParceledListSlice<android.content.UriPermission>(result);
8915    }
8916
8917    @Override
8918    public void clearGrantedUriPermissions(String packageName, int userId) {
8919        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8920                "clearGrantedUriPermissions");
8921        removeUriPermissionsForPackageLocked(packageName, userId, true);
8922    }
8923
8924    @Override
8925    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8926        synchronized (this) {
8927            ProcessRecord app =
8928                who != null ? getRecordForAppLocked(who) : null;
8929            if (app == null) return;
8930
8931            Message msg = Message.obtain();
8932            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8933            msg.obj = app;
8934            msg.arg1 = waiting ? 1 : 0;
8935            mUiHandler.sendMessage(msg);
8936        }
8937    }
8938
8939    @Override
8940    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8941        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8942        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8943        outInfo.availMem = Process.getFreeMemory();
8944        outInfo.totalMem = Process.getTotalMemory();
8945        outInfo.threshold = homeAppMem;
8946        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8947        outInfo.hiddenAppThreshold = cachedAppMem;
8948        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8949                ProcessList.SERVICE_ADJ);
8950        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8951                ProcessList.VISIBLE_APP_ADJ);
8952        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8953                ProcessList.FOREGROUND_APP_ADJ);
8954    }
8955
8956    // =========================================================
8957    // TASK MANAGEMENT
8958    // =========================================================
8959
8960    @Override
8961    public List<IAppTask> getAppTasks(String callingPackage) {
8962        int callingUid = Binder.getCallingUid();
8963        long ident = Binder.clearCallingIdentity();
8964
8965        synchronized(this) {
8966            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8967            try {
8968                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8969
8970                final int N = mRecentTasks.size();
8971                for (int i = 0; i < N; i++) {
8972                    TaskRecord tr = mRecentTasks.get(i);
8973                    // Skip tasks that do not match the caller.  We don't need to verify
8974                    // callingPackage, because we are also limiting to callingUid and know
8975                    // that will limit to the correct security sandbox.
8976                    if (tr.effectiveUid != callingUid) {
8977                        continue;
8978                    }
8979                    Intent intent = tr.getBaseIntent();
8980                    if (intent == null ||
8981                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8982                        continue;
8983                    }
8984                    ActivityManager.RecentTaskInfo taskInfo =
8985                            createRecentTaskInfoFromTaskRecord(tr);
8986                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8987                    list.add(taskImpl);
8988                }
8989            } finally {
8990                Binder.restoreCallingIdentity(ident);
8991            }
8992            return list;
8993        }
8994    }
8995
8996    @Override
8997    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8998        final int callingUid = Binder.getCallingUid();
8999        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9000
9001        synchronized(this) {
9002            if (DEBUG_ALL) Slog.v(
9003                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9004
9005            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9006                    callingUid);
9007
9008            // TODO: Improve with MRU list from all ActivityStacks.
9009            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9010        }
9011
9012        return list;
9013    }
9014
9015    /**
9016     * Creates a new RecentTaskInfo from a TaskRecord.
9017     */
9018    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9019        // Update the task description to reflect any changes in the task stack
9020        tr.updateTaskDescription();
9021
9022        // Compose the recent task info
9023        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9024        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9025        rti.persistentId = tr.taskId;
9026        rti.baseIntent = new Intent(tr.getBaseIntent());
9027        rti.origActivity = tr.origActivity;
9028        rti.realActivity = tr.realActivity;
9029        rti.description = tr.lastDescription;
9030        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9031        rti.userId = tr.userId;
9032        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9033        rti.firstActiveTime = tr.firstActiveTime;
9034        rti.lastActiveTime = tr.lastActiveTime;
9035        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9036        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9037        rti.numActivities = 0;
9038        if (tr.mBounds != null) {
9039            rti.bounds = new Rect(tr.mBounds);
9040        }
9041        rti.isDockable = tr.canGoInDockedStack();
9042        rti.resizeMode = tr.mResizeMode;
9043
9044        ActivityRecord base = null;
9045        ActivityRecord top = null;
9046        ActivityRecord tmp;
9047
9048        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9049            tmp = tr.mActivities.get(i);
9050            if (tmp.finishing) {
9051                continue;
9052            }
9053            base = tmp;
9054            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9055                top = base;
9056            }
9057            rti.numActivities++;
9058        }
9059
9060        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9061        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9062
9063        return rti;
9064    }
9065
9066    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9067        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9068                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9069        if (!allowed) {
9070            if (checkPermission(android.Manifest.permission.GET_TASKS,
9071                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9072                // Temporary compatibility: some existing apps on the system image may
9073                // still be requesting the old permission and not switched to the new
9074                // one; if so, we'll still allow them full access.  This means we need
9075                // to see if they are holding the old permission and are a system app.
9076                try {
9077                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9078                        allowed = true;
9079                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9080                                + " is using old GET_TASKS but privileged; allowing");
9081                    }
9082                } catch (RemoteException e) {
9083                }
9084            }
9085        }
9086        if (!allowed) {
9087            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9088                    + " does not hold REAL_GET_TASKS; limiting output");
9089        }
9090        return allowed;
9091    }
9092
9093    @Override
9094    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9095        final int callingUid = Binder.getCallingUid();
9096        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9097                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9098
9099        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9100        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9101        synchronized (this) {
9102            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9103                    callingUid);
9104            final boolean detailed = checkCallingPermission(
9105                    android.Manifest.permission.GET_DETAILED_TASKS)
9106                    == PackageManager.PERMISSION_GRANTED;
9107
9108            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9109                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9110                return Collections.emptyList();
9111            }
9112            mRecentTasks.loadUserRecentsLocked(userId);
9113
9114            final int recentsCount = mRecentTasks.size();
9115            ArrayList<ActivityManager.RecentTaskInfo> res =
9116                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9117
9118            final Set<Integer> includedUsers;
9119            if (includeProfiles) {
9120                includedUsers = mUserController.getProfileIds(userId);
9121            } else {
9122                includedUsers = new HashSet<>();
9123            }
9124            includedUsers.add(Integer.valueOf(userId));
9125
9126            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9127                TaskRecord tr = mRecentTasks.get(i);
9128                // Only add calling user or related users recent tasks
9129                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9130                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9131                    continue;
9132                }
9133
9134                if (tr.realActivitySuspended) {
9135                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9136                    continue;
9137                }
9138
9139                // Return the entry if desired by the caller.  We always return
9140                // the first entry, because callers always expect this to be the
9141                // foreground app.  We may filter others if the caller has
9142                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9143                // we should exclude the entry.
9144
9145                if (i == 0
9146                        || withExcluded
9147                        || (tr.intent == null)
9148                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9149                                == 0)) {
9150                    if (!allowed) {
9151                        // If the caller doesn't have the GET_TASKS permission, then only
9152                        // allow them to see a small subset of tasks -- their own and home.
9153                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9154                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9155                            continue;
9156                        }
9157                    }
9158                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9159                        if (tr.stack != null && tr.stack.isHomeStack()) {
9160                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9161                                    "Skipping, home stack task: " + tr);
9162                            continue;
9163                        }
9164                    }
9165                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9166                        final ActivityStack stack = tr.stack;
9167                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9168                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9169                                    "Skipping, top task in docked stack: " + tr);
9170                            continue;
9171                        }
9172                    }
9173                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9174                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9175                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9176                                    "Skipping, pinned stack task: " + tr);
9177                            continue;
9178                        }
9179                    }
9180                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9181                        // Don't include auto remove tasks that are finished or finishing.
9182                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9183                                "Skipping, auto-remove without activity: " + tr);
9184                        continue;
9185                    }
9186                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9187                            && !tr.isAvailable) {
9188                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189                                "Skipping, unavail real act: " + tr);
9190                        continue;
9191                    }
9192
9193                    if (!tr.mUserSetupComplete) {
9194                        // Don't include task launched while user is not done setting-up.
9195                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9196                                "Skipping, user setup not complete: " + tr);
9197                        continue;
9198                    }
9199
9200                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9201                    if (!detailed) {
9202                        rti.baseIntent.replaceExtras((Bundle)null);
9203                    }
9204
9205                    res.add(rti);
9206                    maxNum--;
9207                }
9208            }
9209            return res;
9210        }
9211    }
9212
9213    @Override
9214    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9215        synchronized (this) {
9216            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9217                    "getTaskThumbnail()");
9218            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9219                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9220            if (tr != null) {
9221                return tr.getTaskThumbnailLocked();
9222            }
9223        }
9224        return null;
9225    }
9226
9227    @Override
9228    public int addAppTask(IBinder activityToken, Intent intent,
9229            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9230        final int callingUid = Binder.getCallingUid();
9231        final long callingIdent = Binder.clearCallingIdentity();
9232
9233        try {
9234            synchronized (this) {
9235                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9236                if (r == null) {
9237                    throw new IllegalArgumentException("Activity does not exist; token="
9238                            + activityToken);
9239                }
9240                ComponentName comp = intent.getComponent();
9241                if (comp == null) {
9242                    throw new IllegalArgumentException("Intent " + intent
9243                            + " must specify explicit component");
9244                }
9245                if (thumbnail.getWidth() != mThumbnailWidth
9246                        || thumbnail.getHeight() != mThumbnailHeight) {
9247                    throw new IllegalArgumentException("Bad thumbnail size: got "
9248                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9249                            + mThumbnailWidth + "x" + mThumbnailHeight);
9250                }
9251                if (intent.getSelector() != null) {
9252                    intent.setSelector(null);
9253                }
9254                if (intent.getSourceBounds() != null) {
9255                    intent.setSourceBounds(null);
9256                }
9257                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9258                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9259                        // The caller has added this as an auto-remove task...  that makes no
9260                        // sense, so turn off auto-remove.
9261                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9262                    }
9263                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9264                    // Must be a new task.
9265                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9266                }
9267                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9268                    mLastAddedTaskActivity = null;
9269                }
9270                ActivityInfo ainfo = mLastAddedTaskActivity;
9271                if (ainfo == null) {
9272                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9273                            comp, 0, UserHandle.getUserId(callingUid));
9274                    if (ainfo.applicationInfo.uid != callingUid) {
9275                        throw new SecurityException(
9276                                "Can't add task for another application: target uid="
9277                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9278                    }
9279                }
9280
9281                // Use the full screen as the context for the task thumbnail
9282                final Point displaySize = new Point();
9283                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9284                r.task.stack.getDisplaySize(displaySize);
9285                thumbnailInfo.taskWidth = displaySize.x;
9286                thumbnailInfo.taskHeight = displaySize.y;
9287                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9288
9289                TaskRecord task = new TaskRecord(this,
9290                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9291                        ainfo, intent, description, thumbnailInfo);
9292
9293                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9294                if (trimIdx >= 0) {
9295                    // If this would have caused a trim, then we'll abort because that
9296                    // means it would be added at the end of the list but then just removed.
9297                    return INVALID_TASK_ID;
9298                }
9299
9300                final int N = mRecentTasks.size();
9301                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9302                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9303                    tr.removedFromRecents();
9304                }
9305
9306                task.inRecents = true;
9307                mRecentTasks.add(task);
9308                r.task.stack.addTask(task, false, "addAppTask");
9309
9310                task.setLastThumbnailLocked(thumbnail);
9311                task.freeLastThumbnail();
9312
9313                return task.taskId;
9314            }
9315        } finally {
9316            Binder.restoreCallingIdentity(callingIdent);
9317        }
9318    }
9319
9320    @Override
9321    public Point getAppTaskThumbnailSize() {
9322        synchronized (this) {
9323            return new Point(mThumbnailWidth,  mThumbnailHeight);
9324        }
9325    }
9326
9327    @Override
9328    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9329        synchronized (this) {
9330            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9331            if (r != null) {
9332                r.setTaskDescription(td);
9333                r.task.updateTaskDescription();
9334            }
9335        }
9336    }
9337
9338    @Override
9339    public void setTaskResizeable(int taskId, int resizeableMode) {
9340        synchronized (this) {
9341            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9342                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9343            if (task == null) {
9344                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9345                return;
9346            }
9347            if (task.mResizeMode != resizeableMode) {
9348                task.mResizeMode = resizeableMode;
9349                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9350                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9351                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9352            }
9353        }
9354    }
9355
9356    @Override
9357    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9358        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9359        long ident = Binder.clearCallingIdentity();
9360        try {
9361            synchronized (this) {
9362                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9363                if (task == null) {
9364                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9365                    return;
9366                }
9367                int stackId = task.stack.mStackId;
9368                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9369                // in crop windows resize mode or if the task size is affected by the docked stack
9370                // changing size. No need to update configuration.
9371                if (bounds != null && task.inCropWindowsResizeMode()
9372                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9373                    mWindowManager.scrollTask(task.taskId, bounds);
9374                    return;
9375                }
9376
9377                // Place the task in the right stack if it isn't there already based on
9378                // the requested bounds.
9379                // The stack transition logic is:
9380                // - a null bounds on a freeform task moves that task to fullscreen
9381                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9382                //   that task to freeform
9383                // - otherwise the task is not moved
9384                if (!StackId.isTaskResizeAllowed(stackId)) {
9385                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9386                }
9387                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9388                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9389                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9390                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9391                }
9392                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9393                if (stackId != task.stack.mStackId) {
9394                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9395                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9396                    preserveWindow = false;
9397                }
9398
9399                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9400                        false /* deferResume */);
9401            }
9402        } finally {
9403            Binder.restoreCallingIdentity(ident);
9404        }
9405    }
9406
9407    @Override
9408    public Rect getTaskBounds(int taskId) {
9409        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9410        long ident = Binder.clearCallingIdentity();
9411        Rect rect = new Rect();
9412        try {
9413            synchronized (this) {
9414                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9415                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9416                if (task == null) {
9417                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9418                    return rect;
9419                }
9420                if (task.stack != null) {
9421                    // Return the bounds from window manager since it will be adjusted for various
9422                    // things like the presense of a docked stack for tasks that aren't resizeable.
9423                    mWindowManager.getTaskBounds(task.taskId, rect);
9424                } else {
9425                    // Task isn't in window manager yet since it isn't associated with a stack.
9426                    // Return the persist value from activity manager
9427                    if (task.mBounds != null) {
9428                        rect.set(task.mBounds);
9429                    } else if (task.mLastNonFullscreenBounds != null) {
9430                        rect.set(task.mLastNonFullscreenBounds);
9431                    }
9432                }
9433            }
9434        } finally {
9435            Binder.restoreCallingIdentity(ident);
9436        }
9437        return rect;
9438    }
9439
9440    @Override
9441    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9442        if (userId != UserHandle.getCallingUserId()) {
9443            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9444                    "getTaskDescriptionIcon");
9445        }
9446        final File passedIconFile = new File(filePath);
9447        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9448                passedIconFile.getName());
9449        if (!legitIconFile.getPath().equals(filePath)
9450                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9451            throw new IllegalArgumentException("Bad file path: " + filePath
9452                    + " passed for userId " + userId);
9453        }
9454        return mRecentTasks.getTaskDescriptionIcon(filePath);
9455    }
9456
9457    @Override
9458    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9459            throws RemoteException {
9460        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9461                opts.getCustomInPlaceResId() == 0) {
9462            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9463                    "with valid animation");
9464        }
9465        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9466        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9467                opts.getCustomInPlaceResId());
9468        mWindowManager.executeAppTransition();
9469    }
9470
9471    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9472            boolean removeFromRecents) {
9473        if (removeFromRecents) {
9474            mRecentTasks.remove(tr);
9475            tr.removedFromRecents();
9476        }
9477        ComponentName component = tr.getBaseIntent().getComponent();
9478        if (component == null) {
9479            Slog.w(TAG, "No component for base intent of task: " + tr);
9480            return;
9481        }
9482
9483        // Find any running services associated with this app and stop if needed.
9484        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9485
9486        if (!killProcess) {
9487            return;
9488        }
9489
9490        // Determine if the process(es) for this task should be killed.
9491        final String pkg = component.getPackageName();
9492        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9493        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9494        for (int i = 0; i < pmap.size(); i++) {
9495
9496            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9497            for (int j = 0; j < uids.size(); j++) {
9498                ProcessRecord proc = uids.valueAt(j);
9499                if (proc.userId != tr.userId) {
9500                    // Don't kill process for a different user.
9501                    continue;
9502                }
9503                if (proc == mHomeProcess) {
9504                    // Don't kill the home process along with tasks from the same package.
9505                    continue;
9506                }
9507                if (!proc.pkgList.containsKey(pkg)) {
9508                    // Don't kill process that is not associated with this task.
9509                    continue;
9510                }
9511
9512                for (int k = 0; k < proc.activities.size(); k++) {
9513                    TaskRecord otherTask = proc.activities.get(k).task;
9514                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9515                        // Don't kill process(es) that has an activity in a different task that is
9516                        // also in recents.
9517                        return;
9518                    }
9519                }
9520
9521                if (proc.foregroundServices) {
9522                    // Don't kill process(es) with foreground service.
9523                    return;
9524                }
9525
9526                // Add process to kill list.
9527                procsToKill.add(proc);
9528            }
9529        }
9530
9531        // Kill the running processes.
9532        for (int i = 0; i < procsToKill.size(); i++) {
9533            ProcessRecord pr = procsToKill.get(i);
9534            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9535                    && pr.curReceivers.isEmpty()) {
9536                pr.kill("remove task", true);
9537            } else {
9538                // We delay killing processes that are not in the background or running a receiver.
9539                pr.waitingToKill = "remove task";
9540            }
9541        }
9542    }
9543
9544    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9545        // Remove all tasks with activities in the specified package from the list of recent tasks
9546        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9547            TaskRecord tr = mRecentTasks.get(i);
9548            if (tr.userId != userId) continue;
9549
9550            ComponentName cn = tr.intent.getComponent();
9551            if (cn != null && cn.getPackageName().equals(packageName)) {
9552                // If the package name matches, remove the task.
9553                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9554            }
9555        }
9556    }
9557
9558    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9559            int userId) {
9560
9561        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9562            TaskRecord tr = mRecentTasks.get(i);
9563            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9564                continue;
9565            }
9566
9567            ComponentName cn = tr.intent.getComponent();
9568            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9569                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9570            if (sameComponent) {
9571                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9572            }
9573        }
9574    }
9575
9576    /**
9577     * Removes the task with the specified task id.
9578     *
9579     * @param taskId Identifier of the task to be removed.
9580     * @param killProcess Kill any process associated with the task if possible.
9581     * @param removeFromRecents Whether to also remove the task from recents.
9582     * @return Returns true if the given task was found and removed.
9583     */
9584    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9585            boolean removeFromRecents) {
9586        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9587                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9588        if (tr != null) {
9589            tr.removeTaskActivitiesLocked();
9590            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9591            if (tr.isPersistable) {
9592                notifyTaskPersisterLocked(null, true);
9593            }
9594            return true;
9595        }
9596        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9597        return false;
9598    }
9599
9600    @Override
9601    public void removeStack(int stackId) {
9602        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9603        if (stackId == HOME_STACK_ID) {
9604            throw new IllegalArgumentException("Removing home stack is not allowed.");
9605        }
9606
9607        synchronized (this) {
9608            final long ident = Binder.clearCallingIdentity();
9609            try {
9610                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9611                if (stack == null) {
9612                    return;
9613                }
9614                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9615                for (int i = tasks.size() - 1; i >= 0; i--) {
9616                    removeTaskByIdLocked(
9617                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9618                }
9619            } finally {
9620                Binder.restoreCallingIdentity(ident);
9621            }
9622        }
9623    }
9624
9625    @Override
9626    public boolean removeTask(int taskId) {
9627        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9628        synchronized (this) {
9629            final long ident = Binder.clearCallingIdentity();
9630            try {
9631                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9632            } finally {
9633                Binder.restoreCallingIdentity(ident);
9634            }
9635        }
9636    }
9637
9638    /**
9639     * TODO: Add mController hook
9640     */
9641    @Override
9642    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9643        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9644
9645        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9646        synchronized(this) {
9647            moveTaskToFrontLocked(taskId, flags, bOptions);
9648        }
9649    }
9650
9651    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9652        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9653
9654        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9655                Binder.getCallingUid(), -1, -1, "Task to front")) {
9656            ActivityOptions.abort(options);
9657            return;
9658        }
9659        final long origId = Binder.clearCallingIdentity();
9660        try {
9661            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9662            if (task == null) {
9663                Slog.d(TAG, "Could not find task for id: "+ taskId);
9664                return;
9665            }
9666            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9667                mStackSupervisor.showLockTaskToast();
9668                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9669                return;
9670            }
9671            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9672            if (prev != null && prev.isRecentsActivity()) {
9673                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9674            }
9675            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9676                    false /* forceNonResizable */);
9677        } finally {
9678            Binder.restoreCallingIdentity(origId);
9679        }
9680        ActivityOptions.abort(options);
9681    }
9682
9683    /**
9684     * Moves an activity, and all of the other activities within the same task, to the bottom
9685     * of the history stack.  The activity's order within the task is unchanged.
9686     *
9687     * @param token A reference to the activity we wish to move
9688     * @param nonRoot If false then this only works if the activity is the root
9689     *                of a task; if true it will work for any activity in a task.
9690     * @return Returns true if the move completed, false if not.
9691     */
9692    @Override
9693    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9694        enforceNotIsolatedCaller("moveActivityTaskToBack");
9695        synchronized(this) {
9696            final long origId = Binder.clearCallingIdentity();
9697            try {
9698                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9699                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9700                if (task != null) {
9701                    if (mStackSupervisor.isLockedTask(task)) {
9702                        mStackSupervisor.showLockTaskToast();
9703                        return false;
9704                    }
9705                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9706                }
9707            } finally {
9708                Binder.restoreCallingIdentity(origId);
9709            }
9710        }
9711        return false;
9712    }
9713
9714    @Override
9715    public void moveTaskBackwards(int task) {
9716        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9717                "moveTaskBackwards()");
9718
9719        synchronized(this) {
9720            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9721                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9722                return;
9723            }
9724            final long origId = Binder.clearCallingIdentity();
9725            moveTaskBackwardsLocked(task);
9726            Binder.restoreCallingIdentity(origId);
9727        }
9728    }
9729
9730    private final void moveTaskBackwardsLocked(int task) {
9731        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9732    }
9733
9734    @Override
9735    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9736            IActivityContainerCallback callback) throws RemoteException {
9737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9738        synchronized (this) {
9739            if (parentActivityToken == null) {
9740                throw new IllegalArgumentException("parent token must not be null");
9741            }
9742            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9743            if (r == null) {
9744                return null;
9745            }
9746            if (callback == null) {
9747                throw new IllegalArgumentException("callback must not be null");
9748            }
9749            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9750        }
9751    }
9752
9753    @Override
9754    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9755        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9756        synchronized (this) {
9757            mStackSupervisor.deleteActivityContainer(container);
9758        }
9759    }
9760
9761    @Override
9762    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9764        synchronized (this) {
9765            final int stackId = mStackSupervisor.getNextStackId();
9766            final ActivityStack stack =
9767                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9768            if (stack == null) {
9769                return null;
9770            }
9771            return stack.mActivityContainer;
9772        }
9773    }
9774
9775    @Override
9776    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9777        synchronized (this) {
9778            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9779            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9780                return stack.mActivityContainer.getDisplayId();
9781            }
9782            return Display.DEFAULT_DISPLAY;
9783        }
9784    }
9785
9786    @Override
9787    public int getActivityStackId(IBinder token) throws RemoteException {
9788        synchronized (this) {
9789            ActivityStack stack = ActivityRecord.getStackLocked(token);
9790            if (stack == null) {
9791                return INVALID_STACK_ID;
9792            }
9793            return stack.mStackId;
9794        }
9795    }
9796
9797    @Override
9798    public void exitFreeformMode(IBinder token) throws RemoteException {
9799        synchronized (this) {
9800            long ident = Binder.clearCallingIdentity();
9801            try {
9802                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9803                if (r == null) {
9804                    throw new IllegalArgumentException(
9805                            "exitFreeformMode: No activity record matching token=" + token);
9806                }
9807                final ActivityStack stack = r.getStackLocked(token);
9808                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9809                    throw new IllegalStateException(
9810                            "exitFreeformMode: You can only go fullscreen from freeform.");
9811                }
9812                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9813                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9814                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9815            } finally {
9816                Binder.restoreCallingIdentity(ident);
9817            }
9818        }
9819    }
9820
9821    @Override
9822    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9823        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9824        if (stackId == HOME_STACK_ID) {
9825            throw new IllegalArgumentException(
9826                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9827        }
9828        synchronized (this) {
9829            long ident = Binder.clearCallingIdentity();
9830            try {
9831                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9832                        + " to stackId=" + stackId + " toTop=" + toTop);
9833                if (stackId == DOCKED_STACK_ID) {
9834                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9835                            null /* initialBounds */);
9836                }
9837                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9838                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9839                if (result && stackId == DOCKED_STACK_ID) {
9840                    // If task moved to docked stack - show recents if needed.
9841                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9842                            "moveTaskToDockedStack");
9843                }
9844            } finally {
9845                Binder.restoreCallingIdentity(ident);
9846            }
9847        }
9848    }
9849
9850    @Override
9851    public void swapDockedAndFullscreenStack() throws RemoteException {
9852        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9853        synchronized (this) {
9854            long ident = Binder.clearCallingIdentity();
9855            try {
9856                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9857                        FULLSCREEN_WORKSPACE_STACK_ID);
9858                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9859                        : null;
9860                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9861                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9862                        : null;
9863                if (topTask == null || tasks == null || tasks.size() == 0) {
9864                    Slog.w(TAG,
9865                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9866                    return;
9867                }
9868
9869                // TODO: App transition
9870                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9871
9872                // Defer the resume so resume/pausing while moving stacks is dangerous.
9873                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9874                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9875                        ANIMATE, true /* deferResume */);
9876                final int size = tasks.size();
9877                for (int i = 0; i < size; i++) {
9878                    final int id = tasks.get(i).taskId;
9879                    if (id == topTask.taskId) {
9880                        continue;
9881                    }
9882                    mStackSupervisor.moveTaskToStackLocked(id,
9883                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9884                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9885                }
9886
9887                // Because we deferred the resume, to avoid conflicts with stack switches while
9888                // resuming, we need to do it after all the tasks are moved.
9889                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9890                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9891
9892                mWindowManager.executeAppTransition();
9893            } finally {
9894                Binder.restoreCallingIdentity(ident);
9895            }
9896        }
9897    }
9898
9899    /**
9900     * Moves the input task to the docked stack.
9901     *
9902     * @param taskId Id of task to move.
9903     * @param createMode The mode the docked stack should be created in if it doesn't exist
9904     *                   already. See
9905     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9906     *                   and
9907     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9908     * @param toTop If the task and stack should be moved to the top.
9909     * @param animate Whether we should play an animation for the moving the task
9910     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9911     *                      docked stack. Pass {@code null} to use default bounds.
9912     */
9913    @Override
9914    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9915            Rect initialBounds, boolean moveHomeStackFront) {
9916        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9917        synchronized (this) {
9918            long ident = Binder.clearCallingIdentity();
9919            try {
9920                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9921                        + " to createMode=" + createMode + " toTop=" + toTop);
9922                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9923                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9924                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9925                        animate, DEFER_RESUME);
9926                if (moved) {
9927                    if (moveHomeStackFront) {
9928                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9929                    }
9930                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9931                }
9932                return moved;
9933            } finally {
9934                Binder.restoreCallingIdentity(ident);
9935            }
9936        }
9937    }
9938
9939    /**
9940     * Moves the top activity in the input stackId to the pinned stack.
9941     *
9942     * @param stackId Id of stack to move the top activity to pinned stack.
9943     * @param bounds Bounds to use for pinned stack.
9944     *
9945     * @return True if the top activity of the input stack was successfully moved to the pinned
9946     *          stack.
9947     */
9948    @Override
9949    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9950        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9951        synchronized (this) {
9952            if (!mSupportsPictureInPicture) {
9953                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9954                        + "Device doesn't support picture-in-pciture mode");
9955            }
9956
9957            long ident = Binder.clearCallingIdentity();
9958            try {
9959                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9960            } finally {
9961                Binder.restoreCallingIdentity(ident);
9962            }
9963        }
9964    }
9965
9966    @Override
9967    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9968            boolean preserveWindows, boolean animate, int animationDuration) {
9969        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9970        long ident = Binder.clearCallingIdentity();
9971        try {
9972            synchronized (this) {
9973                if (animate) {
9974                    if (stackId == PINNED_STACK_ID) {
9975                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9976                    } else {
9977                        throw new IllegalArgumentException("Stack: " + stackId
9978                                + " doesn't support animated resize.");
9979                    }
9980                } else {
9981                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9982                            null /* tempTaskInsetBounds */, preserveWindows,
9983                            allowResizeInDockedMode, !DEFER_RESUME);
9984                }
9985            }
9986        } finally {
9987            Binder.restoreCallingIdentity(ident);
9988        }
9989    }
9990
9991    @Override
9992    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9993            Rect tempDockedTaskInsetBounds,
9994            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9995        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9996                "resizeDockedStack()");
9997        long ident = Binder.clearCallingIdentity();
9998        try {
9999            synchronized (this) {
10000                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10001                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10002                        PRESERVE_WINDOWS);
10003            }
10004        } finally {
10005            Binder.restoreCallingIdentity(ident);
10006        }
10007    }
10008
10009    @Override
10010    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10011        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10012                "resizePinnedStack()");
10013        final long ident = Binder.clearCallingIdentity();
10014        try {
10015            synchronized (this) {
10016                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10017            }
10018        } finally {
10019            Binder.restoreCallingIdentity(ident);
10020        }
10021    }
10022
10023    @Override
10024    public void positionTaskInStack(int taskId, int stackId, int position) {
10025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10026        if (stackId == HOME_STACK_ID) {
10027            throw new IllegalArgumentException(
10028                    "positionTaskInStack: Attempt to change the position of task "
10029                    + taskId + " in/to home stack");
10030        }
10031        synchronized (this) {
10032            long ident = Binder.clearCallingIdentity();
10033            try {
10034                if (DEBUG_STACK) Slog.d(TAG_STACK,
10035                        "positionTaskInStack: positioning task=" + taskId
10036                        + " in stackId=" + stackId + " at position=" + position);
10037                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10038            } finally {
10039                Binder.restoreCallingIdentity(ident);
10040            }
10041        }
10042    }
10043
10044    @Override
10045    public List<StackInfo> getAllStackInfos() {
10046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10047        long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                return mStackSupervisor.getAllStackInfosLocked();
10051            }
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public StackInfo getStackInfo(int stackId) {
10059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10060        long ident = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                return mStackSupervisor.getStackInfoLocked(stackId);
10064            }
10065        } finally {
10066            Binder.restoreCallingIdentity(ident);
10067        }
10068    }
10069
10070    @Override
10071    public boolean isInHomeStack(int taskId) {
10072        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10073        long ident = Binder.clearCallingIdentity();
10074        try {
10075            synchronized (this) {
10076                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10077                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10078                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10079            }
10080        } finally {
10081            Binder.restoreCallingIdentity(ident);
10082        }
10083    }
10084
10085    @Override
10086    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10087        synchronized(this) {
10088            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10089        }
10090    }
10091
10092    @Override
10093    public void updateDeviceOwner(String packageName) {
10094        final int callingUid = Binder.getCallingUid();
10095        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10096            throw new SecurityException("updateDeviceOwner called from non-system process");
10097        }
10098        synchronized (this) {
10099            mDeviceOwnerName = packageName;
10100        }
10101    }
10102
10103    @Override
10104    public void updateLockTaskPackages(int userId, String[] packages) {
10105        final int callingUid = Binder.getCallingUid();
10106        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10107            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10108                    "updateLockTaskPackages()");
10109        }
10110        synchronized (this) {
10111            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10112                    Arrays.toString(packages));
10113            mLockTaskPackages.put(userId, packages);
10114            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10115        }
10116    }
10117
10118
10119    void startLockTaskModeLocked(TaskRecord task) {
10120        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10121        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10122            return;
10123        }
10124
10125        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10126        // is initiated by system after the pinning request was shown and locked mode is initiated
10127        // by an authorized app directly
10128        final int callingUid = Binder.getCallingUid();
10129        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10130        long ident = Binder.clearCallingIdentity();
10131        try {
10132            if (!isSystemInitiated) {
10133                task.mLockTaskUid = callingUid;
10134                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10135                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10136                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10137                    StatusBarManagerInternal statusBarManager =
10138                            LocalServices.getService(StatusBarManagerInternal.class);
10139                    if (statusBarManager != null) {
10140                        statusBarManager.showScreenPinningRequest(task.taskId);
10141                    }
10142                    return;
10143                }
10144
10145                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10146                if (stack == null || task != stack.topTask()) {
10147                    throw new IllegalArgumentException("Invalid task, not in foreground");
10148                }
10149            }
10150            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10151                    "Locking fully");
10152            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10153                    ActivityManager.LOCK_TASK_MODE_PINNED :
10154                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10155                    "startLockTask", true);
10156        } finally {
10157            Binder.restoreCallingIdentity(ident);
10158        }
10159    }
10160
10161    @Override
10162    public void startLockTaskMode(int taskId) {
10163        synchronized (this) {
10164            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10165            if (task != null) {
10166                startLockTaskModeLocked(task);
10167            }
10168        }
10169    }
10170
10171    @Override
10172    public void startLockTaskMode(IBinder token) {
10173        synchronized (this) {
10174            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10175            if (r == null) {
10176                return;
10177            }
10178            final TaskRecord task = r.task;
10179            if (task != null) {
10180                startLockTaskModeLocked(task);
10181            }
10182        }
10183    }
10184
10185    @Override
10186    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10187        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10188        // This makes inner call to look as if it was initiated by system.
10189        long ident = Binder.clearCallingIdentity();
10190        try {
10191            synchronized (this) {
10192                startLockTaskMode(taskId);
10193            }
10194        } finally {
10195            Binder.restoreCallingIdentity(ident);
10196        }
10197    }
10198
10199    @Override
10200    public void stopLockTaskMode() {
10201        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10202        if (lockTask == null) {
10203            // Our work here is done.
10204            return;
10205        }
10206
10207        final int callingUid = Binder.getCallingUid();
10208        final int lockTaskUid = lockTask.mLockTaskUid;
10209        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10210        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10211            // Done.
10212            return;
10213        } else {
10214            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10215            // It is possible lockTaskMode was started by the system process because
10216            // android:lockTaskMode is set to a locking value in the application manifest
10217            // instead of the app calling startLockTaskMode. In this case
10218            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10219            // {@link TaskRecord.effectiveUid} instead. Also caller with
10220            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10221            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10222                    && callingUid != lockTaskUid
10223                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10224                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10225                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10226            }
10227        }
10228        long ident = Binder.clearCallingIdentity();
10229        try {
10230            Log.d(TAG, "stopLockTaskMode");
10231            // Stop lock task
10232            synchronized (this) {
10233                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10234                        "stopLockTask", true);
10235            }
10236            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10237            if (tm != null) {
10238                tm.showInCallScreen(false);
10239            }
10240        } finally {
10241            Binder.restoreCallingIdentity(ident);
10242        }
10243    }
10244
10245    /**
10246     * This API should be called by SystemUI only when user perform certain action to dismiss
10247     * lock task mode. We should only dismiss pinned lock task mode in this case.
10248     */
10249    @Override
10250    public void stopSystemLockTaskMode() throws RemoteException {
10251        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10252            stopLockTaskMode();
10253        } else {
10254            mStackSupervisor.showLockTaskToast();
10255        }
10256    }
10257
10258    @Override
10259    public boolean isInLockTaskMode() {
10260        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10261    }
10262
10263    @Override
10264    public int getLockTaskModeState() {
10265        synchronized (this) {
10266            return mStackSupervisor.getLockTaskModeState();
10267        }
10268    }
10269
10270    @Override
10271    public void showLockTaskEscapeMessage(IBinder token) {
10272        synchronized (this) {
10273            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10274            if (r == null) {
10275                return;
10276            }
10277            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10278        }
10279    }
10280
10281    // =========================================================
10282    // CONTENT PROVIDERS
10283    // =========================================================
10284
10285    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10286        List<ProviderInfo> providers = null;
10287        try {
10288            providers = AppGlobals.getPackageManager()
10289                    .queryContentProviders(app.processName, app.uid,
10290                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10291                                    | MATCH_DEBUG_TRIAGED_MISSING)
10292                    .getList();
10293        } catch (RemoteException ex) {
10294        }
10295        if (DEBUG_MU) Slog.v(TAG_MU,
10296                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10297        int userId = app.userId;
10298        if (providers != null) {
10299            int N = providers.size();
10300            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10301            for (int i=0; i<N; i++) {
10302                // TODO: keep logic in sync with installEncryptionUnawareProviders
10303                ProviderInfo cpi =
10304                    (ProviderInfo)providers.get(i);
10305                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10306                        cpi.name, cpi.flags);
10307                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10308                    // This is a singleton provider, but a user besides the
10309                    // default user is asking to initialize a process it runs
10310                    // in...  well, no, it doesn't actually run in this process,
10311                    // it runs in the process of the default user.  Get rid of it.
10312                    providers.remove(i);
10313                    N--;
10314                    i--;
10315                    continue;
10316                }
10317
10318                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10319                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10320                if (cpr == null) {
10321                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10322                    mProviderMap.putProviderByClass(comp, cpr);
10323                }
10324                if (DEBUG_MU) Slog.v(TAG_MU,
10325                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10326                app.pubProviders.put(cpi.name, cpr);
10327                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10328                    // Don't add this if it is a platform component that is marked
10329                    // to run in multiple processes, because this is actually
10330                    // part of the framework so doesn't make sense to track as a
10331                    // separate apk in the process.
10332                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10333                            mProcessStats);
10334                }
10335                notifyPackageUse(cpi.applicationInfo.packageName,
10336                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10337            }
10338        }
10339        return providers;
10340    }
10341
10342    /**
10343     * Check if {@link ProcessRecord} has a possible chance at accessing the
10344     * given {@link ProviderInfo}. Final permission checking is always done
10345     * in {@link ContentProvider}.
10346     */
10347    private final String checkContentProviderPermissionLocked(
10348            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10349        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10350        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10351        boolean checkedGrants = false;
10352        if (checkUser) {
10353            // Looking for cross-user grants before enforcing the typical cross-users permissions
10354            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10355            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10356                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10357                    return null;
10358                }
10359                checkedGrants = true;
10360            }
10361            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10362                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10363            if (userId != tmpTargetUserId) {
10364                // When we actually went to determine the final targer user ID, this ended
10365                // up different than our initial check for the authority.  This is because
10366                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10367                // SELF.  So we need to re-check the grants again.
10368                checkedGrants = false;
10369            }
10370        }
10371        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10372                cpi.applicationInfo.uid, cpi.exported)
10373                == PackageManager.PERMISSION_GRANTED) {
10374            return null;
10375        }
10376        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10377                cpi.applicationInfo.uid, cpi.exported)
10378                == PackageManager.PERMISSION_GRANTED) {
10379            return null;
10380        }
10381
10382        PathPermission[] pps = cpi.pathPermissions;
10383        if (pps != null) {
10384            int i = pps.length;
10385            while (i > 0) {
10386                i--;
10387                PathPermission pp = pps[i];
10388                String pprperm = pp.getReadPermission();
10389                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10390                        cpi.applicationInfo.uid, cpi.exported)
10391                        == PackageManager.PERMISSION_GRANTED) {
10392                    return null;
10393                }
10394                String ppwperm = pp.getWritePermission();
10395                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10396                        cpi.applicationInfo.uid, cpi.exported)
10397                        == PackageManager.PERMISSION_GRANTED) {
10398                    return null;
10399                }
10400            }
10401        }
10402        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10403            return null;
10404        }
10405
10406        String msg;
10407        if (!cpi.exported) {
10408            msg = "Permission Denial: opening provider " + cpi.name
10409                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10410                    + ", uid=" + callingUid + ") that is not exported from uid "
10411                    + cpi.applicationInfo.uid;
10412        } else {
10413            msg = "Permission Denial: opening provider " + cpi.name
10414                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10415                    + ", uid=" + callingUid + ") requires "
10416                    + cpi.readPermission + " or " + cpi.writePermission;
10417        }
10418        Slog.w(TAG, msg);
10419        return msg;
10420    }
10421
10422    /**
10423     * Returns if the ContentProvider has granted a uri to callingUid
10424     */
10425    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10426        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10427        if (perms != null) {
10428            for (int i=perms.size()-1; i>=0; i--) {
10429                GrantUri grantUri = perms.keyAt(i);
10430                if (grantUri.sourceUserId == userId || !checkUser) {
10431                    if (matchesProvider(grantUri.uri, cpi)) {
10432                        return true;
10433                    }
10434                }
10435            }
10436        }
10437        return false;
10438    }
10439
10440    /**
10441     * Returns true if the uri authority is one of the authorities specified in the provider.
10442     */
10443    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10444        String uriAuth = uri.getAuthority();
10445        String cpiAuth = cpi.authority;
10446        if (cpiAuth.indexOf(';') == -1) {
10447            return cpiAuth.equals(uriAuth);
10448        }
10449        String[] cpiAuths = cpiAuth.split(";");
10450        int length = cpiAuths.length;
10451        for (int i = 0; i < length; i++) {
10452            if (cpiAuths[i].equals(uriAuth)) return true;
10453        }
10454        return false;
10455    }
10456
10457    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10458            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10459        if (r != null) {
10460            for (int i=0; i<r.conProviders.size(); i++) {
10461                ContentProviderConnection conn = r.conProviders.get(i);
10462                if (conn.provider == cpr) {
10463                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10464                            "Adding provider requested by "
10465                            + r.processName + " from process "
10466                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10467                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10468                    if (stable) {
10469                        conn.stableCount++;
10470                        conn.numStableIncs++;
10471                    } else {
10472                        conn.unstableCount++;
10473                        conn.numUnstableIncs++;
10474                    }
10475                    return conn;
10476                }
10477            }
10478            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10479            if (stable) {
10480                conn.stableCount = 1;
10481                conn.numStableIncs = 1;
10482            } else {
10483                conn.unstableCount = 1;
10484                conn.numUnstableIncs = 1;
10485            }
10486            cpr.connections.add(conn);
10487            r.conProviders.add(conn);
10488            startAssociationLocked(r.uid, r.processName, r.curProcState,
10489                    cpr.uid, cpr.name, cpr.info.processName);
10490            return conn;
10491        }
10492        cpr.addExternalProcessHandleLocked(externalProcessToken);
10493        return null;
10494    }
10495
10496    boolean decProviderCountLocked(ContentProviderConnection conn,
10497            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10498        if (conn != null) {
10499            cpr = conn.provider;
10500            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10501                    "Removing provider requested by "
10502                    + conn.client.processName + " from process "
10503                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10504                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10505            if (stable) {
10506                conn.stableCount--;
10507            } else {
10508                conn.unstableCount--;
10509            }
10510            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10511                cpr.connections.remove(conn);
10512                conn.client.conProviders.remove(conn);
10513                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10514                    // The client is more important than last activity -- note the time this
10515                    // is happening, so we keep the old provider process around a bit as last
10516                    // activity to avoid thrashing it.
10517                    if (cpr.proc != null) {
10518                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10519                    }
10520                }
10521                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10522                return true;
10523            }
10524            return false;
10525        }
10526        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10527        return false;
10528    }
10529
10530    private void checkTime(long startTime, String where) {
10531        long now = SystemClock.uptimeMillis();
10532        if ((now-startTime) > 50) {
10533            // If we are taking more than 50ms, log about it.
10534            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10535        }
10536    }
10537
10538    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10539            PROC_SPACE_TERM,
10540            PROC_SPACE_TERM|PROC_PARENS,
10541            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10542    };
10543
10544    private final long[] mProcessStateStatsLongs = new long[1];
10545
10546    boolean isProcessAliveLocked(ProcessRecord proc) {
10547        if (proc.procStatFile == null) {
10548            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10549        }
10550        mProcessStateStatsLongs[0] = 0;
10551        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10552                mProcessStateStatsLongs, null)) {
10553            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10554            return false;
10555        }
10556        final long state = mProcessStateStatsLongs[0];
10557        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10558                + (char)state);
10559        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10560    }
10561
10562    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10563            String name, IBinder token, boolean stable, int userId) {
10564        ContentProviderRecord cpr;
10565        ContentProviderConnection conn = null;
10566        ProviderInfo cpi = null;
10567
10568        synchronized(this) {
10569            long startTime = SystemClock.uptimeMillis();
10570
10571            ProcessRecord r = null;
10572            if (caller != null) {
10573                r = getRecordForAppLocked(caller);
10574                if (r == null) {
10575                    throw new SecurityException(
10576                            "Unable to find app for caller " + caller
10577                          + " (pid=" + Binder.getCallingPid()
10578                          + ") when getting content provider " + name);
10579                }
10580            }
10581
10582            boolean checkCrossUser = true;
10583
10584            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10585
10586            // First check if this content provider has been published...
10587            cpr = mProviderMap.getProviderByName(name, userId);
10588            // If that didn't work, check if it exists for user 0 and then
10589            // verify that it's a singleton provider before using it.
10590            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10591                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10592                if (cpr != null) {
10593                    cpi = cpr.info;
10594                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10595                            cpi.name, cpi.flags)
10596                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10597                        userId = UserHandle.USER_SYSTEM;
10598                        checkCrossUser = false;
10599                    } else {
10600                        cpr = null;
10601                        cpi = null;
10602                    }
10603                }
10604            }
10605
10606            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10607            if (providerRunning) {
10608                cpi = cpr.info;
10609                String msg;
10610                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10611                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10612                        != null) {
10613                    throw new SecurityException(msg);
10614                }
10615                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10616
10617                if (r != null && cpr.canRunHere(r)) {
10618                    // This provider has been published or is in the process
10619                    // of being published...  but it is also allowed to run
10620                    // in the caller's process, so don't make a connection
10621                    // and just let the caller instantiate its own instance.
10622                    ContentProviderHolder holder = cpr.newHolder(null);
10623                    // don't give caller the provider object, it needs
10624                    // to make its own.
10625                    holder.provider = null;
10626                    return holder;
10627                }
10628
10629                final long origId = Binder.clearCallingIdentity();
10630
10631                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10632
10633                // In this case the provider instance already exists, so we can
10634                // return it right away.
10635                conn = incProviderCountLocked(r, cpr, token, stable);
10636                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10637                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10638                        // If this is a perceptible app accessing the provider,
10639                        // make sure to count it as being accessed and thus
10640                        // back up on the LRU list.  This is good because
10641                        // content providers are often expensive to start.
10642                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10643                        updateLruProcessLocked(cpr.proc, false, null);
10644                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10645                    }
10646                }
10647
10648                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10649                final int verifiedAdj = cpr.proc.verifiedAdj;
10650                boolean success = updateOomAdjLocked(cpr.proc);
10651                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10652                // if the process has been successfully adjusted.  So to reduce races with
10653                // it, we will check whether the process still exists.  Note that this doesn't
10654                // completely get rid of races with LMK killing the process, but should make
10655                // them much smaller.
10656                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10657                    success = false;
10658                }
10659                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10660                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10661                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10662                // NOTE: there is still a race here where a signal could be
10663                // pending on the process even though we managed to update its
10664                // adj level.  Not sure what to do about this, but at least
10665                // the race is now smaller.
10666                if (!success) {
10667                    // Uh oh...  it looks like the provider's process
10668                    // has been killed on us.  We need to wait for a new
10669                    // process to be started, and make sure its death
10670                    // doesn't kill our process.
10671                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10672                            + " is crashing; detaching " + r);
10673                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10674                    checkTime(startTime, "getContentProviderImpl: before appDied");
10675                    appDiedLocked(cpr.proc);
10676                    checkTime(startTime, "getContentProviderImpl: after appDied");
10677                    if (!lastRef) {
10678                        // This wasn't the last ref our process had on
10679                        // the provider...  we have now been killed, bail.
10680                        return null;
10681                    }
10682                    providerRunning = false;
10683                    conn = null;
10684                } else {
10685                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10686                }
10687
10688                Binder.restoreCallingIdentity(origId);
10689            }
10690
10691            if (!providerRunning) {
10692                try {
10693                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10694                    cpi = AppGlobals.getPackageManager().
10695                        resolveContentProvider(name,
10696                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10697                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10698                } catch (RemoteException ex) {
10699                }
10700                if (cpi == null) {
10701                    return null;
10702                }
10703                // If the provider is a singleton AND
10704                // (it's a call within the same user || the provider is a
10705                // privileged app)
10706                // Then allow connecting to the singleton provider
10707                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10708                        cpi.name, cpi.flags)
10709                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10710                if (singleton) {
10711                    userId = UserHandle.USER_SYSTEM;
10712                }
10713                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10714                checkTime(startTime, "getContentProviderImpl: got app info for user");
10715
10716                String msg;
10717                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10718                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10719                        != null) {
10720                    throw new SecurityException(msg);
10721                }
10722                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10723
10724                if (!mProcessesReady
10725                        && !cpi.processName.equals("system")) {
10726                    // If this content provider does not run in the system
10727                    // process, and the system is not yet ready to run other
10728                    // processes, then fail fast instead of hanging.
10729                    throw new IllegalArgumentException(
10730                            "Attempt to launch content provider before system ready");
10731                }
10732
10733                // Make sure that the user who owns this provider is running.  If not,
10734                // we don't want to allow it to run.
10735                if (!mUserController.isUserRunningLocked(userId, 0)) {
10736                    Slog.w(TAG, "Unable to launch app "
10737                            + cpi.applicationInfo.packageName + "/"
10738                            + cpi.applicationInfo.uid + " for provider "
10739                            + name + ": user " + userId + " is stopped");
10740                    return null;
10741                }
10742
10743                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10744                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10745                cpr = mProviderMap.getProviderByClass(comp, userId);
10746                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10747                final boolean firstClass = cpr == null;
10748                if (firstClass) {
10749                    final long ident = Binder.clearCallingIdentity();
10750
10751                    // If permissions need a review before any of the app components can run,
10752                    // we return no provider and launch a review activity if the calling app
10753                    // is in the foreground.
10754                    if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10755                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10756                            return null;
10757                        }
10758                    }
10759
10760                    try {
10761                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10762                        ApplicationInfo ai =
10763                            AppGlobals.getPackageManager().
10764                                getApplicationInfo(
10765                                        cpi.applicationInfo.packageName,
10766                                        STOCK_PM_FLAGS, userId);
10767                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10768                        if (ai == null) {
10769                            Slog.w(TAG, "No package info for content provider "
10770                                    + cpi.name);
10771                            return null;
10772                        }
10773                        ai = getAppInfoForUser(ai, userId);
10774                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10775                    } catch (RemoteException ex) {
10776                        // pm is in same process, this will never happen.
10777                    } finally {
10778                        Binder.restoreCallingIdentity(ident);
10779                    }
10780                }
10781
10782                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10783
10784                if (r != null && cpr.canRunHere(r)) {
10785                    // If this is a multiprocess provider, then just return its
10786                    // info and allow the caller to instantiate it.  Only do
10787                    // this if the provider is the same user as the caller's
10788                    // process, or can run as root (so can be in any process).
10789                    return cpr.newHolder(null);
10790                }
10791
10792                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10793                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10794                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10795
10796                // This is single process, and our app is now connecting to it.
10797                // See if we are already in the process of launching this
10798                // provider.
10799                final int N = mLaunchingProviders.size();
10800                int i;
10801                for (i = 0; i < N; i++) {
10802                    if (mLaunchingProviders.get(i) == cpr) {
10803                        break;
10804                    }
10805                }
10806
10807                // If the provider is not already being launched, then get it
10808                // started.
10809                if (i >= N) {
10810                    final long origId = Binder.clearCallingIdentity();
10811
10812                    try {
10813                        // Content provider is now in use, its package can't be stopped.
10814                        try {
10815                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10816                            AppGlobals.getPackageManager().setPackageStoppedState(
10817                                    cpr.appInfo.packageName, false, userId);
10818                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10819                        } catch (RemoteException e) {
10820                        } catch (IllegalArgumentException e) {
10821                            Slog.w(TAG, "Failed trying to unstop package "
10822                                    + cpr.appInfo.packageName + ": " + e);
10823                        }
10824
10825                        // Use existing process if already started
10826                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10827                        ProcessRecord proc = getProcessRecordLocked(
10828                                cpi.processName, cpr.appInfo.uid, false);
10829                        if (proc != null && proc.thread != null && !proc.killed) {
10830                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10831                                    "Installing in existing process " + proc);
10832                            if (!proc.pubProviders.containsKey(cpi.name)) {
10833                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10834                                proc.pubProviders.put(cpi.name, cpr);
10835                                try {
10836                                    proc.thread.scheduleInstallProvider(cpi);
10837                                } catch (RemoteException e) {
10838                                }
10839                            }
10840                        } else {
10841                            checkTime(startTime, "getContentProviderImpl: before start process");
10842                            proc = startProcessLocked(cpi.processName,
10843                                    cpr.appInfo, false, 0, "content provider",
10844                                    new ComponentName(cpi.applicationInfo.packageName,
10845                                            cpi.name), false, false, false);
10846                            checkTime(startTime, "getContentProviderImpl: after start process");
10847                            if (proc == null) {
10848                                Slog.w(TAG, "Unable to launch app "
10849                                        + cpi.applicationInfo.packageName + "/"
10850                                        + cpi.applicationInfo.uid + " for provider "
10851                                        + name + ": process is bad");
10852                                return null;
10853                            }
10854                        }
10855                        cpr.launchingApp = proc;
10856                        mLaunchingProviders.add(cpr);
10857                    } finally {
10858                        Binder.restoreCallingIdentity(origId);
10859                    }
10860                }
10861
10862                checkTime(startTime, "getContentProviderImpl: updating data structures");
10863
10864                // Make sure the provider is published (the same provider class
10865                // may be published under multiple names).
10866                if (firstClass) {
10867                    mProviderMap.putProviderByClass(comp, cpr);
10868                }
10869
10870                mProviderMap.putProviderByName(name, cpr);
10871                conn = incProviderCountLocked(r, cpr, token, stable);
10872                if (conn != null) {
10873                    conn.waiting = true;
10874                }
10875            }
10876            checkTime(startTime, "getContentProviderImpl: done!");
10877        }
10878
10879        // Wait for the provider to be published...
10880        synchronized (cpr) {
10881            while (cpr.provider == null) {
10882                if (cpr.launchingApp == null) {
10883                    Slog.w(TAG, "Unable to launch app "
10884                            + cpi.applicationInfo.packageName + "/"
10885                            + cpi.applicationInfo.uid + " for provider "
10886                            + name + ": launching app became null");
10887                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10888                            UserHandle.getUserId(cpi.applicationInfo.uid),
10889                            cpi.applicationInfo.packageName,
10890                            cpi.applicationInfo.uid, name);
10891                    return null;
10892                }
10893                try {
10894                    if (DEBUG_MU) Slog.v(TAG_MU,
10895                            "Waiting to start provider " + cpr
10896                            + " launchingApp=" + cpr.launchingApp);
10897                    if (conn != null) {
10898                        conn.waiting = true;
10899                    }
10900                    cpr.wait();
10901                } catch (InterruptedException ex) {
10902                } finally {
10903                    if (conn != null) {
10904                        conn.waiting = false;
10905                    }
10906                }
10907            }
10908        }
10909        return cpr != null ? cpr.newHolder(conn) : null;
10910    }
10911
10912    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10913            ProcessRecord r, final int userId) {
10914        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10915                cpi.packageName, userId)) {
10916
10917            final boolean callerForeground = r == null || r.setSchedGroup
10918                    != ProcessList.SCHED_GROUP_BACKGROUND;
10919
10920            // Show a permission review UI only for starting from a foreground app
10921            if (!callerForeground) {
10922                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10923                        + cpi.packageName + " requires a permissions review");
10924                return false;
10925            }
10926
10927            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10928            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10929                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10930            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10931
10932            if (DEBUG_PERMISSIONS_REVIEW) {
10933                Slog.i(TAG, "u" + userId + " Launching permission review "
10934                        + "for package " + cpi.packageName);
10935            }
10936
10937            final UserHandle userHandle = new UserHandle(userId);
10938            mHandler.post(new Runnable() {
10939                @Override
10940                public void run() {
10941                    mContext.startActivityAsUser(intent, userHandle);
10942                }
10943            });
10944
10945            return false;
10946        }
10947
10948        return true;
10949    }
10950
10951    PackageManagerInternal getPackageManagerInternalLocked() {
10952        if (mPackageManagerInt == null) {
10953            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10954        }
10955        return mPackageManagerInt;
10956    }
10957
10958    @Override
10959    public final ContentProviderHolder getContentProvider(
10960            IApplicationThread caller, String name, int userId, boolean stable) {
10961        enforceNotIsolatedCaller("getContentProvider");
10962        if (caller == null) {
10963            String msg = "null IApplicationThread when getting content provider "
10964                    + name;
10965            Slog.w(TAG, msg);
10966            throw new SecurityException(msg);
10967        }
10968        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10969        // with cross-user grant.
10970        return getContentProviderImpl(caller, name, null, stable, userId);
10971    }
10972
10973    public ContentProviderHolder getContentProviderExternal(
10974            String name, int userId, IBinder token) {
10975        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10976            "Do not have permission in call getContentProviderExternal()");
10977        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10978                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10979        return getContentProviderExternalUnchecked(name, token, userId);
10980    }
10981
10982    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10983            IBinder token, int userId) {
10984        return getContentProviderImpl(null, name, token, true, userId);
10985    }
10986
10987    /**
10988     * Drop a content provider from a ProcessRecord's bookkeeping
10989     */
10990    public void removeContentProvider(IBinder connection, boolean stable) {
10991        enforceNotIsolatedCaller("removeContentProvider");
10992        long ident = Binder.clearCallingIdentity();
10993        try {
10994            synchronized (this) {
10995                ContentProviderConnection conn;
10996                try {
10997                    conn = (ContentProviderConnection)connection;
10998                } catch (ClassCastException e) {
10999                    String msg ="removeContentProvider: " + connection
11000                            + " not a ContentProviderConnection";
11001                    Slog.w(TAG, msg);
11002                    throw new IllegalArgumentException(msg);
11003                }
11004                if (conn == null) {
11005                    throw new NullPointerException("connection is null");
11006                }
11007                if (decProviderCountLocked(conn, null, null, stable)) {
11008                    updateOomAdjLocked();
11009                }
11010            }
11011        } finally {
11012            Binder.restoreCallingIdentity(ident);
11013        }
11014    }
11015
11016    public void removeContentProviderExternal(String name, IBinder token) {
11017        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11018            "Do not have permission in call removeContentProviderExternal()");
11019        int userId = UserHandle.getCallingUserId();
11020        long ident = Binder.clearCallingIdentity();
11021        try {
11022            removeContentProviderExternalUnchecked(name, token, userId);
11023        } finally {
11024            Binder.restoreCallingIdentity(ident);
11025        }
11026    }
11027
11028    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11029        synchronized (this) {
11030            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11031            if(cpr == null) {
11032                //remove from mProvidersByClass
11033                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11034                return;
11035            }
11036
11037            //update content provider record entry info
11038            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11039            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11040            if (localCpr.hasExternalProcessHandles()) {
11041                if (localCpr.removeExternalProcessHandleLocked(token)) {
11042                    updateOomAdjLocked();
11043                } else {
11044                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11045                            + " with no external reference for token: "
11046                            + token + ".");
11047                }
11048            } else {
11049                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11050                        + " with no external references.");
11051            }
11052        }
11053    }
11054
11055    public final void publishContentProviders(IApplicationThread caller,
11056            List<ContentProviderHolder> providers) {
11057        if (providers == null) {
11058            return;
11059        }
11060
11061        enforceNotIsolatedCaller("publishContentProviders");
11062        synchronized (this) {
11063            final ProcessRecord r = getRecordForAppLocked(caller);
11064            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11065            if (r == null) {
11066                throw new SecurityException(
11067                        "Unable to find app for caller " + caller
11068                      + " (pid=" + Binder.getCallingPid()
11069                      + ") when publishing content providers");
11070            }
11071
11072            final long origId = Binder.clearCallingIdentity();
11073
11074            final int N = providers.size();
11075            for (int i = 0; i < N; i++) {
11076                ContentProviderHolder src = providers.get(i);
11077                if (src == null || src.info == null || src.provider == null) {
11078                    continue;
11079                }
11080                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11081                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11082                if (dst != null) {
11083                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11084                    mProviderMap.putProviderByClass(comp, dst);
11085                    String names[] = dst.info.authority.split(";");
11086                    for (int j = 0; j < names.length; j++) {
11087                        mProviderMap.putProviderByName(names[j], dst);
11088                    }
11089
11090                    int launchingCount = mLaunchingProviders.size();
11091                    int j;
11092                    boolean wasInLaunchingProviders = false;
11093                    for (j = 0; j < launchingCount; j++) {
11094                        if (mLaunchingProviders.get(j) == dst) {
11095                            mLaunchingProviders.remove(j);
11096                            wasInLaunchingProviders = true;
11097                            j--;
11098                            launchingCount--;
11099                        }
11100                    }
11101                    if (wasInLaunchingProviders) {
11102                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11103                    }
11104                    synchronized (dst) {
11105                        dst.provider = src.provider;
11106                        dst.proc = r;
11107                        dst.notifyAll();
11108                    }
11109                    updateOomAdjLocked(r);
11110                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11111                            src.info.authority);
11112                }
11113            }
11114
11115            Binder.restoreCallingIdentity(origId);
11116        }
11117    }
11118
11119    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11120        ContentProviderConnection conn;
11121        try {
11122            conn = (ContentProviderConnection)connection;
11123        } catch (ClassCastException e) {
11124            String msg ="refContentProvider: " + connection
11125                    + " not a ContentProviderConnection";
11126            Slog.w(TAG, msg);
11127            throw new IllegalArgumentException(msg);
11128        }
11129        if (conn == null) {
11130            throw new NullPointerException("connection is null");
11131        }
11132
11133        synchronized (this) {
11134            if (stable > 0) {
11135                conn.numStableIncs += stable;
11136            }
11137            stable = conn.stableCount + stable;
11138            if (stable < 0) {
11139                throw new IllegalStateException("stableCount < 0: " + stable);
11140            }
11141
11142            if (unstable > 0) {
11143                conn.numUnstableIncs += unstable;
11144            }
11145            unstable = conn.unstableCount + unstable;
11146            if (unstable < 0) {
11147                throw new IllegalStateException("unstableCount < 0: " + unstable);
11148            }
11149
11150            if ((stable+unstable) <= 0) {
11151                throw new IllegalStateException("ref counts can't go to zero here: stable="
11152                        + stable + " unstable=" + unstable);
11153            }
11154            conn.stableCount = stable;
11155            conn.unstableCount = unstable;
11156            return !conn.dead;
11157        }
11158    }
11159
11160    public void unstableProviderDied(IBinder connection) {
11161        ContentProviderConnection conn;
11162        try {
11163            conn = (ContentProviderConnection)connection;
11164        } catch (ClassCastException e) {
11165            String msg ="refContentProvider: " + connection
11166                    + " not a ContentProviderConnection";
11167            Slog.w(TAG, msg);
11168            throw new IllegalArgumentException(msg);
11169        }
11170        if (conn == null) {
11171            throw new NullPointerException("connection is null");
11172        }
11173
11174        // Safely retrieve the content provider associated with the connection.
11175        IContentProvider provider;
11176        synchronized (this) {
11177            provider = conn.provider.provider;
11178        }
11179
11180        if (provider == null) {
11181            // Um, yeah, we're way ahead of you.
11182            return;
11183        }
11184
11185        // Make sure the caller is being honest with us.
11186        if (provider.asBinder().pingBinder()) {
11187            // Er, no, still looks good to us.
11188            synchronized (this) {
11189                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11190                        + " says " + conn + " died, but we don't agree");
11191                return;
11192            }
11193        }
11194
11195        // Well look at that!  It's dead!
11196        synchronized (this) {
11197            if (conn.provider.provider != provider) {
11198                // But something changed...  good enough.
11199                return;
11200            }
11201
11202            ProcessRecord proc = conn.provider.proc;
11203            if (proc == null || proc.thread == null) {
11204                // Seems like the process is already cleaned up.
11205                return;
11206            }
11207
11208            // As far as we're concerned, this is just like receiving a
11209            // death notification...  just a bit prematurely.
11210            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11211                    + ") early provider death");
11212            final long ident = Binder.clearCallingIdentity();
11213            try {
11214                appDiedLocked(proc);
11215            } finally {
11216                Binder.restoreCallingIdentity(ident);
11217            }
11218        }
11219    }
11220
11221    @Override
11222    public void appNotRespondingViaProvider(IBinder connection) {
11223        enforceCallingPermission(
11224                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11225
11226        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11227        if (conn == null) {
11228            Slog.w(TAG, "ContentProviderConnection is null");
11229            return;
11230        }
11231
11232        final ProcessRecord host = conn.provider.proc;
11233        if (host == null) {
11234            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11235            return;
11236        }
11237
11238        mHandler.post(new Runnable() {
11239            @Override
11240            public void run() {
11241                mAppErrors.appNotResponding(host, null, null, false,
11242                        "ContentProvider not responding");
11243            }
11244        });
11245    }
11246
11247    public final void installSystemProviders() {
11248        List<ProviderInfo> providers;
11249        synchronized (this) {
11250            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11251            providers = generateApplicationProvidersLocked(app);
11252            if (providers != null) {
11253                for (int i=providers.size()-1; i>=0; i--) {
11254                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11255                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11256                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11257                                + ": not system .apk");
11258                        providers.remove(i);
11259                    }
11260                }
11261            }
11262        }
11263        if (providers != null) {
11264            mSystemThread.installSystemProviders(providers);
11265        }
11266
11267        mCoreSettingsObserver = new CoreSettingsObserver(this);
11268        mFontScaleSettingObserver = new FontScaleSettingObserver();
11269
11270        //mUsageStatsService.monitorPackages();
11271    }
11272
11273    private void startPersistentApps(int matchFlags) {
11274        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11275
11276        synchronized (this) {
11277            try {
11278                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11279                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11280                for (ApplicationInfo app : apps) {
11281                    if (!"android".equals(app.packageName)) {
11282                        addAppLocked(app, false, null /* ABI override */);
11283                    }
11284                }
11285            } catch (RemoteException ex) {
11286            }
11287        }
11288    }
11289
11290    /**
11291     * When a user is unlocked, we need to install encryption-unaware providers
11292     * belonging to any running apps.
11293     */
11294    private void installEncryptionUnawareProviders(int userId) {
11295        // We're only interested in providers that are encryption unaware, and
11296        // we don't care about uninstalled apps, since there's no way they're
11297        // running at this point.
11298        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11299
11300        synchronized (this) {
11301            final int NP = mProcessNames.getMap().size();
11302            for (int ip = 0; ip < NP; ip++) {
11303                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11304                final int NA = apps.size();
11305                for (int ia = 0; ia < NA; ia++) {
11306                    final ProcessRecord app = apps.valueAt(ia);
11307                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11308
11309                    final int NG = app.pkgList.size();
11310                    for (int ig = 0; ig < NG; ig++) {
11311                        try {
11312                            final String pkgName = app.pkgList.keyAt(ig);
11313                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11314                                    .getPackageInfo(pkgName, matchFlags, userId);
11315                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11316                                for (ProviderInfo pi : pkgInfo.providers) {
11317                                    // TODO: keep in sync with generateApplicationProvidersLocked
11318                                    final boolean processMatch = Objects.equals(pi.processName,
11319                                            app.processName) || pi.multiprocess;
11320                                    final boolean userMatch = isSingleton(pi.processName,
11321                                            pi.applicationInfo, pi.name, pi.flags)
11322                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11323                                    if (processMatch && userMatch) {
11324                                        Log.v(TAG, "Installing " + pi);
11325                                        app.thread.scheduleInstallProvider(pi);
11326                                    } else {
11327                                        Log.v(TAG, "Skipping " + pi);
11328                                    }
11329                                }
11330                            }
11331                        } catch (RemoteException ignored) {
11332                        }
11333                    }
11334                }
11335            }
11336        }
11337    }
11338
11339    /**
11340     * Allows apps to retrieve the MIME type of a URI.
11341     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11342     * users, then it does not need permission to access the ContentProvider.
11343     * Either, it needs cross-user uri grants.
11344     *
11345     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11346     *
11347     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11348     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11349     */
11350    public String getProviderMimeType(Uri uri, int userId) {
11351        enforceNotIsolatedCaller("getProviderMimeType");
11352        final String name = uri.getAuthority();
11353        int callingUid = Binder.getCallingUid();
11354        int callingPid = Binder.getCallingPid();
11355        long ident = 0;
11356        boolean clearedIdentity = false;
11357        synchronized (this) {
11358            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11359        }
11360        if (canClearIdentity(callingPid, callingUid, userId)) {
11361            clearedIdentity = true;
11362            ident = Binder.clearCallingIdentity();
11363        }
11364        ContentProviderHolder holder = null;
11365        try {
11366            holder = getContentProviderExternalUnchecked(name, null, userId);
11367            if (holder != null) {
11368                return holder.provider.getType(uri);
11369            }
11370        } catch (RemoteException e) {
11371            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11372            return null;
11373        } catch (Exception e) {
11374            Log.w(TAG, "Exception while determining type of " + uri, e);
11375            return null;
11376        } finally {
11377            // We need to clear the identity to call removeContentProviderExternalUnchecked
11378            if (!clearedIdentity) {
11379                ident = Binder.clearCallingIdentity();
11380            }
11381            try {
11382                if (holder != null) {
11383                    removeContentProviderExternalUnchecked(name, null, userId);
11384                }
11385            } finally {
11386                Binder.restoreCallingIdentity(ident);
11387            }
11388        }
11389
11390        return null;
11391    }
11392
11393    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11394        if (UserHandle.getUserId(callingUid) == userId) {
11395            return true;
11396        }
11397        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11398                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11399                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11400                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11401                return true;
11402        }
11403        return false;
11404    }
11405
11406    // =========================================================
11407    // GLOBAL MANAGEMENT
11408    // =========================================================
11409
11410    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11411            boolean isolated, int isolatedUid) {
11412        String proc = customProcess != null ? customProcess : info.processName;
11413        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11414        final int userId = UserHandle.getUserId(info.uid);
11415        int uid = info.uid;
11416        if (isolated) {
11417            if (isolatedUid == 0) {
11418                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11419                while (true) {
11420                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11421                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11422                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11423                    }
11424                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11425                    mNextIsolatedProcessUid++;
11426                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11427                        // No process for this uid, use it.
11428                        break;
11429                    }
11430                    stepsLeft--;
11431                    if (stepsLeft <= 0) {
11432                        return null;
11433                    }
11434                }
11435            } else {
11436                // Special case for startIsolatedProcess (internal only), where
11437                // the uid of the isolated process is specified by the caller.
11438                uid = isolatedUid;
11439            }
11440        }
11441        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11442        if (!mBooted && !mBooting
11443                && userId == UserHandle.USER_SYSTEM
11444                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11445            r.persistent = true;
11446            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11447        }
11448        addProcessNameLocked(r);
11449        return r;
11450    }
11451
11452    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11453            String abiOverride) {
11454        ProcessRecord app;
11455        if (!isolated) {
11456            app = getProcessRecordLocked(info.processName, info.uid, true);
11457        } else {
11458            app = null;
11459        }
11460
11461        if (app == null) {
11462            app = newProcessRecordLocked(info, null, isolated, 0);
11463            updateLruProcessLocked(app, false, null);
11464            updateOomAdjLocked();
11465        }
11466
11467        // This package really, really can not be stopped.
11468        try {
11469            AppGlobals.getPackageManager().setPackageStoppedState(
11470                    info.packageName, false, UserHandle.getUserId(app.uid));
11471        } catch (RemoteException e) {
11472        } catch (IllegalArgumentException e) {
11473            Slog.w(TAG, "Failed trying to unstop package "
11474                    + info.packageName + ": " + e);
11475        }
11476
11477        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11478            app.persistent = true;
11479            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11480        }
11481        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11482            mPersistentStartingProcesses.add(app);
11483            startProcessLocked(app, "added application", app.processName, abiOverride,
11484                    null /* entryPoint */, null /* entryPointArgs */);
11485        }
11486
11487        return app;
11488    }
11489
11490    public void unhandledBack() {
11491        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11492                "unhandledBack()");
11493
11494        synchronized(this) {
11495            final long origId = Binder.clearCallingIdentity();
11496            try {
11497                getFocusedStack().unhandledBackLocked();
11498            } finally {
11499                Binder.restoreCallingIdentity(origId);
11500            }
11501        }
11502    }
11503
11504    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11505        enforceNotIsolatedCaller("openContentUri");
11506        final int userId = UserHandle.getCallingUserId();
11507        String name = uri.getAuthority();
11508        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11509        ParcelFileDescriptor pfd = null;
11510        if (cph != null) {
11511            // We record the binder invoker's uid in thread-local storage before
11512            // going to the content provider to open the file.  Later, in the code
11513            // that handles all permissions checks, we look for this uid and use
11514            // that rather than the Activity Manager's own uid.  The effect is that
11515            // we do the check against the caller's permissions even though it looks
11516            // to the content provider like the Activity Manager itself is making
11517            // the request.
11518            Binder token = new Binder();
11519            sCallerIdentity.set(new Identity(
11520                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11521            try {
11522                pfd = cph.provider.openFile(null, uri, "r", null, token);
11523            } catch (FileNotFoundException e) {
11524                // do nothing; pfd will be returned null
11525            } finally {
11526                // Ensure that whatever happens, we clean up the identity state
11527                sCallerIdentity.remove();
11528                // Ensure we're done with the provider.
11529                removeContentProviderExternalUnchecked(name, null, userId);
11530            }
11531        } else {
11532            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11533        }
11534        return pfd;
11535    }
11536
11537    // Actually is sleeping or shutting down or whatever else in the future
11538    // is an inactive state.
11539    boolean isSleepingOrShuttingDownLocked() {
11540        return isSleepingLocked() || mShuttingDown;
11541    }
11542
11543    boolean isShuttingDownLocked() {
11544        return mShuttingDown;
11545    }
11546
11547    boolean isSleepingLocked() {
11548        return mSleeping;
11549    }
11550
11551    void onWakefulnessChanged(int wakefulness) {
11552        synchronized(this) {
11553            mWakefulness = wakefulness;
11554            updateSleepIfNeededLocked();
11555        }
11556    }
11557
11558    void finishRunningVoiceLocked() {
11559        if (mRunningVoice != null) {
11560            mRunningVoice = null;
11561            mVoiceWakeLock.release();
11562            updateSleepIfNeededLocked();
11563        }
11564    }
11565
11566    void startTimeTrackingFocusedActivityLocked() {
11567        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11568            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11569        }
11570    }
11571
11572    void updateSleepIfNeededLocked() {
11573        if (mSleeping && !shouldSleepLocked()) {
11574            mSleeping = false;
11575            startTimeTrackingFocusedActivityLocked();
11576            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11577            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11578            updateOomAdjLocked();
11579        } else if (!mSleeping && shouldSleepLocked()) {
11580            mSleeping = true;
11581            if (mCurAppTimeTracker != null) {
11582                mCurAppTimeTracker.stop();
11583            }
11584            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11585            mStackSupervisor.goingToSleepLocked();
11586            updateOomAdjLocked();
11587
11588            // Initialize the wake times of all processes.
11589            checkExcessivePowerUsageLocked(false);
11590            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11591            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11592            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11593        }
11594    }
11595
11596    private boolean shouldSleepLocked() {
11597        // Resume applications while running a voice interactor.
11598        if (mRunningVoice != null) {
11599            return false;
11600        }
11601
11602        // TODO: Transform the lock screen state into a sleep token instead.
11603        switch (mWakefulness) {
11604            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11605            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11606            case PowerManagerInternal.WAKEFULNESS_DOZING:
11607                // Pause applications whenever the lock screen is shown or any sleep
11608                // tokens have been acquired.
11609                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11610            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11611            default:
11612                // If we're asleep then pause applications unconditionally.
11613                return true;
11614        }
11615    }
11616
11617    /** Pokes the task persister. */
11618    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11619        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11620    }
11621
11622    /** Notifies all listeners when the task stack has changed. */
11623    void notifyTaskStackChangedLocked() {
11624        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11625        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11626        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11627        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11628    }
11629
11630    /** Notifies all listeners when an Activity is pinned. */
11631    void notifyActivityPinnedLocked() {
11632        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11633        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11634    }
11635
11636    /**
11637     * Notifies all listeners when an attempt was made to start an an activity that is already
11638     * running in the pinned stack and the activity was not actually started, but the task is
11639     * either brought to the front or a new Intent is delivered to it.
11640     */
11641    void notifyPinnedActivityRestartAttemptLocked() {
11642        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11643        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11644    }
11645
11646    /** Notifies all listeners when the pinned stack animation ends. */
11647    @Override
11648    public void notifyPinnedStackAnimationEnded() {
11649        synchronized (this) {
11650            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11651            mHandler.obtainMessage(
11652                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11653        }
11654    }
11655
11656    @Override
11657    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11658        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11659    }
11660
11661    @Override
11662    public boolean shutdown(int timeout) {
11663        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11664                != PackageManager.PERMISSION_GRANTED) {
11665            throw new SecurityException("Requires permission "
11666                    + android.Manifest.permission.SHUTDOWN);
11667        }
11668
11669        boolean timedout = false;
11670
11671        synchronized(this) {
11672            mShuttingDown = true;
11673            updateEventDispatchingLocked();
11674            timedout = mStackSupervisor.shutdownLocked(timeout);
11675        }
11676
11677        mAppOpsService.shutdown();
11678        if (mUsageStatsService != null) {
11679            mUsageStatsService.prepareShutdown();
11680        }
11681        mBatteryStatsService.shutdown();
11682        synchronized (this) {
11683            mProcessStats.shutdownLocked();
11684            notifyTaskPersisterLocked(null, true);
11685        }
11686
11687        return timedout;
11688    }
11689
11690    public final void activitySlept(IBinder token) {
11691        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11692
11693        final long origId = Binder.clearCallingIdentity();
11694
11695        synchronized (this) {
11696            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11697            if (r != null) {
11698                mStackSupervisor.activitySleptLocked(r);
11699            }
11700        }
11701
11702        Binder.restoreCallingIdentity(origId);
11703    }
11704
11705    private String lockScreenShownToString() {
11706        switch (mLockScreenShown) {
11707            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11708            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11709            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11710            default: return "Unknown=" + mLockScreenShown;
11711        }
11712    }
11713
11714    void logLockScreen(String msg) {
11715        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11716                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11717                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11718                + " mSleeping=" + mSleeping);
11719    }
11720
11721    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11722        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11723        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11724        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11725            boolean wasRunningVoice = mRunningVoice != null;
11726            mRunningVoice = session;
11727            if (!wasRunningVoice) {
11728                mVoiceWakeLock.acquire();
11729                updateSleepIfNeededLocked();
11730            }
11731        }
11732    }
11733
11734    private void updateEventDispatchingLocked() {
11735        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11736    }
11737
11738    public void setLockScreenShown(boolean showing, boolean occluded) {
11739        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11740                != PackageManager.PERMISSION_GRANTED) {
11741            throw new SecurityException("Requires permission "
11742                    + android.Manifest.permission.DEVICE_POWER);
11743        }
11744
11745        synchronized(this) {
11746            long ident = Binder.clearCallingIdentity();
11747            try {
11748                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11749                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11750                if (showing && occluded) {
11751                    // The lock screen is currently showing, but is occluded by a window that can
11752                    // show on top of the lock screen. In this can we want to dismiss the docked
11753                    // stack since it will be complicated/risky to try to put the activity on top
11754                    // of the lock screen in the right fullscreen configuration.
11755                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11756                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11757                }
11758
11759                updateSleepIfNeededLocked();
11760            } finally {
11761                Binder.restoreCallingIdentity(ident);
11762            }
11763        }
11764    }
11765
11766    @Override
11767    public void notifyLockedProfile(@UserIdInt int userId) {
11768        try {
11769            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11770                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11771            }
11772        } catch (RemoteException ex) {
11773            throw new SecurityException("Fail to check is caller a privileged app", ex);
11774        }
11775
11776        synchronized (this) {
11777            if (mStackSupervisor.isUserLockedProfile(userId)) {
11778                final long ident = Binder.clearCallingIdentity();
11779                try {
11780                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11781                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11782                        // If there is no device lock, we will show the profile's credential page.
11783                        mActivityStarter.showConfirmDeviceCredential(userId);
11784                    } else {
11785                        // Showing launcher to avoid user entering credential twice.
11786                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11787                    }
11788                } finally {
11789                    Binder.restoreCallingIdentity(ident);
11790                }
11791            }
11792        }
11793    }
11794
11795    @Override
11796    public void startConfirmDeviceCredentialIntent(Intent intent) {
11797        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11798        synchronized (this) {
11799            final long ident = Binder.clearCallingIdentity();
11800            try {
11801                mActivityStarter.startConfirmCredentialIntent(intent);
11802            } finally {
11803                Binder.restoreCallingIdentity(ident);
11804            }
11805        }
11806    }
11807
11808    @Override
11809    public void stopAppSwitches() {
11810        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11811                != PackageManager.PERMISSION_GRANTED) {
11812            throw new SecurityException("viewquires permission "
11813                    + android.Manifest.permission.STOP_APP_SWITCHES);
11814        }
11815
11816        synchronized(this) {
11817            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11818                    + APP_SWITCH_DELAY_TIME;
11819            mDidAppSwitch = false;
11820            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11821            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11822            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11823        }
11824    }
11825
11826    public void resumeAppSwitches() {
11827        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11828                != PackageManager.PERMISSION_GRANTED) {
11829            throw new SecurityException("Requires permission "
11830                    + android.Manifest.permission.STOP_APP_SWITCHES);
11831        }
11832
11833        synchronized(this) {
11834            // Note that we don't execute any pending app switches... we will
11835            // let those wait until either the timeout, or the next start
11836            // activity request.
11837            mAppSwitchesAllowedTime = 0;
11838        }
11839    }
11840
11841    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11842            int callingPid, int callingUid, String name) {
11843        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11844            return true;
11845        }
11846
11847        int perm = checkComponentPermission(
11848                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11849                sourceUid, -1, true);
11850        if (perm == PackageManager.PERMISSION_GRANTED) {
11851            return true;
11852        }
11853
11854        // If the actual IPC caller is different from the logical source, then
11855        // also see if they are allowed to control app switches.
11856        if (callingUid != -1 && callingUid != sourceUid) {
11857            perm = checkComponentPermission(
11858                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11859                    callingUid, -1, true);
11860            if (perm == PackageManager.PERMISSION_GRANTED) {
11861                return true;
11862            }
11863        }
11864
11865        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11866        return false;
11867    }
11868
11869    public void setDebugApp(String packageName, boolean waitForDebugger,
11870            boolean persistent) {
11871        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11872                "setDebugApp()");
11873
11874        long ident = Binder.clearCallingIdentity();
11875        try {
11876            // Note that this is not really thread safe if there are multiple
11877            // callers into it at the same time, but that's not a situation we
11878            // care about.
11879            if (persistent) {
11880                final ContentResolver resolver = mContext.getContentResolver();
11881                Settings.Global.putString(
11882                    resolver, Settings.Global.DEBUG_APP,
11883                    packageName);
11884                Settings.Global.putInt(
11885                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11886                    waitForDebugger ? 1 : 0);
11887            }
11888
11889            synchronized (this) {
11890                if (!persistent) {
11891                    mOrigDebugApp = mDebugApp;
11892                    mOrigWaitForDebugger = mWaitForDebugger;
11893                }
11894                mDebugApp = packageName;
11895                mWaitForDebugger = waitForDebugger;
11896                mDebugTransient = !persistent;
11897                if (packageName != null) {
11898                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11899                            false, UserHandle.USER_ALL, "set debug app");
11900                }
11901            }
11902        } finally {
11903            Binder.restoreCallingIdentity(ident);
11904        }
11905    }
11906
11907    void setTrackAllocationApp(ApplicationInfo app, String processName) {
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
11916            mTrackAllocationApp = processName;
11917        }
11918    }
11919
11920    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11921        synchronized (this) {
11922            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11923            if (!isDebuggable) {
11924                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11925                    throw new SecurityException("Process not debuggable: " + app.packageName);
11926                }
11927            }
11928            mProfileApp = processName;
11929            mProfileFile = profilerInfo.profileFile;
11930            if (mProfileFd != null) {
11931                try {
11932                    mProfileFd.close();
11933                } catch (IOException e) {
11934                }
11935                mProfileFd = null;
11936            }
11937            mProfileFd = profilerInfo.profileFd;
11938            mSamplingInterval = profilerInfo.samplingInterval;
11939            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11940            mProfileType = 0;
11941        }
11942    }
11943
11944    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11945        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11946        if (!isDebuggable) {
11947            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11948                throw new SecurityException("Process not debuggable: " + app.packageName);
11949            }
11950        }
11951        mNativeDebuggingApp = processName;
11952    }
11953
11954    @Override
11955    public void setAlwaysFinish(boolean enabled) {
11956        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11957                "setAlwaysFinish()");
11958
11959        long ident = Binder.clearCallingIdentity();
11960        try {
11961            Settings.Global.putInt(
11962                    mContext.getContentResolver(),
11963                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11964
11965            synchronized (this) {
11966                mAlwaysFinishActivities = enabled;
11967            }
11968        } finally {
11969            Binder.restoreCallingIdentity(ident);
11970        }
11971    }
11972
11973    @Override
11974    public void setLenientBackgroundCheck(boolean enabled) {
11975        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11976                "setLenientBackgroundCheck()");
11977
11978        long ident = Binder.clearCallingIdentity();
11979        try {
11980            Settings.Global.putInt(
11981                    mContext.getContentResolver(),
11982                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11983
11984            synchronized (this) {
11985                mLenientBackgroundCheck = enabled;
11986            }
11987        } finally {
11988            Binder.restoreCallingIdentity(ident);
11989        }
11990    }
11991
11992    @Override
11993    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11994        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11995                "setActivityController()");
11996        synchronized (this) {
11997            mController = controller;
11998            mControllerIsAMonkey = imAMonkey;
11999            Watchdog.getInstance().setActivityController(controller);
12000        }
12001    }
12002
12003    @Override
12004    public void setUserIsMonkey(boolean userIsMonkey) {
12005        synchronized (this) {
12006            synchronized (mPidsSelfLocked) {
12007                final int callingPid = Binder.getCallingPid();
12008                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12009                if (precessRecord == null) {
12010                    throw new SecurityException("Unknown process: " + callingPid);
12011                }
12012                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12013                    throw new SecurityException("Only an instrumentation process "
12014                            + "with a UiAutomation can call setUserIsMonkey");
12015                }
12016            }
12017            mUserIsMonkey = userIsMonkey;
12018        }
12019    }
12020
12021    @Override
12022    public boolean isUserAMonkey() {
12023        synchronized (this) {
12024            // If there is a controller also implies the user is a monkey.
12025            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12026        }
12027    }
12028
12029    public void requestBugReport(int bugreportType) {
12030        String service = null;
12031        switch (bugreportType) {
12032            case ActivityManager.BUGREPORT_OPTION_FULL:
12033                service = "bugreport";
12034                break;
12035            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12036                service = "bugreportplus";
12037                break;
12038            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12039                service = "bugreportremote";
12040                break;
12041        }
12042        if (service == null) {
12043            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12044                    + bugreportType);
12045        }
12046        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12047        SystemProperties.set("ctl.start", service);
12048    }
12049
12050    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12051        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12052    }
12053
12054    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12055        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12056            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12057        }
12058        return KEY_DISPATCHING_TIMEOUT;
12059    }
12060
12061    @Override
12062    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12063        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12064                != PackageManager.PERMISSION_GRANTED) {
12065            throw new SecurityException("Requires permission "
12066                    + android.Manifest.permission.FILTER_EVENTS);
12067        }
12068        ProcessRecord proc;
12069        long timeout;
12070        synchronized (this) {
12071            synchronized (mPidsSelfLocked) {
12072                proc = mPidsSelfLocked.get(pid);
12073            }
12074            timeout = getInputDispatchingTimeoutLocked(proc);
12075        }
12076
12077        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12078            return -1;
12079        }
12080
12081        return timeout;
12082    }
12083
12084    /**
12085     * Handle input dispatching timeouts.
12086     * Returns whether input dispatching should be aborted or not.
12087     */
12088    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12089            final ActivityRecord activity, final ActivityRecord parent,
12090            final boolean aboveSystem, String reason) {
12091        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12092                != PackageManager.PERMISSION_GRANTED) {
12093            throw new SecurityException("Requires permission "
12094                    + android.Manifest.permission.FILTER_EVENTS);
12095        }
12096
12097        final String annotation;
12098        if (reason == null) {
12099            annotation = "Input dispatching timed out";
12100        } else {
12101            annotation = "Input dispatching timed out (" + reason + ")";
12102        }
12103
12104        if (proc != null) {
12105            synchronized (this) {
12106                if (proc.debugging) {
12107                    return false;
12108                }
12109
12110                if (mDidDexOpt) {
12111                    // Give more time since we were dexopting.
12112                    mDidDexOpt = false;
12113                    return false;
12114                }
12115
12116                if (proc.instrumentationClass != null) {
12117                    Bundle info = new Bundle();
12118                    info.putString("shortMsg", "keyDispatchingTimedOut");
12119                    info.putString("longMsg", annotation);
12120                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12121                    return true;
12122                }
12123            }
12124            mHandler.post(new Runnable() {
12125                @Override
12126                public void run() {
12127                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12128                }
12129            });
12130        }
12131
12132        return true;
12133    }
12134
12135    @Override
12136    public Bundle getAssistContextExtras(int requestType) {
12137        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12138                null, null, true /* focused */, true /* newSessionId */,
12139                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12140        if (pae == null) {
12141            return null;
12142        }
12143        synchronized (pae) {
12144            while (!pae.haveResult) {
12145                try {
12146                    pae.wait();
12147                } catch (InterruptedException e) {
12148                }
12149            }
12150        }
12151        synchronized (this) {
12152            buildAssistBundleLocked(pae, pae.result);
12153            mPendingAssistExtras.remove(pae);
12154            mUiHandler.removeCallbacks(pae);
12155        }
12156        return pae.extras;
12157    }
12158
12159    @Override
12160    public boolean isAssistDataAllowedOnCurrentActivity() {
12161        int userId;
12162        synchronized (this) {
12163            userId = mUserController.getCurrentUserIdLocked();
12164            ActivityRecord activity = getFocusedStack().topActivity();
12165            if (activity == null) {
12166                return false;
12167            }
12168            userId = activity.userId;
12169        }
12170        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12171                Context.DEVICE_POLICY_SERVICE);
12172        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12173    }
12174
12175    @Override
12176    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12177        long ident = Binder.clearCallingIdentity();
12178        try {
12179            synchronized (this) {
12180                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12181                ActivityRecord top = getFocusedStack().topActivity();
12182                if (top != caller) {
12183                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12184                            + " is not current top " + top);
12185                    return false;
12186                }
12187                if (!top.nowVisible) {
12188                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12189                            + " is not visible");
12190                    return false;
12191                }
12192            }
12193            AssistUtils utils = new AssistUtils(mContext);
12194            return utils.showSessionForActiveService(args,
12195                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12196        } finally {
12197            Binder.restoreCallingIdentity(ident);
12198        }
12199    }
12200
12201    @Override
12202    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12203            Bundle receiverExtras,
12204            IBinder activityToken, boolean focused, boolean newSessionId) {
12205        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12206                activityToken, focused, newSessionId,
12207                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12208                != null;
12209    }
12210
12211    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12212            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12213            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12214        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12215                "enqueueAssistContext()");
12216        synchronized (this) {
12217            ActivityRecord activity = getFocusedStack().topActivity();
12218            if (activity == null) {
12219                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12220                return null;
12221            }
12222            if (activity.app == null || activity.app.thread == null) {
12223                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12224                return null;
12225            }
12226            if (focused) {
12227                if (activityToken != null) {
12228                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12229                    if (activity != caller) {
12230                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12231                                + " is not current top " + activity);
12232                        return null;
12233                    }
12234                }
12235            } else {
12236                activity = ActivityRecord.forTokenLocked(activityToken);
12237                if (activity == null) {
12238                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12239                            + " couldn't be found");
12240                    return null;
12241                }
12242            }
12243
12244            PendingAssistExtras pae;
12245            Bundle extras = new Bundle();
12246            if (args != null) {
12247                extras.putAll(args);
12248            }
12249            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12250            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12251            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12252                    userHandle);
12253            // Increment the sessionId if necessary
12254            if (newSessionId) {
12255                mViSessionId++;
12256            }
12257            try {
12258                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12259                        requestType, mViSessionId);
12260                mPendingAssistExtras.add(pae);
12261                mUiHandler.postDelayed(pae, timeout);
12262            } catch (RemoteException e) {
12263                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12264                return null;
12265            }
12266            return pae;
12267        }
12268    }
12269
12270    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12271        IResultReceiver receiver;
12272        synchronized (this) {
12273            mPendingAssistExtras.remove(pae);
12274            receiver = pae.receiver;
12275        }
12276        if (receiver != null) {
12277            // Caller wants result sent back to them.
12278            Bundle sendBundle = new Bundle();
12279            // At least return the receiver extras
12280            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12281                    pae.receiverExtras);
12282            try {
12283                pae.receiver.send(0, sendBundle);
12284            } catch (RemoteException e) {
12285            }
12286        }
12287    }
12288
12289    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12290        if (result != null) {
12291            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12292        }
12293        if (pae.hint != null) {
12294            pae.extras.putBoolean(pae.hint, true);
12295        }
12296    }
12297
12298    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12299            AssistContent content, Uri referrer) {
12300        PendingAssistExtras pae = (PendingAssistExtras)token;
12301        synchronized (pae) {
12302            pae.result = extras;
12303            pae.structure = structure;
12304            pae.content = content;
12305            if (referrer != null) {
12306                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12307            }
12308            pae.haveResult = true;
12309            pae.notifyAll();
12310            if (pae.intent == null && pae.receiver == null) {
12311                // Caller is just waiting for the result.
12312                return;
12313            }
12314        }
12315
12316        // We are now ready to launch the assist activity.
12317        IResultReceiver sendReceiver = null;
12318        Bundle sendBundle = null;
12319        synchronized (this) {
12320            buildAssistBundleLocked(pae, extras);
12321            boolean exists = mPendingAssistExtras.remove(pae);
12322            mUiHandler.removeCallbacks(pae);
12323            if (!exists) {
12324                // Timed out.
12325                return;
12326            }
12327            if ((sendReceiver=pae.receiver) != null) {
12328                // Caller wants result sent back to them.
12329                sendBundle = new Bundle();
12330                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12331                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12332                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12333                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12334                        pae.receiverExtras);
12335            }
12336        }
12337        if (sendReceiver != null) {
12338            try {
12339                sendReceiver.send(0, sendBundle);
12340            } catch (RemoteException e) {
12341            }
12342            return;
12343        }
12344
12345        long ident = Binder.clearCallingIdentity();
12346        try {
12347            pae.intent.replaceExtras(pae.extras);
12348            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12349                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12350                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12351            closeSystemDialogs("assist");
12352            try {
12353                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12354            } catch (ActivityNotFoundException e) {
12355                Slog.w(TAG, "No activity to handle assist action.", e);
12356            }
12357        } finally {
12358            Binder.restoreCallingIdentity(ident);
12359        }
12360    }
12361
12362    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12363            Bundle args) {
12364        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12365                true /* focused */, true /* newSessionId */,
12366                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12367    }
12368
12369    public void registerProcessObserver(IProcessObserver observer) {
12370        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12371                "registerProcessObserver()");
12372        synchronized (this) {
12373            mProcessObservers.register(observer);
12374        }
12375    }
12376
12377    @Override
12378    public void unregisterProcessObserver(IProcessObserver observer) {
12379        synchronized (this) {
12380            mProcessObservers.unregister(observer);
12381        }
12382    }
12383
12384    @Override
12385    public void registerUidObserver(IUidObserver observer, int which) {
12386        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12387                "registerUidObserver()");
12388        synchronized (this) {
12389            mUidObservers.register(observer, which);
12390        }
12391    }
12392
12393    @Override
12394    public void unregisterUidObserver(IUidObserver observer) {
12395        synchronized (this) {
12396            mUidObservers.unregister(observer);
12397        }
12398    }
12399
12400    @Override
12401    public boolean convertFromTranslucent(IBinder token) {
12402        final long origId = Binder.clearCallingIdentity();
12403        try {
12404            synchronized (this) {
12405                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12406                if (r == null) {
12407                    return false;
12408                }
12409                final boolean translucentChanged = r.changeWindowTranslucency(true);
12410                if (translucentChanged) {
12411                    r.task.stack.releaseBackgroundResources(r);
12412                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12413                }
12414                mWindowManager.setAppFullscreen(token, true);
12415                return translucentChanged;
12416            }
12417        } finally {
12418            Binder.restoreCallingIdentity(origId);
12419        }
12420    }
12421
12422    @Override
12423    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12424        final long origId = Binder.clearCallingIdentity();
12425        try {
12426            synchronized (this) {
12427                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12428                if (r == null) {
12429                    return false;
12430                }
12431                int index = r.task.mActivities.lastIndexOf(r);
12432                if (index > 0) {
12433                    ActivityRecord under = r.task.mActivities.get(index - 1);
12434                    under.returningOptions = options;
12435                }
12436                final boolean translucentChanged = r.changeWindowTranslucency(false);
12437                if (translucentChanged) {
12438                    r.task.stack.convertActivityToTranslucent(r);
12439                }
12440                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12441                mWindowManager.setAppFullscreen(token, false);
12442                return translucentChanged;
12443            }
12444        } finally {
12445            Binder.restoreCallingIdentity(origId);
12446        }
12447    }
12448
12449    @Override
12450    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12451        final long origId = Binder.clearCallingIdentity();
12452        try {
12453            synchronized (this) {
12454                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12455                if (r != null) {
12456                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12457                }
12458            }
12459            return false;
12460        } finally {
12461            Binder.restoreCallingIdentity(origId);
12462        }
12463    }
12464
12465    @Override
12466    public boolean isBackgroundVisibleBehind(IBinder token) {
12467        final long origId = Binder.clearCallingIdentity();
12468        try {
12469            synchronized (this) {
12470                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12471                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12472                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12473                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12474                return visible;
12475            }
12476        } finally {
12477            Binder.restoreCallingIdentity(origId);
12478        }
12479    }
12480
12481    @Override
12482    public ActivityOptions getActivityOptions(IBinder token) {
12483        final long origId = Binder.clearCallingIdentity();
12484        try {
12485            synchronized (this) {
12486                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12487                if (r != null) {
12488                    final ActivityOptions activityOptions = r.pendingOptions;
12489                    r.pendingOptions = null;
12490                    return activityOptions;
12491                }
12492                return null;
12493            }
12494        } finally {
12495            Binder.restoreCallingIdentity(origId);
12496        }
12497    }
12498
12499    @Override
12500    public void setImmersive(IBinder token, boolean immersive) {
12501        synchronized(this) {
12502            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12503            if (r == null) {
12504                throw new IllegalArgumentException();
12505            }
12506            r.immersive = immersive;
12507
12508            // update associated state if we're frontmost
12509            if (r == mFocusedActivity) {
12510                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12511                applyUpdateLockStateLocked(r);
12512            }
12513        }
12514    }
12515
12516    @Override
12517    public boolean isImmersive(IBinder token) {
12518        synchronized (this) {
12519            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12520            if (r == null) {
12521                throw new IllegalArgumentException();
12522            }
12523            return r.immersive;
12524        }
12525    }
12526
12527    @Override
12528    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12529        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12530            throw new UnsupportedOperationException("VR mode not supported on this device!");
12531        }
12532
12533        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12534
12535        ActivityRecord r;
12536        synchronized (this) {
12537            r = ActivityRecord.isInStackLocked(token);
12538        }
12539
12540        if (r == null) {
12541            throw new IllegalArgumentException();
12542        }
12543
12544        int err;
12545        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12546                VrManagerInternal.NO_ERROR) {
12547            return err;
12548        }
12549
12550        synchronized(this) {
12551            r.requestedVrComponent = (enabled) ? packageName : null;
12552
12553            // Update associated state if this activity is currently focused
12554            if (r == mFocusedActivity) {
12555                applyUpdateVrModeLocked(r);
12556            }
12557            return 0;
12558        }
12559    }
12560
12561    @Override
12562    public boolean isVrModePackageEnabled(ComponentName packageName) {
12563        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12564            throw new UnsupportedOperationException("VR mode not supported on this device!");
12565        }
12566
12567        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12568
12569        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12570                VrManagerInternal.NO_ERROR;
12571    }
12572
12573    public boolean isTopActivityImmersive() {
12574        enforceNotIsolatedCaller("startActivity");
12575        synchronized (this) {
12576            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12577            return (r != null) ? r.immersive : false;
12578        }
12579    }
12580
12581    @Override
12582    public boolean isTopOfTask(IBinder token) {
12583        synchronized (this) {
12584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12585            if (r == null) {
12586                throw new IllegalArgumentException();
12587            }
12588            return r.task.getTopActivity() == r;
12589        }
12590    }
12591
12592    public final void enterSafeMode() {
12593        synchronized(this) {
12594            // It only makes sense to do this before the system is ready
12595            // and started launching other packages.
12596            if (!mSystemReady) {
12597                try {
12598                    AppGlobals.getPackageManager().enterSafeMode();
12599                } catch (RemoteException e) {
12600                }
12601            }
12602
12603            mSafeMode = true;
12604        }
12605    }
12606
12607    public final void showSafeModeOverlay() {
12608        View v = LayoutInflater.from(mContext).inflate(
12609                com.android.internal.R.layout.safe_mode, null);
12610        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12611        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12612        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12613        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12614        lp.gravity = Gravity.BOTTOM | Gravity.START;
12615        lp.format = v.getBackground().getOpacity();
12616        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12617                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12618        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12619        ((WindowManager)mContext.getSystemService(
12620                Context.WINDOW_SERVICE)).addView(v, lp);
12621    }
12622
12623    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12624        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12625            return;
12626        }
12627        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12628        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12629        synchronized (stats) {
12630            if (mBatteryStatsService.isOnBattery()) {
12631                mBatteryStatsService.enforceCallingPermission();
12632                int MY_UID = Binder.getCallingUid();
12633                final int uid;
12634                if (sender == null) {
12635                    uid = sourceUid;
12636                } else {
12637                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12638                }
12639                BatteryStatsImpl.Uid.Pkg pkg =
12640                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12641                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12642                pkg.noteWakeupAlarmLocked(tag);
12643            }
12644        }
12645    }
12646
12647    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12648        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12649            return;
12650        }
12651        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12652        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12653        synchronized (stats) {
12654            mBatteryStatsService.enforceCallingPermission();
12655            int MY_UID = Binder.getCallingUid();
12656            final int uid;
12657            if (sender == null) {
12658                uid = sourceUid;
12659            } else {
12660                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12661            }
12662            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12663        }
12664    }
12665
12666    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12667        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12668            return;
12669        }
12670        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12671        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12672        synchronized (stats) {
12673            mBatteryStatsService.enforceCallingPermission();
12674            int MY_UID = Binder.getCallingUid();
12675            final int uid;
12676            if (sender == null) {
12677                uid = sourceUid;
12678            } else {
12679                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12680            }
12681            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12682        }
12683    }
12684
12685    public boolean killPids(int[] pids, String pReason, boolean secure) {
12686        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12687            throw new SecurityException("killPids only available to the system");
12688        }
12689        String reason = (pReason == null) ? "Unknown" : pReason;
12690        // XXX Note: don't acquire main activity lock here, because the window
12691        // manager calls in with its locks held.
12692
12693        boolean killed = false;
12694        synchronized (mPidsSelfLocked) {
12695            int worstType = 0;
12696            for (int i=0; i<pids.length; i++) {
12697                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12698                if (proc != null) {
12699                    int type = proc.setAdj;
12700                    if (type > worstType) {
12701                        worstType = type;
12702                    }
12703                }
12704            }
12705
12706            // If the worst oom_adj is somewhere in the cached proc LRU range,
12707            // then constrain it so we will kill all cached procs.
12708            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12709                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12710                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12711            }
12712
12713            // If this is not a secure call, don't let it kill processes that
12714            // are important.
12715            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12716                worstType = ProcessList.SERVICE_ADJ;
12717            }
12718
12719            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12720            for (int i=0; i<pids.length; i++) {
12721                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12722                if (proc == null) {
12723                    continue;
12724                }
12725                int adj = proc.setAdj;
12726                if (adj >= worstType && !proc.killedByAm) {
12727                    proc.kill(reason, true);
12728                    killed = true;
12729                }
12730            }
12731        }
12732        return killed;
12733    }
12734
12735    @Override
12736    public void killUid(int appId, int userId, String reason) {
12737        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12738        synchronized (this) {
12739            final long identity = Binder.clearCallingIdentity();
12740            try {
12741                killPackageProcessesLocked(null, appId, userId,
12742                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12743                        reason != null ? reason : "kill uid");
12744            } finally {
12745                Binder.restoreCallingIdentity(identity);
12746            }
12747        }
12748    }
12749
12750    @Override
12751    public boolean killProcessesBelowForeground(String reason) {
12752        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12753            throw new SecurityException("killProcessesBelowForeground() only available to system");
12754        }
12755
12756        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12757    }
12758
12759    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12760        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12761            throw new SecurityException("killProcessesBelowAdj() only available to system");
12762        }
12763
12764        boolean killed = false;
12765        synchronized (mPidsSelfLocked) {
12766            final int size = mPidsSelfLocked.size();
12767            for (int i = 0; i < size; i++) {
12768                final int pid = mPidsSelfLocked.keyAt(i);
12769                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12770                if (proc == null) continue;
12771
12772                final int adj = proc.setAdj;
12773                if (adj > belowAdj && !proc.killedByAm) {
12774                    proc.kill(reason, true);
12775                    killed = true;
12776                }
12777            }
12778        }
12779        return killed;
12780    }
12781
12782    @Override
12783    public void hang(final IBinder who, boolean allowRestart) {
12784        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12785                != PackageManager.PERMISSION_GRANTED) {
12786            throw new SecurityException("Requires permission "
12787                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12788        }
12789
12790        final IBinder.DeathRecipient death = new DeathRecipient() {
12791            @Override
12792            public void binderDied() {
12793                synchronized (this) {
12794                    notifyAll();
12795                }
12796            }
12797        };
12798
12799        try {
12800            who.linkToDeath(death, 0);
12801        } catch (RemoteException e) {
12802            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12803            return;
12804        }
12805
12806        synchronized (this) {
12807            Watchdog.getInstance().setAllowRestart(allowRestart);
12808            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12809            synchronized (death) {
12810                while (who.isBinderAlive()) {
12811                    try {
12812                        death.wait();
12813                    } catch (InterruptedException e) {
12814                    }
12815                }
12816            }
12817            Watchdog.getInstance().setAllowRestart(true);
12818        }
12819    }
12820
12821    @Override
12822    public void restart() {
12823        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12824                != PackageManager.PERMISSION_GRANTED) {
12825            throw new SecurityException("Requires permission "
12826                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12827        }
12828
12829        Log.i(TAG, "Sending shutdown broadcast...");
12830
12831        BroadcastReceiver br = new BroadcastReceiver() {
12832            @Override public void onReceive(Context context, Intent intent) {
12833                // Now the broadcast is done, finish up the low-level shutdown.
12834                Log.i(TAG, "Shutting down activity manager...");
12835                shutdown(10000);
12836                Log.i(TAG, "Shutdown complete, restarting!");
12837                Process.killProcess(Process.myPid());
12838                System.exit(10);
12839            }
12840        };
12841
12842        // First send the high-level shut down broadcast.
12843        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12844        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12845        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12846        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12847        mContext.sendOrderedBroadcastAsUser(intent,
12848                UserHandle.ALL, null, br, mHandler, 0, null, null);
12849        */
12850        br.onReceive(mContext, intent);
12851    }
12852
12853    private long getLowRamTimeSinceIdle(long now) {
12854        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12855    }
12856
12857    @Override
12858    public void performIdleMaintenance() {
12859        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12860                != PackageManager.PERMISSION_GRANTED) {
12861            throw new SecurityException("Requires permission "
12862                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12863        }
12864
12865        synchronized (this) {
12866            final long now = SystemClock.uptimeMillis();
12867            final long timeSinceLastIdle = now - mLastIdleTime;
12868            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12869            mLastIdleTime = now;
12870            mLowRamTimeSinceLastIdle = 0;
12871            if (mLowRamStartTime != 0) {
12872                mLowRamStartTime = now;
12873            }
12874
12875            StringBuilder sb = new StringBuilder(128);
12876            sb.append("Idle maintenance over ");
12877            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12878            sb.append(" low RAM for ");
12879            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12880            Slog.i(TAG, sb.toString());
12881
12882            // If at least 1/3 of our time since the last idle period has been spent
12883            // with RAM low, then we want to kill processes.
12884            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12885
12886            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12887                ProcessRecord proc = mLruProcesses.get(i);
12888                if (proc.notCachedSinceIdle) {
12889                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12890                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12891                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12892                        if (doKilling && proc.initialIdlePss != 0
12893                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12894                            sb = new StringBuilder(128);
12895                            sb.append("Kill");
12896                            sb.append(proc.processName);
12897                            sb.append(" in idle maint: pss=");
12898                            sb.append(proc.lastPss);
12899                            sb.append(", swapPss=");
12900                            sb.append(proc.lastSwapPss);
12901                            sb.append(", initialPss=");
12902                            sb.append(proc.initialIdlePss);
12903                            sb.append(", period=");
12904                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12905                            sb.append(", lowRamPeriod=");
12906                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12907                            Slog.wtfQuiet(TAG, sb.toString());
12908                            proc.kill("idle maint (pss " + proc.lastPss
12909                                    + " from " + proc.initialIdlePss + ")", true);
12910                        }
12911                    }
12912                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12913                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12914                    proc.notCachedSinceIdle = true;
12915                    proc.initialIdlePss = 0;
12916                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12917                            mTestPssMode, isSleepingLocked(), now);
12918                }
12919            }
12920
12921            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12922            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12923        }
12924    }
12925
12926    @Override
12927    public void sendIdleJobTrigger() {
12928        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12929                != PackageManager.PERMISSION_GRANTED) {
12930            throw new SecurityException("Requires permission "
12931                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12932        }
12933
12934        final long ident = Binder.clearCallingIdentity();
12935        try {
12936            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12937                    .setPackage("android")
12938                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12939            broadcastIntent(null, intent, null, null, 0, null, null, null,
12940                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12941        } finally {
12942            Binder.restoreCallingIdentity(ident);
12943        }
12944    }
12945
12946    private void retrieveSettings() {
12947        final ContentResolver resolver = mContext.getContentResolver();
12948        final boolean freeformWindowManagement =
12949                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12950                        || Settings.Global.getInt(
12951                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12952        final boolean supportsPictureInPicture =
12953                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12954
12955        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12956        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12957        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12958        final boolean alwaysFinishActivities =
12959                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12960        final boolean lenientBackgroundCheck =
12961                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12962        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12963        final boolean forceResizable = Settings.Global.getInt(
12964                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12965        final boolean supportsLeanbackOnly =
12966                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12967
12968        // Transfer any global setting for forcing RTL layout, into a System Property
12969        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12970
12971        final Configuration configuration = new Configuration();
12972        Settings.System.getConfiguration(resolver, configuration);
12973        if (forceRtl) {
12974            // This will take care of setting the correct layout direction flags
12975            configuration.setLayoutDirection(configuration.locale);
12976        }
12977
12978        synchronized (this) {
12979            mDebugApp = mOrigDebugApp = debugApp;
12980            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12981            mAlwaysFinishActivities = alwaysFinishActivities;
12982            mLenientBackgroundCheck = lenientBackgroundCheck;
12983            mSupportsLeanbackOnly = supportsLeanbackOnly;
12984            mForceResizableActivities = forceResizable;
12985            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12986            if (supportsMultiWindow || forceResizable) {
12987                mSupportsMultiWindow = true;
12988                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12989                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12990            } else {
12991                mSupportsMultiWindow = false;
12992                mSupportsFreeformWindowManagement = false;
12993                mSupportsPictureInPicture = false;
12994            }
12995            // This happens before any activities are started, so we can
12996            // change mConfiguration in-place.
12997            updateConfigurationLocked(configuration, null, true);
12998            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12999                    "Initial config: " + mConfiguration);
13000
13001            // Load resources only after the current configuration has been set.
13002            final Resources res = mContext.getResources();
13003            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13004            mThumbnailWidth = res.getDimensionPixelSize(
13005                    com.android.internal.R.dimen.thumbnail_width);
13006            mThumbnailHeight = res.getDimensionPixelSize(
13007                    com.android.internal.R.dimen.thumbnail_height);
13008            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13009                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13010            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13011                    com.android.internal.R.string.config_appsNotReportingCrashes));
13012            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13013                mFullscreenThumbnailScale = (float) res
13014                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13015                    (float) mConfiguration.screenWidthDp;
13016            } else {
13017                mFullscreenThumbnailScale = res.getFraction(
13018                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13019            }
13020        }
13021    }
13022
13023    public boolean testIsSystemReady() {
13024        // no need to synchronize(this) just to read & return the value
13025        return mSystemReady;
13026    }
13027
13028    public void systemReady(final Runnable goingCallback) {
13029        synchronized(this) {
13030            if (mSystemReady) {
13031                // If we're done calling all the receivers, run the next "boot phase" passed in
13032                // by the SystemServer
13033                if (goingCallback != null) {
13034                    goingCallback.run();
13035                }
13036                return;
13037            }
13038
13039            mLocalDeviceIdleController
13040                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13041
13042            // Make sure we have the current profile info, since it is needed for security checks.
13043            mUserController.onSystemReady();
13044            mRecentTasks.onSystemReadyLocked();
13045            mAppOpsService.systemReady();
13046            mSystemReady = true;
13047        }
13048
13049        ArrayList<ProcessRecord> procsToKill = null;
13050        synchronized(mPidsSelfLocked) {
13051            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13052                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13053                if (!isAllowedWhileBooting(proc.info)){
13054                    if (procsToKill == null) {
13055                        procsToKill = new ArrayList<ProcessRecord>();
13056                    }
13057                    procsToKill.add(proc);
13058                }
13059            }
13060        }
13061
13062        synchronized(this) {
13063            if (procsToKill != null) {
13064                for (int i=procsToKill.size()-1; i>=0; i--) {
13065                    ProcessRecord proc = procsToKill.get(i);
13066                    Slog.i(TAG, "Removing system update proc: " + proc);
13067                    removeProcessLocked(proc, true, false, "system update done");
13068                }
13069            }
13070
13071            // Now that we have cleaned up any update processes, we
13072            // are ready to start launching real processes and know that
13073            // we won't trample on them any more.
13074            mProcessesReady = true;
13075        }
13076
13077        Slog.i(TAG, "System now ready");
13078        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13079            SystemClock.uptimeMillis());
13080
13081        synchronized(this) {
13082            // Make sure we have no pre-ready processes sitting around.
13083
13084            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13085                ResolveInfo ri = mContext.getPackageManager()
13086                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13087                                STOCK_PM_FLAGS);
13088                CharSequence errorMsg = null;
13089                if (ri != null) {
13090                    ActivityInfo ai = ri.activityInfo;
13091                    ApplicationInfo app = ai.applicationInfo;
13092                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13093                        mTopAction = Intent.ACTION_FACTORY_TEST;
13094                        mTopData = null;
13095                        mTopComponent = new ComponentName(app.packageName,
13096                                ai.name);
13097                    } else {
13098                        errorMsg = mContext.getResources().getText(
13099                                com.android.internal.R.string.factorytest_not_system);
13100                    }
13101                } else {
13102                    errorMsg = mContext.getResources().getText(
13103                            com.android.internal.R.string.factorytest_no_action);
13104                }
13105                if (errorMsg != null) {
13106                    mTopAction = null;
13107                    mTopData = null;
13108                    mTopComponent = null;
13109                    Message msg = Message.obtain();
13110                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13111                    msg.getData().putCharSequence("msg", errorMsg);
13112                    mUiHandler.sendMessage(msg);
13113                }
13114            }
13115        }
13116
13117        retrieveSettings();
13118        final int currentUserId;
13119        synchronized (this) {
13120            currentUserId = mUserController.getCurrentUserIdLocked();
13121            readGrantedUriPermissionsLocked();
13122        }
13123
13124        if (goingCallback != null) goingCallback.run();
13125
13126        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13127                Integer.toString(currentUserId), currentUserId);
13128        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13129                Integer.toString(currentUserId), currentUserId);
13130        mSystemServiceManager.startUser(currentUserId);
13131
13132        synchronized (this) {
13133            // Only start up encryption-aware persistent apps; once user is
13134            // unlocked we'll come back around and start unaware apps
13135            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13136
13137            // Start up initial activity.
13138            mBooting = true;
13139            // Enable home activity for system user, so that the system can always boot
13140            if (UserManager.isSplitSystemUser()) {
13141                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13142                try {
13143                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13144                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13145                            UserHandle.USER_SYSTEM);
13146                } catch (RemoteException e) {
13147                    throw e.rethrowAsRuntimeException();
13148                }
13149            }
13150            startHomeActivityLocked(currentUserId, "systemReady");
13151
13152            try {
13153                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13154                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13155                            + " data partition or your device will be unstable.");
13156                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13157                }
13158            } catch (RemoteException e) {
13159            }
13160
13161            if (!Build.isBuildConsistent()) {
13162                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13163                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13164            }
13165
13166            long ident = Binder.clearCallingIdentity();
13167            try {
13168                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13169                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13170                        | Intent.FLAG_RECEIVER_FOREGROUND);
13171                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13172                broadcastIntentLocked(null, null, intent,
13173                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13174                        null, false, false, MY_PID, Process.SYSTEM_UID,
13175                        currentUserId);
13176                intent = new Intent(Intent.ACTION_USER_STARTING);
13177                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13178                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13179                broadcastIntentLocked(null, null, intent,
13180                        null, new IIntentReceiver.Stub() {
13181                            @Override
13182                            public void performReceive(Intent intent, int resultCode, String data,
13183                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13184                                    throws RemoteException {
13185                            }
13186                        }, 0, null, null,
13187                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13188                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13189            } catch (Throwable t) {
13190                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13191            } finally {
13192                Binder.restoreCallingIdentity(ident);
13193            }
13194            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13195            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13196        }
13197    }
13198
13199    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13200        synchronized (this) {
13201            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13202        }
13203    }
13204
13205    void skipCurrentReceiverLocked(ProcessRecord app) {
13206        for (BroadcastQueue queue : mBroadcastQueues) {
13207            queue.skipCurrentReceiverLocked(app);
13208        }
13209    }
13210
13211    /**
13212     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13213     * The application process will exit immediately after this call returns.
13214     * @param app object of the crashing app, null for the system server
13215     * @param crashInfo describing the exception
13216     */
13217    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13218        ProcessRecord r = findAppProcess(app, "Crash");
13219        final String processName = app == null ? "system_server"
13220                : (r == null ? "unknown" : r.processName);
13221
13222        handleApplicationCrashInner("crash", r, processName, crashInfo);
13223    }
13224
13225    /* Native crash reporting uses this inner version because it needs to be somewhat
13226     * decoupled from the AM-managed cleanup lifecycle
13227     */
13228    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13229            ApplicationErrorReport.CrashInfo crashInfo) {
13230        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13231                UserHandle.getUserId(Binder.getCallingUid()), processName,
13232                r == null ? -1 : r.info.flags,
13233                crashInfo.exceptionClassName,
13234                crashInfo.exceptionMessage,
13235                crashInfo.throwFileName,
13236                crashInfo.throwLineNumber);
13237
13238        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13239
13240        mAppErrors.crashApplication(r, crashInfo);
13241    }
13242
13243    public void handleApplicationStrictModeViolation(
13244            IBinder app,
13245            int violationMask,
13246            StrictMode.ViolationInfo info) {
13247        ProcessRecord r = findAppProcess(app, "StrictMode");
13248        if (r == null) {
13249            return;
13250        }
13251
13252        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13253            Integer stackFingerprint = info.hashCode();
13254            boolean logIt = true;
13255            synchronized (mAlreadyLoggedViolatedStacks) {
13256                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13257                    logIt = false;
13258                    // TODO: sub-sample into EventLog for these, with
13259                    // the info.durationMillis?  Then we'd get
13260                    // the relative pain numbers, without logging all
13261                    // the stack traces repeatedly.  We'd want to do
13262                    // likewise in the client code, which also does
13263                    // dup suppression, before the Binder call.
13264                } else {
13265                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13266                        mAlreadyLoggedViolatedStacks.clear();
13267                    }
13268                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13269                }
13270            }
13271            if (logIt) {
13272                logStrictModeViolationToDropBox(r, info);
13273            }
13274        }
13275
13276        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13277            AppErrorResult result = new AppErrorResult();
13278            synchronized (this) {
13279                final long origId = Binder.clearCallingIdentity();
13280
13281                Message msg = Message.obtain();
13282                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13283                HashMap<String, Object> data = new HashMap<String, Object>();
13284                data.put("result", result);
13285                data.put("app", r);
13286                data.put("violationMask", violationMask);
13287                data.put("info", info);
13288                msg.obj = data;
13289                mUiHandler.sendMessage(msg);
13290
13291                Binder.restoreCallingIdentity(origId);
13292            }
13293            int res = result.get();
13294            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13295        }
13296    }
13297
13298    // Depending on the policy in effect, there could be a bunch of
13299    // these in quick succession so we try to batch these together to
13300    // minimize disk writes, number of dropbox entries, and maximize
13301    // compression, by having more fewer, larger records.
13302    private void logStrictModeViolationToDropBox(
13303            ProcessRecord process,
13304            StrictMode.ViolationInfo info) {
13305        if (info == null) {
13306            return;
13307        }
13308        final boolean isSystemApp = process == null ||
13309                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13310                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13311        final String processName = process == null ? "unknown" : process.processName;
13312        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13313        final DropBoxManager dbox = (DropBoxManager)
13314                mContext.getSystemService(Context.DROPBOX_SERVICE);
13315
13316        // Exit early if the dropbox isn't configured to accept this report type.
13317        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13318
13319        boolean bufferWasEmpty;
13320        boolean needsFlush;
13321        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13322        synchronized (sb) {
13323            bufferWasEmpty = sb.length() == 0;
13324            appendDropBoxProcessHeaders(process, processName, sb);
13325            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13326            sb.append("System-App: ").append(isSystemApp).append("\n");
13327            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13328            if (info.violationNumThisLoop != 0) {
13329                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13330            }
13331            if (info.numAnimationsRunning != 0) {
13332                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13333            }
13334            if (info.broadcastIntentAction != null) {
13335                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13336            }
13337            if (info.durationMillis != -1) {
13338                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13339            }
13340            if (info.numInstances != -1) {
13341                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13342            }
13343            if (info.tags != null) {
13344                for (String tag : info.tags) {
13345                    sb.append("Span-Tag: ").append(tag).append("\n");
13346                }
13347            }
13348            sb.append("\n");
13349            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13350                sb.append(info.crashInfo.stackTrace);
13351                sb.append("\n");
13352            }
13353            if (info.message != null) {
13354                sb.append(info.message);
13355                sb.append("\n");
13356            }
13357
13358            // Only buffer up to ~64k.  Various logging bits truncate
13359            // things at 128k.
13360            needsFlush = (sb.length() > 64 * 1024);
13361        }
13362
13363        // Flush immediately if the buffer's grown too large, or this
13364        // is a non-system app.  Non-system apps are isolated with a
13365        // different tag & policy and not batched.
13366        //
13367        // Batching is useful during internal testing with
13368        // StrictMode settings turned up high.  Without batching,
13369        // thousands of separate files could be created on boot.
13370        if (!isSystemApp || needsFlush) {
13371            new Thread("Error dump: " + dropboxTag) {
13372                @Override
13373                public void run() {
13374                    String report;
13375                    synchronized (sb) {
13376                        report = sb.toString();
13377                        sb.delete(0, sb.length());
13378                        sb.trimToSize();
13379                    }
13380                    if (report.length() != 0) {
13381                        dbox.addText(dropboxTag, report);
13382                    }
13383                }
13384            }.start();
13385            return;
13386        }
13387
13388        // System app batching:
13389        if (!bufferWasEmpty) {
13390            // An existing dropbox-writing thread is outstanding, so
13391            // we don't need to start it up.  The existing thread will
13392            // catch the buffer appends we just did.
13393            return;
13394        }
13395
13396        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13397        // (After this point, we shouldn't access AMS internal data structures.)
13398        new Thread("Error dump: " + dropboxTag) {
13399            @Override
13400            public void run() {
13401                // 5 second sleep to let stacks arrive and be batched together
13402                try {
13403                    Thread.sleep(5000);  // 5 seconds
13404                } catch (InterruptedException e) {}
13405
13406                String errorReport;
13407                synchronized (mStrictModeBuffer) {
13408                    errorReport = mStrictModeBuffer.toString();
13409                    if (errorReport.length() == 0) {
13410                        return;
13411                    }
13412                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13413                    mStrictModeBuffer.trimToSize();
13414                }
13415                dbox.addText(dropboxTag, errorReport);
13416            }
13417        }.start();
13418    }
13419
13420    /**
13421     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13422     * @param app object of the crashing app, null for the system server
13423     * @param tag reported by the caller
13424     * @param system whether this wtf is coming from the system
13425     * @param crashInfo describing the context of the error
13426     * @return true if the process should exit immediately (WTF is fatal)
13427     */
13428    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13429            final ApplicationErrorReport.CrashInfo crashInfo) {
13430        final int callingUid = Binder.getCallingUid();
13431        final int callingPid = Binder.getCallingPid();
13432
13433        if (system) {
13434            // If this is coming from the system, we could very well have low-level
13435            // system locks held, so we want to do this all asynchronously.  And we
13436            // never want this to become fatal, so there is that too.
13437            mHandler.post(new Runnable() {
13438                @Override public void run() {
13439                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13440                }
13441            });
13442            return false;
13443        }
13444
13445        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13446                crashInfo);
13447
13448        if (r != null && r.pid != Process.myPid() &&
13449                Settings.Global.getInt(mContext.getContentResolver(),
13450                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13451            mAppErrors.crashApplication(r, crashInfo);
13452            return true;
13453        } else {
13454            return false;
13455        }
13456    }
13457
13458    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13459            final ApplicationErrorReport.CrashInfo crashInfo) {
13460        final ProcessRecord r = findAppProcess(app, "WTF");
13461        final String processName = app == null ? "system_server"
13462                : (r == null ? "unknown" : r.processName);
13463
13464        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13465                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13466
13467        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13468
13469        return r;
13470    }
13471
13472    /**
13473     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13474     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13475     */
13476    private ProcessRecord findAppProcess(IBinder app, String reason) {
13477        if (app == null) {
13478            return null;
13479        }
13480
13481        synchronized (this) {
13482            final int NP = mProcessNames.getMap().size();
13483            for (int ip=0; ip<NP; ip++) {
13484                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13485                final int NA = apps.size();
13486                for (int ia=0; ia<NA; ia++) {
13487                    ProcessRecord p = apps.valueAt(ia);
13488                    if (p.thread != null && p.thread.asBinder() == app) {
13489                        return p;
13490                    }
13491                }
13492            }
13493
13494            Slog.w(TAG, "Can't find mystery application for " + reason
13495                    + " from pid=" + Binder.getCallingPid()
13496                    + " uid=" + Binder.getCallingUid() + ": " + app);
13497            return null;
13498        }
13499    }
13500
13501    /**
13502     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13503     * to append various headers to the dropbox log text.
13504     */
13505    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13506            StringBuilder sb) {
13507        // Watchdog thread ends up invoking this function (with
13508        // a null ProcessRecord) to add the stack file to dropbox.
13509        // Do not acquire a lock on this (am) in such cases, as it
13510        // could cause a potential deadlock, if and when watchdog
13511        // is invoked due to unavailability of lock on am and it
13512        // would prevent watchdog from killing system_server.
13513        if (process == null) {
13514            sb.append("Process: ").append(processName).append("\n");
13515            return;
13516        }
13517        // Note: ProcessRecord 'process' is guarded by the service
13518        // instance.  (notably process.pkgList, which could otherwise change
13519        // concurrently during execution of this method)
13520        synchronized (this) {
13521            sb.append("Process: ").append(processName).append("\n");
13522            int flags = process.info.flags;
13523            IPackageManager pm = AppGlobals.getPackageManager();
13524            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13525            for (int ip=0; ip<process.pkgList.size(); ip++) {
13526                String pkg = process.pkgList.keyAt(ip);
13527                sb.append("Package: ").append(pkg);
13528                try {
13529                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13530                    if (pi != null) {
13531                        sb.append(" v").append(pi.versionCode);
13532                        if (pi.versionName != null) {
13533                            sb.append(" (").append(pi.versionName).append(")");
13534                        }
13535                    }
13536                } catch (RemoteException e) {
13537                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13538                }
13539                sb.append("\n");
13540            }
13541        }
13542    }
13543
13544    private static String processClass(ProcessRecord process) {
13545        if (process == null || process.pid == MY_PID) {
13546            return "system_server";
13547        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13548            return "system_app";
13549        } else {
13550            return "data_app";
13551        }
13552    }
13553
13554    private volatile long mWtfClusterStart;
13555    private volatile int mWtfClusterCount;
13556
13557    /**
13558     * Write a description of an error (crash, WTF, ANR) to the drop box.
13559     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13560     * @param process which caused the error, null means the system server
13561     * @param activity which triggered the error, null if unknown
13562     * @param parent activity related to the error, null if unknown
13563     * @param subject line related to the error, null if absent
13564     * @param report in long form describing the error, null if absent
13565     * @param dataFile text file to include in the report, null if none
13566     * @param crashInfo giving an application stack trace, null if absent
13567     */
13568    public void addErrorToDropBox(String eventType,
13569            ProcessRecord process, String processName, ActivityRecord activity,
13570            ActivityRecord parent, String subject,
13571            final String report, final File dataFile,
13572            final ApplicationErrorReport.CrashInfo crashInfo) {
13573        // NOTE -- this must never acquire the ActivityManagerService lock,
13574        // otherwise the watchdog may be prevented from resetting the system.
13575
13576        final String dropboxTag = processClass(process) + "_" + eventType;
13577        final DropBoxManager dbox = (DropBoxManager)
13578                mContext.getSystemService(Context.DROPBOX_SERVICE);
13579
13580        // Exit early if the dropbox isn't configured to accept this report type.
13581        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13582
13583        // Rate-limit how often we're willing to do the heavy lifting below to
13584        // collect and record logs; currently 5 logs per 10 second period.
13585        final long now = SystemClock.elapsedRealtime();
13586        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13587            mWtfClusterStart = now;
13588            mWtfClusterCount = 1;
13589        } else {
13590            if (mWtfClusterCount++ >= 5) return;
13591        }
13592
13593        final StringBuilder sb = new StringBuilder(1024);
13594        appendDropBoxProcessHeaders(process, processName, sb);
13595        if (process != null) {
13596            sb.append("Foreground: ")
13597                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13598                    .append("\n");
13599        }
13600        if (activity != null) {
13601            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13602        }
13603        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13604            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13605        }
13606        if (parent != null && parent != activity) {
13607            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13608        }
13609        if (subject != null) {
13610            sb.append("Subject: ").append(subject).append("\n");
13611        }
13612        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13613        if (Debug.isDebuggerConnected()) {
13614            sb.append("Debugger: Connected\n");
13615        }
13616        sb.append("\n");
13617
13618        // Do the rest in a worker thread to avoid blocking the caller on I/O
13619        // (After this point, we shouldn't access AMS internal data structures.)
13620        Thread worker = new Thread("Error dump: " + dropboxTag) {
13621            @Override
13622            public void run() {
13623                if (report != null) {
13624                    sb.append(report);
13625                }
13626
13627                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13628                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13629                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13630                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13631
13632                if (dataFile != null && maxDataFileSize > 0) {
13633                    try {
13634                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13635                                    "\n\n[[TRUNCATED]]"));
13636                    } catch (IOException e) {
13637                        Slog.e(TAG, "Error reading " + dataFile, e);
13638                    }
13639                }
13640                if (crashInfo != null && crashInfo.stackTrace != null) {
13641                    sb.append(crashInfo.stackTrace);
13642                }
13643
13644                if (lines > 0) {
13645                    sb.append("\n");
13646
13647                    // Merge several logcat streams, and take the last N lines
13648                    InputStreamReader input = null;
13649                    try {
13650                        java.lang.Process logcat = new ProcessBuilder(
13651                                "/system/bin/timeout", "-k", "15s", "10s",
13652                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13653                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13654                                        .redirectErrorStream(true).start();
13655
13656                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13657                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13658                        input = new InputStreamReader(logcat.getInputStream());
13659
13660                        int num;
13661                        char[] buf = new char[8192];
13662                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13663                    } catch (IOException e) {
13664                        Slog.e(TAG, "Error running logcat", e);
13665                    } finally {
13666                        if (input != null) try { input.close(); } catch (IOException e) {}
13667                    }
13668                }
13669
13670                dbox.addText(dropboxTag, sb.toString());
13671            }
13672        };
13673
13674        if (process == null) {
13675            // If process is null, we are being called from some internal code
13676            // and may be about to die -- run this synchronously.
13677            worker.run();
13678        } else {
13679            worker.start();
13680        }
13681    }
13682
13683    @Override
13684    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13685        enforceNotIsolatedCaller("getProcessesInErrorState");
13686        // assume our apps are happy - lazy create the list
13687        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13688
13689        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13690                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13691        int userId = UserHandle.getUserId(Binder.getCallingUid());
13692
13693        synchronized (this) {
13694
13695            // iterate across all processes
13696            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13697                ProcessRecord app = mLruProcesses.get(i);
13698                if (!allUsers && app.userId != userId) {
13699                    continue;
13700                }
13701                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13702                    // This one's in trouble, so we'll generate a report for it
13703                    // crashes are higher priority (in case there's a crash *and* an anr)
13704                    ActivityManager.ProcessErrorStateInfo report = null;
13705                    if (app.crashing) {
13706                        report = app.crashingReport;
13707                    } else if (app.notResponding) {
13708                        report = app.notRespondingReport;
13709                    }
13710
13711                    if (report != null) {
13712                        if (errList == null) {
13713                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13714                        }
13715                        errList.add(report);
13716                    } else {
13717                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13718                                " crashing = " + app.crashing +
13719                                " notResponding = " + app.notResponding);
13720                    }
13721                }
13722            }
13723        }
13724
13725        return errList;
13726    }
13727
13728    static int procStateToImportance(int procState, int memAdj,
13729            ActivityManager.RunningAppProcessInfo currApp) {
13730        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13731        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13732            currApp.lru = memAdj;
13733        } else {
13734            currApp.lru = 0;
13735        }
13736        return imp;
13737    }
13738
13739    private void fillInProcMemInfo(ProcessRecord app,
13740            ActivityManager.RunningAppProcessInfo outInfo) {
13741        outInfo.pid = app.pid;
13742        outInfo.uid = app.info.uid;
13743        if (mHeavyWeightProcess == app) {
13744            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13745        }
13746        if (app.persistent) {
13747            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13748        }
13749        if (app.activities.size() > 0) {
13750            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13751        }
13752        outInfo.lastTrimLevel = app.trimMemoryLevel;
13753        int adj = app.curAdj;
13754        int procState = app.curProcState;
13755        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13756        outInfo.importanceReasonCode = app.adjTypeCode;
13757        outInfo.processState = app.curProcState;
13758    }
13759
13760    @Override
13761    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13762        enforceNotIsolatedCaller("getRunningAppProcesses");
13763
13764        final int callingUid = Binder.getCallingUid();
13765
13766        // Lazy instantiation of list
13767        List<ActivityManager.RunningAppProcessInfo> runList = null;
13768        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13769                callingUid) == PackageManager.PERMISSION_GRANTED;
13770        final int userId = UserHandle.getUserId(callingUid);
13771        final boolean allUids = isGetTasksAllowed(
13772                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13773
13774        synchronized (this) {
13775            // Iterate across all processes
13776            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13777                ProcessRecord app = mLruProcesses.get(i);
13778                if ((!allUsers && app.userId != userId)
13779                        || (!allUids && app.uid != callingUid)) {
13780                    continue;
13781                }
13782                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13783                    // Generate process state info for running application
13784                    ActivityManager.RunningAppProcessInfo currApp =
13785                        new ActivityManager.RunningAppProcessInfo(app.processName,
13786                                app.pid, app.getPackageList());
13787                    fillInProcMemInfo(app, currApp);
13788                    if (app.adjSource instanceof ProcessRecord) {
13789                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13790                        currApp.importanceReasonImportance =
13791                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13792                                        app.adjSourceProcState);
13793                    } else if (app.adjSource instanceof ActivityRecord) {
13794                        ActivityRecord r = (ActivityRecord)app.adjSource;
13795                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13796                    }
13797                    if (app.adjTarget instanceof ComponentName) {
13798                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13799                    }
13800                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13801                    //        + " lru=" + currApp.lru);
13802                    if (runList == null) {
13803                        runList = new ArrayList<>();
13804                    }
13805                    runList.add(currApp);
13806                }
13807            }
13808        }
13809        return runList;
13810    }
13811
13812    @Override
13813    public List<ApplicationInfo> getRunningExternalApplications() {
13814        enforceNotIsolatedCaller("getRunningExternalApplications");
13815        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13816        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13817        if (runningApps != null && runningApps.size() > 0) {
13818            Set<String> extList = new HashSet<String>();
13819            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13820                if (app.pkgList != null) {
13821                    for (String pkg : app.pkgList) {
13822                        extList.add(pkg);
13823                    }
13824                }
13825            }
13826            IPackageManager pm = AppGlobals.getPackageManager();
13827            for (String pkg : extList) {
13828                try {
13829                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13830                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13831                        retList.add(info);
13832                    }
13833                } catch (RemoteException e) {
13834                }
13835            }
13836        }
13837        return retList;
13838    }
13839
13840    @Override
13841    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13842        enforceNotIsolatedCaller("getMyMemoryState");
13843        synchronized (this) {
13844            ProcessRecord proc;
13845            synchronized (mPidsSelfLocked) {
13846                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13847            }
13848            fillInProcMemInfo(proc, outInfo);
13849        }
13850    }
13851
13852    @Override
13853    public int getMemoryTrimLevel() {
13854        enforceNotIsolatedCaller("getMyMemoryState");
13855        synchronized (this) {
13856            return mLastMemoryLevel;
13857        }
13858    }
13859
13860    @Override
13861    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13862            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13863        (new ActivityManagerShellCommand(this, false)).exec(
13864                this, in, out, err, args, resultReceiver);
13865    }
13866
13867    @Override
13868    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13869        if (checkCallingPermission(android.Manifest.permission.DUMP)
13870                != PackageManager.PERMISSION_GRANTED) {
13871            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13872                    + Binder.getCallingPid()
13873                    + ", uid=" + Binder.getCallingUid()
13874                    + " without permission "
13875                    + android.Manifest.permission.DUMP);
13876            return;
13877        }
13878
13879        boolean dumpAll = false;
13880        boolean dumpClient = false;
13881        boolean dumpCheckin = false;
13882        boolean dumpCheckinFormat = false;
13883        String dumpPackage = null;
13884
13885        int opti = 0;
13886        while (opti < args.length) {
13887            String opt = args[opti];
13888            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13889                break;
13890            }
13891            opti++;
13892            if ("-a".equals(opt)) {
13893                dumpAll = true;
13894            } else if ("-c".equals(opt)) {
13895                dumpClient = true;
13896            } else if ("-p".equals(opt)) {
13897                if (opti < args.length) {
13898                    dumpPackage = args[opti];
13899                    opti++;
13900                } else {
13901                    pw.println("Error: -p option requires package argument");
13902                    return;
13903                }
13904                dumpClient = true;
13905            } else if ("--checkin".equals(opt)) {
13906                dumpCheckin = dumpCheckinFormat = true;
13907            } else if ("-C".equals(opt)) {
13908                dumpCheckinFormat = true;
13909            } else if ("-h".equals(opt)) {
13910                ActivityManagerShellCommand.dumpHelp(pw, true);
13911                return;
13912            } else {
13913                pw.println("Unknown argument: " + opt + "; use -h for help");
13914            }
13915        }
13916
13917        long origId = Binder.clearCallingIdentity();
13918        boolean more = false;
13919        // Is the caller requesting to dump a particular piece of data?
13920        if (opti < args.length) {
13921            String cmd = args[opti];
13922            opti++;
13923            if ("activities".equals(cmd) || "a".equals(cmd)) {
13924                synchronized (this) {
13925                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13926                }
13927            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13928                synchronized (this) {
13929                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13930                }
13931            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13932                String[] newArgs;
13933                String name;
13934                if (opti >= args.length) {
13935                    name = null;
13936                    newArgs = EMPTY_STRING_ARRAY;
13937                } else {
13938                    dumpPackage = args[opti];
13939                    opti++;
13940                    newArgs = new String[args.length - opti];
13941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13942                            args.length - opti);
13943                }
13944                synchronized (this) {
13945                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13946                }
13947            } else if ("broadcast-stats".equals(cmd)) {
13948                String[] newArgs;
13949                String name;
13950                if (opti >= args.length) {
13951                    name = null;
13952                    newArgs = EMPTY_STRING_ARRAY;
13953                } else {
13954                    dumpPackage = args[opti];
13955                    opti++;
13956                    newArgs = new String[args.length - opti];
13957                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13958                            args.length - opti);
13959                }
13960                synchronized (this) {
13961                    if (dumpCheckinFormat) {
13962                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13963                                dumpPackage);
13964                    } else {
13965                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13966                    }
13967                }
13968            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13969                String[] newArgs;
13970                String name;
13971                if (opti >= args.length) {
13972                    name = null;
13973                    newArgs = EMPTY_STRING_ARRAY;
13974                } else {
13975                    dumpPackage = args[opti];
13976                    opti++;
13977                    newArgs = new String[args.length - opti];
13978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13979                            args.length - opti);
13980                }
13981                synchronized (this) {
13982                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13983                }
13984            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13985                String[] newArgs;
13986                String name;
13987                if (opti >= args.length) {
13988                    name = null;
13989                    newArgs = EMPTY_STRING_ARRAY;
13990                } else {
13991                    dumpPackage = args[opti];
13992                    opti++;
13993                    newArgs = new String[args.length - opti];
13994                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13995                            args.length - opti);
13996                }
13997                synchronized (this) {
13998                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13999                }
14000            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14001                synchronized (this) {
14002                    dumpOomLocked(fd, pw, args, opti, true);
14003                }
14004            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14005                synchronized (this) {
14006                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14007                }
14008            } else if ("provider".equals(cmd)) {
14009                String[] newArgs;
14010                String name;
14011                if (opti >= args.length) {
14012                    name = null;
14013                    newArgs = EMPTY_STRING_ARRAY;
14014                } else {
14015                    name = args[opti];
14016                    opti++;
14017                    newArgs = new String[args.length - opti];
14018                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14019                }
14020                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14021                    pw.println("No providers match: " + name);
14022                    pw.println("Use -h for help.");
14023                }
14024            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14025                synchronized (this) {
14026                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14027                }
14028            } else if ("service".equals(cmd)) {
14029                String[] newArgs;
14030                String name;
14031                if (opti >= args.length) {
14032                    name = null;
14033                    newArgs = EMPTY_STRING_ARRAY;
14034                } else {
14035                    name = args[opti];
14036                    opti++;
14037                    newArgs = new String[args.length - opti];
14038                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14039                            args.length - opti);
14040                }
14041                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14042                    pw.println("No services match: " + name);
14043                    pw.println("Use -h for help.");
14044                }
14045            } else if ("package".equals(cmd)) {
14046                String[] newArgs;
14047                if (opti >= args.length) {
14048                    pw.println("package: no package name specified");
14049                    pw.println("Use -h for help.");
14050                } else {
14051                    dumpPackage = args[opti];
14052                    opti++;
14053                    newArgs = new String[args.length - opti];
14054                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14055                            args.length - opti);
14056                    args = newArgs;
14057                    opti = 0;
14058                    more = true;
14059                }
14060            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14061                synchronized (this) {
14062                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14063                }
14064            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14065                if (dumpClient) {
14066                    ActiveServices.ServiceDumper dumper;
14067                    synchronized (this) {
14068                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14069                                dumpPackage);
14070                    }
14071                    dumper.dumpWithClient();
14072                } else {
14073                    synchronized (this) {
14074                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14075                                dumpPackage).dumpLocked();
14076                    }
14077                }
14078            } else if ("locks".equals(cmd)) {
14079                LockGuard.dump(fd, pw, args);
14080            } else {
14081                // Dumping a single activity?
14082                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14083                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14084                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14085                    if (res < 0) {
14086                        pw.println("Bad activity command, or no activities match: " + cmd);
14087                        pw.println("Use -h for help.");
14088                    }
14089                }
14090            }
14091            if (!more) {
14092                Binder.restoreCallingIdentity(origId);
14093                return;
14094            }
14095        }
14096
14097        // No piece of data specified, dump everything.
14098        if (dumpCheckinFormat) {
14099            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14100        } else if (dumpClient) {
14101            ActiveServices.ServiceDumper sdumper;
14102            synchronized (this) {
14103                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14104                pw.println();
14105                if (dumpAll) {
14106                    pw.println("-------------------------------------------------------------------------------");
14107                }
14108                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14109                pw.println();
14110                if (dumpAll) {
14111                    pw.println("-------------------------------------------------------------------------------");
14112                }
14113                if (dumpAll || dumpPackage != null) {
14114                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14115                    pw.println();
14116                    if (dumpAll) {
14117                        pw.println("-------------------------------------------------------------------------------");
14118                    }
14119                }
14120                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14121                pw.println();
14122                if (dumpAll) {
14123                    pw.println("-------------------------------------------------------------------------------");
14124                }
14125                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14126                pw.println();
14127                if (dumpAll) {
14128                    pw.println("-------------------------------------------------------------------------------");
14129                }
14130                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14131                        dumpPackage);
14132            }
14133            sdumper.dumpWithClient();
14134            pw.println();
14135            synchronized (this) {
14136                if (dumpAll) {
14137                    pw.println("-------------------------------------------------------------------------------");
14138                }
14139                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14140                pw.println();
14141                if (dumpAll) {
14142                    pw.println("-------------------------------------------------------------------------------");
14143                }
14144                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14145                if (mAssociations.size() > 0) {
14146                    pw.println();
14147                    if (dumpAll) {
14148                        pw.println("-------------------------------------------------------------------------------");
14149                    }
14150                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14151                }
14152                pw.println();
14153                if (dumpAll) {
14154                    pw.println("-------------------------------------------------------------------------------");
14155                }
14156                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14157            }
14158
14159        } else {
14160            synchronized (this) {
14161                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14162                pw.println();
14163                if (dumpAll) {
14164                    pw.println("-------------------------------------------------------------------------------");
14165                }
14166                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14167                pw.println();
14168                if (dumpAll) {
14169                    pw.println("-------------------------------------------------------------------------------");
14170                }
14171                if (dumpAll || dumpPackage != null) {
14172                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14173                    pw.println();
14174                    if (dumpAll) {
14175                        pw.println("-------------------------------------------------------------------------------");
14176                    }
14177                }
14178                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14179                pw.println();
14180                if (dumpAll) {
14181                    pw.println("-------------------------------------------------------------------------------");
14182                }
14183                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14184                pw.println();
14185                if (dumpAll) {
14186                    pw.println("-------------------------------------------------------------------------------");
14187                }
14188                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14189                        .dumpLocked();
14190                pw.println();
14191                if (dumpAll) {
14192                    pw.println("-------------------------------------------------------------------------------");
14193                }
14194                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14195                pw.println();
14196                if (dumpAll) {
14197                    pw.println("-------------------------------------------------------------------------------");
14198                }
14199                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14200                if (mAssociations.size() > 0) {
14201                    pw.println();
14202                    if (dumpAll) {
14203                        pw.println("-------------------------------------------------------------------------------");
14204                    }
14205                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14206                }
14207                pw.println();
14208                if (dumpAll) {
14209                    pw.println("-------------------------------------------------------------------------------");
14210                }
14211                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14212            }
14213        }
14214        Binder.restoreCallingIdentity(origId);
14215    }
14216
14217    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14218            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14219        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14220
14221        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14222                dumpPackage);
14223        boolean needSep = printedAnything;
14224
14225        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14226                dumpPackage, needSep, "  mFocusedActivity: ");
14227        if (printed) {
14228            printedAnything = true;
14229            needSep = false;
14230        }
14231
14232        if (dumpPackage == null) {
14233            if (needSep) {
14234                pw.println();
14235            }
14236            needSep = true;
14237            printedAnything = true;
14238            mStackSupervisor.dump(pw, "  ");
14239        }
14240
14241        if (!printedAnything) {
14242            pw.println("  (nothing)");
14243        }
14244    }
14245
14246    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14247            int opti, boolean dumpAll, String dumpPackage) {
14248        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14249
14250        boolean printedAnything = false;
14251
14252        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14253            boolean printedHeader = false;
14254
14255            final int N = mRecentTasks.size();
14256            for (int i=0; i<N; i++) {
14257                TaskRecord tr = mRecentTasks.get(i);
14258                if (dumpPackage != null) {
14259                    if (tr.realActivity == null ||
14260                            !dumpPackage.equals(tr.realActivity)) {
14261                        continue;
14262                    }
14263                }
14264                if (!printedHeader) {
14265                    pw.println("  Recent tasks:");
14266                    printedHeader = true;
14267                    printedAnything = true;
14268                }
14269                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14270                        pw.println(tr);
14271                if (dumpAll) {
14272                    mRecentTasks.get(i).dump(pw, "    ");
14273                }
14274            }
14275        }
14276
14277        if (!printedAnything) {
14278            pw.println("  (nothing)");
14279        }
14280    }
14281
14282    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14283            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14284        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14285
14286        int dumpUid = 0;
14287        if (dumpPackage != null) {
14288            IPackageManager pm = AppGlobals.getPackageManager();
14289            try {
14290                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14291            } catch (RemoteException e) {
14292            }
14293        }
14294
14295        boolean printedAnything = false;
14296
14297        final long now = SystemClock.uptimeMillis();
14298
14299        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14300            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14301                    = mAssociations.valueAt(i1);
14302            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14303                SparseArray<ArrayMap<String, Association>> sourceUids
14304                        = targetComponents.valueAt(i2);
14305                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14306                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14307                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14308                        Association ass = sourceProcesses.valueAt(i4);
14309                        if (dumpPackage != null) {
14310                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14311                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14312                                continue;
14313                            }
14314                        }
14315                        printedAnything = true;
14316                        pw.print("  ");
14317                        pw.print(ass.mTargetProcess);
14318                        pw.print("/");
14319                        UserHandle.formatUid(pw, ass.mTargetUid);
14320                        pw.print(" <- ");
14321                        pw.print(ass.mSourceProcess);
14322                        pw.print("/");
14323                        UserHandle.formatUid(pw, ass.mSourceUid);
14324                        pw.println();
14325                        pw.print("    via ");
14326                        pw.print(ass.mTargetComponent.flattenToShortString());
14327                        pw.println();
14328                        pw.print("    ");
14329                        long dur = ass.mTime;
14330                        if (ass.mNesting > 0) {
14331                            dur += now - ass.mStartTime;
14332                        }
14333                        TimeUtils.formatDuration(dur, pw);
14334                        pw.print(" (");
14335                        pw.print(ass.mCount);
14336                        pw.print(" times)");
14337                        pw.print("  ");
14338                        for (int i=0; i<ass.mStateTimes.length; i++) {
14339                            long amt = ass.mStateTimes[i];
14340                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14341                                amt += now - ass.mLastStateUptime;
14342                            }
14343                            if (amt != 0) {
14344                                pw.print(" ");
14345                                pw.print(ProcessList.makeProcStateString(
14346                                            i + ActivityManager.MIN_PROCESS_STATE));
14347                                pw.print("=");
14348                                TimeUtils.formatDuration(amt, pw);
14349                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14350                                    pw.print("*");
14351                                }
14352                            }
14353                        }
14354                        pw.println();
14355                        if (ass.mNesting > 0) {
14356                            pw.print("    Currently active: ");
14357                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14358                            pw.println();
14359                        }
14360                    }
14361                }
14362            }
14363
14364        }
14365
14366        if (!printedAnything) {
14367            pw.println("  (nothing)");
14368        }
14369    }
14370
14371    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14372            String header, boolean needSep) {
14373        boolean printed = false;
14374        int whichAppId = -1;
14375        if (dumpPackage != null) {
14376            try {
14377                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14378                        dumpPackage, 0);
14379                whichAppId = UserHandle.getAppId(info.uid);
14380            } catch (NameNotFoundException e) {
14381                e.printStackTrace();
14382            }
14383        }
14384        for (int i=0; i<uids.size(); i++) {
14385            UidRecord uidRec = uids.valueAt(i);
14386            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14387                continue;
14388            }
14389            if (!printed) {
14390                printed = true;
14391                if (needSep) {
14392                    pw.println();
14393                }
14394                pw.print("  ");
14395                pw.println(header);
14396                needSep = true;
14397            }
14398            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14399            pw.print(": "); pw.println(uidRec);
14400        }
14401        return printed;
14402    }
14403
14404    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14405            int opti, boolean dumpAll, String dumpPackage) {
14406        boolean needSep = false;
14407        boolean printedAnything = false;
14408        int numPers = 0;
14409
14410        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14411
14412        if (dumpAll) {
14413            final int NP = mProcessNames.getMap().size();
14414            for (int ip=0; ip<NP; ip++) {
14415                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14416                final int NA = procs.size();
14417                for (int ia=0; ia<NA; ia++) {
14418                    ProcessRecord r = procs.valueAt(ia);
14419                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14420                        continue;
14421                    }
14422                    if (!needSep) {
14423                        pw.println("  All known processes:");
14424                        needSep = true;
14425                        printedAnything = true;
14426                    }
14427                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14428                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14429                        pw.print(" "); pw.println(r);
14430                    r.dump(pw, "    ");
14431                    if (r.persistent) {
14432                        numPers++;
14433                    }
14434                }
14435            }
14436        }
14437
14438        if (mIsolatedProcesses.size() > 0) {
14439            boolean printed = false;
14440            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14441                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14442                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14443                    continue;
14444                }
14445                if (!printed) {
14446                    if (needSep) {
14447                        pw.println();
14448                    }
14449                    pw.println("  Isolated process list (sorted by uid):");
14450                    printedAnything = true;
14451                    printed = true;
14452                    needSep = true;
14453                }
14454                pw.println(String.format("%sIsolated #%2d: %s",
14455                        "    ", i, r.toString()));
14456            }
14457        }
14458
14459        if (mActiveUids.size() > 0) {
14460            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14461                printedAnything = needSep = true;
14462            }
14463        }
14464        if (mValidateUids.size() > 0) {
14465            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14466                printedAnything = needSep = true;
14467            }
14468        }
14469
14470        if (mLruProcesses.size() > 0) {
14471            if (needSep) {
14472                pw.println();
14473            }
14474            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14475                    pw.print(" total, non-act at ");
14476                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14477                    pw.print(", non-svc at ");
14478                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14479                    pw.println("):");
14480            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14481            needSep = true;
14482            printedAnything = true;
14483        }
14484
14485        if (dumpAll || dumpPackage != null) {
14486            synchronized (mPidsSelfLocked) {
14487                boolean printed = false;
14488                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14489                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14490                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14491                        continue;
14492                    }
14493                    if (!printed) {
14494                        if (needSep) pw.println();
14495                        needSep = true;
14496                        pw.println("  PID mappings:");
14497                        printed = true;
14498                        printedAnything = true;
14499                    }
14500                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14501                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14502                }
14503            }
14504        }
14505
14506        if (mForegroundProcesses.size() > 0) {
14507            synchronized (mPidsSelfLocked) {
14508                boolean printed = false;
14509                for (int i=0; i<mForegroundProcesses.size(); i++) {
14510                    ProcessRecord r = mPidsSelfLocked.get(
14511                            mForegroundProcesses.valueAt(i).pid);
14512                    if (dumpPackage != null && (r == null
14513                            || !r.pkgList.containsKey(dumpPackage))) {
14514                        continue;
14515                    }
14516                    if (!printed) {
14517                        if (needSep) pw.println();
14518                        needSep = true;
14519                        pw.println("  Foreground Processes:");
14520                        printed = true;
14521                        printedAnything = true;
14522                    }
14523                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14524                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14525                }
14526            }
14527        }
14528
14529        if (mPersistentStartingProcesses.size() > 0) {
14530            if (needSep) pw.println();
14531            needSep = true;
14532            printedAnything = true;
14533            pw.println("  Persisent processes that are starting:");
14534            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14535                    "Starting Norm", "Restarting PERS", dumpPackage);
14536        }
14537
14538        if (mRemovedProcesses.size() > 0) {
14539            if (needSep) pw.println();
14540            needSep = true;
14541            printedAnything = true;
14542            pw.println("  Processes that are being removed:");
14543            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14544                    "Removed Norm", "Removed PERS", dumpPackage);
14545        }
14546
14547        if (mProcessesOnHold.size() > 0) {
14548            if (needSep) pw.println();
14549            needSep = true;
14550            printedAnything = true;
14551            pw.println("  Processes that are on old until the system is ready:");
14552            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14553                    "OnHold Norm", "OnHold PERS", dumpPackage);
14554        }
14555
14556        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14557
14558        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14559        if (needSep) {
14560            printedAnything = true;
14561        }
14562
14563        if (dumpPackage == null) {
14564            pw.println();
14565            needSep = false;
14566            mUserController.dump(pw, dumpAll);
14567        }
14568        if (mHomeProcess != null && (dumpPackage == null
14569                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14570            if (needSep) {
14571                pw.println();
14572                needSep = false;
14573            }
14574            pw.println("  mHomeProcess: " + mHomeProcess);
14575        }
14576        if (mPreviousProcess != null && (dumpPackage == null
14577                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14578            if (needSep) {
14579                pw.println();
14580                needSep = false;
14581            }
14582            pw.println("  mPreviousProcess: " + mPreviousProcess);
14583        }
14584        if (dumpAll) {
14585            StringBuilder sb = new StringBuilder(128);
14586            sb.append("  mPreviousProcessVisibleTime: ");
14587            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14588            pw.println(sb);
14589        }
14590        if (mHeavyWeightProcess != null && (dumpPackage == null
14591                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14592            if (needSep) {
14593                pw.println();
14594                needSep = false;
14595            }
14596            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14597        }
14598        if (dumpPackage == null) {
14599            pw.println("  mConfiguration: " + mConfiguration);
14600        }
14601        if (dumpAll) {
14602            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14603            if (mCompatModePackages.getPackages().size() > 0) {
14604                boolean printed = false;
14605                for (Map.Entry<String, Integer> entry
14606                        : mCompatModePackages.getPackages().entrySet()) {
14607                    String pkg = entry.getKey();
14608                    int mode = entry.getValue();
14609                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14610                        continue;
14611                    }
14612                    if (!printed) {
14613                        pw.println("  mScreenCompatPackages:");
14614                        printed = true;
14615                    }
14616                    pw.print("    "); pw.print(pkg); pw.print(": ");
14617                            pw.print(mode); pw.println();
14618                }
14619            }
14620        }
14621        if (dumpPackage == null) {
14622            pw.println("  mWakefulness="
14623                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14624            pw.println("  mSleepTokens=" + mSleepTokens);
14625            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14626                    + lockScreenShownToString());
14627            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14628            if (mRunningVoice != null) {
14629                pw.println("  mRunningVoice=" + mRunningVoice);
14630                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14631            }
14632        }
14633        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14634                || mOrigWaitForDebugger) {
14635            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14636                    || dumpPackage.equals(mOrigDebugApp)) {
14637                if (needSep) {
14638                    pw.println();
14639                    needSep = false;
14640                }
14641                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14642                        + " mDebugTransient=" + mDebugTransient
14643                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14644            }
14645        }
14646        if (mCurAppTimeTracker != null) {
14647            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14648        }
14649        if (mMemWatchProcesses.getMap().size() > 0) {
14650            pw.println("  Mem watch processes:");
14651            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14652                    = mMemWatchProcesses.getMap();
14653            for (int i=0; i<procs.size(); i++) {
14654                final String proc = procs.keyAt(i);
14655                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14656                for (int j=0; j<uids.size(); j++) {
14657                    if (needSep) {
14658                        pw.println();
14659                        needSep = false;
14660                    }
14661                    StringBuilder sb = new StringBuilder();
14662                    sb.append("    ").append(proc).append('/');
14663                    UserHandle.formatUid(sb, uids.keyAt(j));
14664                    Pair<Long, String> val = uids.valueAt(j);
14665                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14666                    if (val.second != null) {
14667                        sb.append(", report to ").append(val.second);
14668                    }
14669                    pw.println(sb.toString());
14670                }
14671            }
14672            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14673            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14674            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14675                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14676        }
14677        if (mTrackAllocationApp != null) {
14678            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14679                if (needSep) {
14680                    pw.println();
14681                    needSep = false;
14682                }
14683                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14684            }
14685        }
14686        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14687                || mProfileFd != null) {
14688            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14689                if (needSep) {
14690                    pw.println();
14691                    needSep = false;
14692                }
14693                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14694                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14695                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14696                        + mAutoStopProfiler);
14697                pw.println("  mProfileType=" + mProfileType);
14698            }
14699        }
14700        if (mNativeDebuggingApp != null) {
14701            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14702                if (needSep) {
14703                    pw.println();
14704                    needSep = false;
14705                }
14706                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14707            }
14708        }
14709        if (dumpPackage == null) {
14710            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14711                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14712                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14713            }
14714            if (mController != null) {
14715                pw.println("  mController=" + mController
14716                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14717            }
14718            if (dumpAll) {
14719                pw.println("  Total persistent processes: " + numPers);
14720                pw.println("  mProcessesReady=" + mProcessesReady
14721                        + " mSystemReady=" + mSystemReady
14722                        + " mBooted=" + mBooted
14723                        + " mFactoryTest=" + mFactoryTest);
14724                pw.println("  mBooting=" + mBooting
14725                        + " mCallFinishBooting=" + mCallFinishBooting
14726                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14727                pw.print("  mLastPowerCheckRealtime=");
14728                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14729                        pw.println("");
14730                pw.print("  mLastPowerCheckUptime=");
14731                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14732                        pw.println("");
14733                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14734                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14735                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14736                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14737                        + " (" + mLruProcesses.size() + " total)"
14738                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14739                        + " mNumServiceProcs=" + mNumServiceProcs
14740                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14741                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14742                        + " mLastMemoryLevel=" + mLastMemoryLevel
14743                        + " mLastNumProcesses=" + mLastNumProcesses);
14744                long now = SystemClock.uptimeMillis();
14745                pw.print("  mLastIdleTime=");
14746                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14747                        pw.print(" mLowRamSinceLastIdle=");
14748                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14749                        pw.println();
14750            }
14751        }
14752
14753        if (!printedAnything) {
14754            pw.println("  (nothing)");
14755        }
14756    }
14757
14758    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14759            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14760        if (mProcessesToGc.size() > 0) {
14761            boolean printed = false;
14762            long now = SystemClock.uptimeMillis();
14763            for (int i=0; i<mProcessesToGc.size(); i++) {
14764                ProcessRecord proc = mProcessesToGc.get(i);
14765                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14766                    continue;
14767                }
14768                if (!printed) {
14769                    if (needSep) pw.println();
14770                    needSep = true;
14771                    pw.println("  Processes that are waiting to GC:");
14772                    printed = true;
14773                }
14774                pw.print("    Process "); pw.println(proc);
14775                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14776                        pw.print(", last gced=");
14777                        pw.print(now-proc.lastRequestedGc);
14778                        pw.print(" ms ago, last lowMem=");
14779                        pw.print(now-proc.lastLowMemory);
14780                        pw.println(" ms ago");
14781
14782            }
14783        }
14784        return needSep;
14785    }
14786
14787    void printOomLevel(PrintWriter pw, String name, int adj) {
14788        pw.print("    ");
14789        if (adj >= 0) {
14790            pw.print(' ');
14791            if (adj < 10) pw.print(' ');
14792        } else {
14793            if (adj > -10) pw.print(' ');
14794        }
14795        pw.print(adj);
14796        pw.print(": ");
14797        pw.print(name);
14798        pw.print(" (");
14799        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14800        pw.println(")");
14801    }
14802
14803    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14804            int opti, boolean dumpAll) {
14805        boolean needSep = false;
14806
14807        if (mLruProcesses.size() > 0) {
14808            if (needSep) pw.println();
14809            needSep = true;
14810            pw.println("  OOM levels:");
14811            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14812            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14813            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14814            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14815            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14816            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14817            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14818            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14819            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14820            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14821            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14822            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14823            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14824            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14825
14826            if (needSep) pw.println();
14827            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14828                    pw.print(" total, non-act at ");
14829                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14830                    pw.print(", non-svc at ");
14831                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14832                    pw.println("):");
14833            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14834            needSep = true;
14835        }
14836
14837        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14838
14839        pw.println();
14840        pw.println("  mHomeProcess: " + mHomeProcess);
14841        pw.println("  mPreviousProcess: " + mPreviousProcess);
14842        if (mHeavyWeightProcess != null) {
14843            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14844        }
14845
14846        return true;
14847    }
14848
14849    /**
14850     * There are three ways to call this:
14851     *  - no provider specified: dump all the providers
14852     *  - a flattened component name that matched an existing provider was specified as the
14853     *    first arg: dump that one provider
14854     *  - the first arg isn't the flattened component name of an existing provider:
14855     *    dump all providers whose component contains the first arg as a substring
14856     */
14857    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14858            int opti, boolean dumpAll) {
14859        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14860    }
14861
14862    static class ItemMatcher {
14863        ArrayList<ComponentName> components;
14864        ArrayList<String> strings;
14865        ArrayList<Integer> objects;
14866        boolean all;
14867
14868        ItemMatcher() {
14869            all = true;
14870        }
14871
14872        void build(String name) {
14873            ComponentName componentName = ComponentName.unflattenFromString(name);
14874            if (componentName != null) {
14875                if (components == null) {
14876                    components = new ArrayList<ComponentName>();
14877                }
14878                components.add(componentName);
14879                all = false;
14880            } else {
14881                int objectId = 0;
14882                // Not a '/' separated full component name; maybe an object ID?
14883                try {
14884                    objectId = Integer.parseInt(name, 16);
14885                    if (objects == null) {
14886                        objects = new ArrayList<Integer>();
14887                    }
14888                    objects.add(objectId);
14889                    all = false;
14890                } catch (RuntimeException e) {
14891                    // Not an integer; just do string match.
14892                    if (strings == null) {
14893                        strings = new ArrayList<String>();
14894                    }
14895                    strings.add(name);
14896                    all = false;
14897                }
14898            }
14899        }
14900
14901        int build(String[] args, int opti) {
14902            for (; opti<args.length; opti++) {
14903                String name = args[opti];
14904                if ("--".equals(name)) {
14905                    return opti+1;
14906                }
14907                build(name);
14908            }
14909            return opti;
14910        }
14911
14912        boolean match(Object object, ComponentName comp) {
14913            if (all) {
14914                return true;
14915            }
14916            if (components != null) {
14917                for (int i=0; i<components.size(); i++) {
14918                    if (components.get(i).equals(comp)) {
14919                        return true;
14920                    }
14921                }
14922            }
14923            if (objects != null) {
14924                for (int i=0; i<objects.size(); i++) {
14925                    if (System.identityHashCode(object) == objects.get(i)) {
14926                        return true;
14927                    }
14928                }
14929            }
14930            if (strings != null) {
14931                String flat = comp.flattenToString();
14932                for (int i=0; i<strings.size(); i++) {
14933                    if (flat.contains(strings.get(i))) {
14934                        return true;
14935                    }
14936                }
14937            }
14938            return false;
14939        }
14940    }
14941
14942    /**
14943     * There are three things that cmd can be:
14944     *  - a flattened component name that matches an existing activity
14945     *  - the cmd arg isn't the flattened component name of an existing activity:
14946     *    dump all activity whose component contains the cmd as a substring
14947     *  - A hex number of the ActivityRecord object instance.
14948     */
14949    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14950            int opti, boolean dumpAll) {
14951        ArrayList<ActivityRecord> activities;
14952
14953        synchronized (this) {
14954            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14955        }
14956
14957        if (activities.size() <= 0) {
14958            return false;
14959        }
14960
14961        String[] newArgs = new String[args.length - opti];
14962        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14963
14964        TaskRecord lastTask = null;
14965        boolean needSep = false;
14966        for (int i=activities.size()-1; i>=0; i--) {
14967            ActivityRecord r = activities.get(i);
14968            if (needSep) {
14969                pw.println();
14970            }
14971            needSep = true;
14972            synchronized (this) {
14973                if (lastTask != r.task) {
14974                    lastTask = r.task;
14975                    pw.print("TASK "); pw.print(lastTask.affinity);
14976                            pw.print(" id="); pw.println(lastTask.taskId);
14977                    if (dumpAll) {
14978                        lastTask.dump(pw, "  ");
14979                    }
14980                }
14981            }
14982            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14983        }
14984        return true;
14985    }
14986
14987    /**
14988     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14989     * there is a thread associated with the activity.
14990     */
14991    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14992            final ActivityRecord r, String[] args, boolean dumpAll) {
14993        String innerPrefix = prefix + "  ";
14994        synchronized (this) {
14995            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14996                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14997                    pw.print(" pid=");
14998                    if (r.app != null) pw.println(r.app.pid);
14999                    else pw.println("(not running)");
15000            if (dumpAll) {
15001                r.dump(pw, innerPrefix);
15002            }
15003        }
15004        if (r.app != null && r.app.thread != null) {
15005            // flush anything that is already in the PrintWriter since the thread is going
15006            // to write to the file descriptor directly
15007            pw.flush();
15008            try {
15009                TransferPipe tp = new TransferPipe();
15010                try {
15011                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15012                            r.appToken, innerPrefix, args);
15013                    tp.go(fd);
15014                } finally {
15015                    tp.kill();
15016                }
15017            } catch (IOException e) {
15018                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15019            } catch (RemoteException e) {
15020                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15021            }
15022        }
15023    }
15024
15025    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15026            int opti, boolean dumpAll, String dumpPackage) {
15027        boolean needSep = false;
15028        boolean onlyHistory = false;
15029        boolean printedAnything = false;
15030
15031        if ("history".equals(dumpPackage)) {
15032            if (opti < args.length && "-s".equals(args[opti])) {
15033                dumpAll = false;
15034            }
15035            onlyHistory = true;
15036            dumpPackage = null;
15037        }
15038
15039        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15040        if (!onlyHistory && dumpAll) {
15041            if (mRegisteredReceivers.size() > 0) {
15042                boolean printed = false;
15043                Iterator it = mRegisteredReceivers.values().iterator();
15044                while (it.hasNext()) {
15045                    ReceiverList r = (ReceiverList)it.next();
15046                    if (dumpPackage != null && (r.app == null ||
15047                            !dumpPackage.equals(r.app.info.packageName))) {
15048                        continue;
15049                    }
15050                    if (!printed) {
15051                        pw.println("  Registered Receivers:");
15052                        needSep = true;
15053                        printed = true;
15054                        printedAnything = true;
15055                    }
15056                    pw.print("  * "); pw.println(r);
15057                    r.dump(pw, "    ");
15058                }
15059            }
15060
15061            if (mReceiverResolver.dump(pw, needSep ?
15062                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15063                    "    ", dumpPackage, false, false)) {
15064                needSep = true;
15065                printedAnything = true;
15066            }
15067        }
15068
15069        for (BroadcastQueue q : mBroadcastQueues) {
15070            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15071            printedAnything |= needSep;
15072        }
15073
15074        needSep = true;
15075
15076        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15077            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15078                if (needSep) {
15079                    pw.println();
15080                }
15081                needSep = true;
15082                printedAnything = true;
15083                pw.print("  Sticky broadcasts for user ");
15084                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15085                StringBuilder sb = new StringBuilder(128);
15086                for (Map.Entry<String, ArrayList<Intent>> ent
15087                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15088                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15089                    if (dumpAll) {
15090                        pw.println(":");
15091                        ArrayList<Intent> intents = ent.getValue();
15092                        final int N = intents.size();
15093                        for (int i=0; i<N; i++) {
15094                            sb.setLength(0);
15095                            sb.append("    Intent: ");
15096                            intents.get(i).toShortString(sb, false, true, false, false);
15097                            pw.println(sb.toString());
15098                            Bundle bundle = intents.get(i).getExtras();
15099                            if (bundle != null) {
15100                                pw.print("      ");
15101                                pw.println(bundle.toString());
15102                            }
15103                        }
15104                    } else {
15105                        pw.println("");
15106                    }
15107                }
15108            }
15109        }
15110
15111        if (!onlyHistory && dumpAll) {
15112            pw.println();
15113            for (BroadcastQueue queue : mBroadcastQueues) {
15114                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15115                        + queue.mBroadcastsScheduled);
15116            }
15117            pw.println("  mHandler:");
15118            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15119            needSep = true;
15120            printedAnything = true;
15121        }
15122
15123        if (!printedAnything) {
15124            pw.println("  (nothing)");
15125        }
15126    }
15127
15128    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15129            int opti, boolean dumpAll, String dumpPackage) {
15130        if (mCurBroadcastStats == null) {
15131            return;
15132        }
15133
15134        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15135        final long now = SystemClock.elapsedRealtime();
15136        if (mLastBroadcastStats != null) {
15137            pw.print("  Last stats (from ");
15138            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15139            pw.print(" to ");
15140            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15141            pw.print(", ");
15142            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15143                    - mLastBroadcastStats.mStartUptime, pw);
15144            pw.println(" uptime):");
15145            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15146                pw.println("    (nothing)");
15147            }
15148            pw.println();
15149        }
15150        pw.print("  Current stats (from ");
15151        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15152        pw.print(" to now, ");
15153        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15154                - mCurBroadcastStats.mStartUptime, pw);
15155        pw.println(" uptime):");
15156        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15157            pw.println("    (nothing)");
15158        }
15159    }
15160
15161    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15162            int opti, boolean fullCheckin, String dumpPackage) {
15163        if (mCurBroadcastStats == null) {
15164            return;
15165        }
15166
15167        if (mLastBroadcastStats != null) {
15168            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15169            if (fullCheckin) {
15170                mLastBroadcastStats = null;
15171                return;
15172            }
15173        }
15174        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15175        if (fullCheckin) {
15176            mCurBroadcastStats = null;
15177        }
15178    }
15179
15180    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15181            int opti, boolean dumpAll, String dumpPackage) {
15182        boolean needSep;
15183        boolean printedAnything = false;
15184
15185        ItemMatcher matcher = new ItemMatcher();
15186        matcher.build(args, opti);
15187
15188        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15189
15190        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15191        printedAnything |= needSep;
15192
15193        if (mLaunchingProviders.size() > 0) {
15194            boolean printed = false;
15195            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15196                ContentProviderRecord r = mLaunchingProviders.get(i);
15197                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15198                    continue;
15199                }
15200                if (!printed) {
15201                    if (needSep) pw.println();
15202                    needSep = true;
15203                    pw.println("  Launching content providers:");
15204                    printed = true;
15205                    printedAnything = true;
15206                }
15207                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15208                        pw.println(r);
15209            }
15210        }
15211
15212        if (!printedAnything) {
15213            pw.println("  (nothing)");
15214        }
15215    }
15216
15217    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15218            int opti, boolean dumpAll, String dumpPackage) {
15219        boolean needSep = false;
15220        boolean printedAnything = false;
15221
15222        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15223
15224        if (mGrantedUriPermissions.size() > 0) {
15225            boolean printed = false;
15226            int dumpUid = -2;
15227            if (dumpPackage != null) {
15228                try {
15229                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15230                            MATCH_UNINSTALLED_PACKAGES, 0);
15231                } catch (NameNotFoundException e) {
15232                    dumpUid = -1;
15233                }
15234            }
15235            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15236                int uid = mGrantedUriPermissions.keyAt(i);
15237                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15238                    continue;
15239                }
15240                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15241                if (!printed) {
15242                    if (needSep) pw.println();
15243                    needSep = true;
15244                    pw.println("  Granted Uri Permissions:");
15245                    printed = true;
15246                    printedAnything = true;
15247                }
15248                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15249                for (UriPermission perm : perms.values()) {
15250                    pw.print("    "); pw.println(perm);
15251                    if (dumpAll) {
15252                        perm.dump(pw, "      ");
15253                    }
15254                }
15255            }
15256        }
15257
15258        if (!printedAnything) {
15259            pw.println("  (nothing)");
15260        }
15261    }
15262
15263    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15264            int opti, boolean dumpAll, String dumpPackage) {
15265        boolean printed = false;
15266
15267        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15268
15269        if (mIntentSenderRecords.size() > 0) {
15270            Iterator<WeakReference<PendingIntentRecord>> it
15271                    = mIntentSenderRecords.values().iterator();
15272            while (it.hasNext()) {
15273                WeakReference<PendingIntentRecord> ref = it.next();
15274                PendingIntentRecord rec = ref != null ? ref.get(): null;
15275                if (dumpPackage != null && (rec == null
15276                        || !dumpPackage.equals(rec.key.packageName))) {
15277                    continue;
15278                }
15279                printed = true;
15280                if (rec != null) {
15281                    pw.print("  * "); pw.println(rec);
15282                    if (dumpAll) {
15283                        rec.dump(pw, "    ");
15284                    }
15285                } else {
15286                    pw.print("  * "); pw.println(ref);
15287                }
15288            }
15289        }
15290
15291        if (!printed) {
15292            pw.println("  (nothing)");
15293        }
15294    }
15295
15296    private static final int dumpProcessList(PrintWriter pw,
15297            ActivityManagerService service, List list,
15298            String prefix, String normalLabel, String persistentLabel,
15299            String dumpPackage) {
15300        int numPers = 0;
15301        final int N = list.size()-1;
15302        for (int i=N; i>=0; i--) {
15303            ProcessRecord r = (ProcessRecord)list.get(i);
15304            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15305                continue;
15306            }
15307            pw.println(String.format("%s%s #%2d: %s",
15308                    prefix, (r.persistent ? persistentLabel : normalLabel),
15309                    i, r.toString()));
15310            if (r.persistent) {
15311                numPers++;
15312            }
15313        }
15314        return numPers;
15315    }
15316
15317    private static final boolean dumpProcessOomList(PrintWriter pw,
15318            ActivityManagerService service, List<ProcessRecord> origList,
15319            String prefix, String normalLabel, String persistentLabel,
15320            boolean inclDetails, String dumpPackage) {
15321
15322        ArrayList<Pair<ProcessRecord, Integer>> list
15323                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15324        for (int i=0; i<origList.size(); i++) {
15325            ProcessRecord r = origList.get(i);
15326            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15327                continue;
15328            }
15329            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15330        }
15331
15332        if (list.size() <= 0) {
15333            return false;
15334        }
15335
15336        Comparator<Pair<ProcessRecord, Integer>> comparator
15337                = new Comparator<Pair<ProcessRecord, Integer>>() {
15338            @Override
15339            public int compare(Pair<ProcessRecord, Integer> object1,
15340                    Pair<ProcessRecord, Integer> object2) {
15341                if (object1.first.setAdj != object2.first.setAdj) {
15342                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15343                }
15344                if (object1.first.setProcState != object2.first.setProcState) {
15345                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15346                }
15347                if (object1.second.intValue() != object2.second.intValue()) {
15348                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15349                }
15350                return 0;
15351            }
15352        };
15353
15354        Collections.sort(list, comparator);
15355
15356        final long curRealtime = SystemClock.elapsedRealtime();
15357        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15358        final long curUptime = SystemClock.uptimeMillis();
15359        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15360
15361        for (int i=list.size()-1; i>=0; i--) {
15362            ProcessRecord r = list.get(i).first;
15363            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15364            char schedGroup;
15365            switch (r.setSchedGroup) {
15366                case ProcessList.SCHED_GROUP_BACKGROUND:
15367                    schedGroup = 'B';
15368                    break;
15369                case ProcessList.SCHED_GROUP_DEFAULT:
15370                    schedGroup = 'F';
15371                    break;
15372                case ProcessList.SCHED_GROUP_TOP_APP:
15373                    schedGroup = 'T';
15374                    break;
15375                default:
15376                    schedGroup = '?';
15377                    break;
15378            }
15379            char foreground;
15380            if (r.foregroundActivities) {
15381                foreground = 'A';
15382            } else if (r.foregroundServices) {
15383                foreground = 'S';
15384            } else {
15385                foreground = ' ';
15386            }
15387            String procState = ProcessList.makeProcStateString(r.curProcState);
15388            pw.print(prefix);
15389            pw.print(r.persistent ? persistentLabel : normalLabel);
15390            pw.print(" #");
15391            int num = (origList.size()-1)-list.get(i).second;
15392            if (num < 10) pw.print(' ');
15393            pw.print(num);
15394            pw.print(": ");
15395            pw.print(oomAdj);
15396            pw.print(' ');
15397            pw.print(schedGroup);
15398            pw.print('/');
15399            pw.print(foreground);
15400            pw.print('/');
15401            pw.print(procState);
15402            pw.print(" trm:");
15403            if (r.trimMemoryLevel < 10) pw.print(' ');
15404            pw.print(r.trimMemoryLevel);
15405            pw.print(' ');
15406            pw.print(r.toShortString());
15407            pw.print(" (");
15408            pw.print(r.adjType);
15409            pw.println(')');
15410            if (r.adjSource != null || r.adjTarget != null) {
15411                pw.print(prefix);
15412                pw.print("    ");
15413                if (r.adjTarget instanceof ComponentName) {
15414                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15415                } else if (r.adjTarget != null) {
15416                    pw.print(r.adjTarget.toString());
15417                } else {
15418                    pw.print("{null}");
15419                }
15420                pw.print("<=");
15421                if (r.adjSource instanceof ProcessRecord) {
15422                    pw.print("Proc{");
15423                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15424                    pw.println("}");
15425                } else if (r.adjSource != null) {
15426                    pw.println(r.adjSource.toString());
15427                } else {
15428                    pw.println("{null}");
15429                }
15430            }
15431            if (inclDetails) {
15432                pw.print(prefix);
15433                pw.print("    ");
15434                pw.print("oom: max="); pw.print(r.maxAdj);
15435                pw.print(" curRaw="); pw.print(r.curRawAdj);
15436                pw.print(" setRaw="); pw.print(r.setRawAdj);
15437                pw.print(" cur="); pw.print(r.curAdj);
15438                pw.print(" set="); pw.println(r.setAdj);
15439                pw.print(prefix);
15440                pw.print("    ");
15441                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15442                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15443                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15444                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15445                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15446                pw.println();
15447                pw.print(prefix);
15448                pw.print("    ");
15449                pw.print("cached="); pw.print(r.cached);
15450                pw.print(" empty="); pw.print(r.empty);
15451                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15452
15453                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15454                    if (r.lastWakeTime != 0) {
15455                        long wtime;
15456                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15457                        synchronized (stats) {
15458                            wtime = stats.getProcessWakeTime(r.info.uid,
15459                                    r.pid, curRealtime);
15460                        }
15461                        long timeUsed = wtime - r.lastWakeTime;
15462                        pw.print(prefix);
15463                        pw.print("    ");
15464                        pw.print("keep awake over ");
15465                        TimeUtils.formatDuration(realtimeSince, pw);
15466                        pw.print(" used ");
15467                        TimeUtils.formatDuration(timeUsed, pw);
15468                        pw.print(" (");
15469                        pw.print((timeUsed*100)/realtimeSince);
15470                        pw.println("%)");
15471                    }
15472                    if (r.lastCpuTime != 0) {
15473                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15474                        pw.print(prefix);
15475                        pw.print("    ");
15476                        pw.print("run cpu over ");
15477                        TimeUtils.formatDuration(uptimeSince, pw);
15478                        pw.print(" used ");
15479                        TimeUtils.formatDuration(timeUsed, pw);
15480                        pw.print(" (");
15481                        pw.print((timeUsed*100)/uptimeSince);
15482                        pw.println("%)");
15483                    }
15484                }
15485            }
15486        }
15487        return true;
15488    }
15489
15490    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15491            String[] args) {
15492        ArrayList<ProcessRecord> procs;
15493        synchronized (this) {
15494            if (args != null && args.length > start
15495                    && args[start].charAt(0) != '-') {
15496                procs = new ArrayList<ProcessRecord>();
15497                int pid = -1;
15498                try {
15499                    pid = Integer.parseInt(args[start]);
15500                } catch (NumberFormatException e) {
15501                }
15502                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15503                    ProcessRecord proc = mLruProcesses.get(i);
15504                    if (proc.pid == pid) {
15505                        procs.add(proc);
15506                    } else if (allPkgs && proc.pkgList != null
15507                            && proc.pkgList.containsKey(args[start])) {
15508                        procs.add(proc);
15509                    } else if (proc.processName.equals(args[start])) {
15510                        procs.add(proc);
15511                    }
15512                }
15513                if (procs.size() <= 0) {
15514                    return null;
15515                }
15516            } else {
15517                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15518            }
15519        }
15520        return procs;
15521    }
15522
15523    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15524            PrintWriter pw, String[] args) {
15525        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15526        if (procs == null) {
15527            pw.println("No process found for: " + args[0]);
15528            return;
15529        }
15530
15531        long uptime = SystemClock.uptimeMillis();
15532        long realtime = SystemClock.elapsedRealtime();
15533        pw.println("Applications Graphics Acceleration Info:");
15534        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15535
15536        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15537            ProcessRecord r = procs.get(i);
15538            if (r.thread != null) {
15539                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15540                pw.flush();
15541                try {
15542                    TransferPipe tp = new TransferPipe();
15543                    try {
15544                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15545                        tp.go(fd);
15546                    } finally {
15547                        tp.kill();
15548                    }
15549                } catch (IOException e) {
15550                    pw.println("Failure while dumping the app: " + r);
15551                    pw.flush();
15552                } catch (RemoteException e) {
15553                    pw.println("Got a RemoteException while dumping the app " + r);
15554                    pw.flush();
15555                }
15556            }
15557        }
15558    }
15559
15560    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15561        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15562        if (procs == null) {
15563            pw.println("No process found for: " + args[0]);
15564            return;
15565        }
15566
15567        pw.println("Applications Database Info:");
15568
15569        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15570            ProcessRecord r = procs.get(i);
15571            if (r.thread != null) {
15572                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15573                pw.flush();
15574                try {
15575                    TransferPipe tp = new TransferPipe();
15576                    try {
15577                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15578                        tp.go(fd);
15579                    } finally {
15580                        tp.kill();
15581                    }
15582                } catch (IOException e) {
15583                    pw.println("Failure while dumping the app: " + r);
15584                    pw.flush();
15585                } catch (RemoteException e) {
15586                    pw.println("Got a RemoteException while dumping the app " + r);
15587                    pw.flush();
15588                }
15589            }
15590        }
15591    }
15592
15593    final static class MemItem {
15594        final boolean isProc;
15595        final String label;
15596        final String shortLabel;
15597        final long pss;
15598        final long swapPss;
15599        final int id;
15600        final boolean hasActivities;
15601        ArrayList<MemItem> subitems;
15602
15603        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15604                boolean _hasActivities) {
15605            isProc = true;
15606            label = _label;
15607            shortLabel = _shortLabel;
15608            pss = _pss;
15609            swapPss = _swapPss;
15610            id = _id;
15611            hasActivities = _hasActivities;
15612        }
15613
15614        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15615            isProc = false;
15616            label = _label;
15617            shortLabel = _shortLabel;
15618            pss = _pss;
15619            swapPss = _swapPss;
15620            id = _id;
15621            hasActivities = false;
15622        }
15623    }
15624
15625    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15626            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15627        if (sort && !isCompact) {
15628            Collections.sort(items, new Comparator<MemItem>() {
15629                @Override
15630                public int compare(MemItem lhs, MemItem rhs) {
15631                    if (lhs.pss < rhs.pss) {
15632                        return 1;
15633                    } else if (lhs.pss > rhs.pss) {
15634                        return -1;
15635                    }
15636                    return 0;
15637                }
15638            });
15639        }
15640
15641        for (int i=0; i<items.size(); i++) {
15642            MemItem mi = items.get(i);
15643            if (!isCompact) {
15644                if (dumpSwapPss) {
15645                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15646                            mi.label, stringifyKBSize(mi.swapPss));
15647                } else {
15648                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15649                }
15650            } else if (mi.isProc) {
15651                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15652                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15653                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15654                pw.println(mi.hasActivities ? ",a" : ",e");
15655            } else {
15656                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15657                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15658            }
15659            if (mi.subitems != null) {
15660                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15661                        true, isCompact, dumpSwapPss);
15662            }
15663        }
15664    }
15665
15666    // These are in KB.
15667    static final long[] DUMP_MEM_BUCKETS = new long[] {
15668        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15669        120*1024, 160*1024, 200*1024,
15670        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15671        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15672    };
15673
15674    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15675            boolean stackLike) {
15676        int start = label.lastIndexOf('.');
15677        if (start >= 0) start++;
15678        else start = 0;
15679        int end = label.length();
15680        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15681            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15682                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15683                out.append(bucket);
15684                out.append(stackLike ? "MB." : "MB ");
15685                out.append(label, start, end);
15686                return;
15687            }
15688        }
15689        out.append(memKB/1024);
15690        out.append(stackLike ? "MB." : "MB ");
15691        out.append(label, start, end);
15692    }
15693
15694    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15695            ProcessList.NATIVE_ADJ,
15696            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15697            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15698            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15699            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15700            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15701            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15702    };
15703    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15704            "Native",
15705            "System", "Persistent", "Persistent Service", "Foreground",
15706            "Visible", "Perceptible",
15707            "Heavy Weight", "Backup",
15708            "A Services", "Home",
15709            "Previous", "B Services", "Cached"
15710    };
15711    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15712            "native",
15713            "sys", "pers", "persvc", "fore",
15714            "vis", "percept",
15715            "heavy", "backup",
15716            "servicea", "home",
15717            "prev", "serviceb", "cached"
15718    };
15719
15720    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15721            long realtime, boolean isCheckinRequest, boolean isCompact) {
15722        if (isCompact) {
15723            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15724        }
15725        if (isCheckinRequest || isCompact) {
15726            // short checkin version
15727            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15728        } else {
15729            pw.println("Applications Memory Usage (in Kilobytes):");
15730            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15731        }
15732    }
15733
15734    private static final int KSM_SHARED = 0;
15735    private static final int KSM_SHARING = 1;
15736    private static final int KSM_UNSHARED = 2;
15737    private static final int KSM_VOLATILE = 3;
15738
15739    private final long[] getKsmInfo() {
15740        long[] longOut = new long[4];
15741        final int[] SINGLE_LONG_FORMAT = new int[] {
15742            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15743        };
15744        long[] longTmp = new long[1];
15745        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15746                SINGLE_LONG_FORMAT, null, longTmp, null);
15747        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15748        longTmp[0] = 0;
15749        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15750                SINGLE_LONG_FORMAT, null, longTmp, null);
15751        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15752        longTmp[0] = 0;
15753        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15754                SINGLE_LONG_FORMAT, null, longTmp, null);
15755        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15756        longTmp[0] = 0;
15757        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15758                SINGLE_LONG_FORMAT, null, longTmp, null);
15759        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15760        return longOut;
15761    }
15762
15763    private static String stringifySize(long size, int order) {
15764        Locale locale = Locale.US;
15765        switch (order) {
15766            case 1:
15767                return String.format(locale, "%,13d", size);
15768            case 1024:
15769                return String.format(locale, "%,9dK", size / 1024);
15770            case 1024 * 1024:
15771                return String.format(locale, "%,5dM", size / 1024 / 1024);
15772            case 1024 * 1024 * 1024:
15773                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15774            default:
15775                throw new IllegalArgumentException("Invalid size order");
15776        }
15777    }
15778
15779    private static String stringifyKBSize(long size) {
15780        return stringifySize(size * 1024, 1024);
15781    }
15782
15783    // Update this version number in case you change the 'compact' format
15784    private static final int MEMINFO_COMPACT_VERSION = 1;
15785
15786    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15787            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15788        boolean dumpDetails = false;
15789        boolean dumpFullDetails = false;
15790        boolean dumpDalvik = false;
15791        boolean dumpSummaryOnly = false;
15792        boolean dumpUnreachable = false;
15793        boolean oomOnly = false;
15794        boolean isCompact = false;
15795        boolean localOnly = false;
15796        boolean packages = false;
15797        boolean isCheckinRequest = false;
15798        boolean dumpSwapPss = false;
15799
15800        int opti = 0;
15801        while (opti < args.length) {
15802            String opt = args[opti];
15803            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15804                break;
15805            }
15806            opti++;
15807            if ("-a".equals(opt)) {
15808                dumpDetails = true;
15809                dumpFullDetails = true;
15810                dumpDalvik = true;
15811                dumpSwapPss = true;
15812            } else if ("-d".equals(opt)) {
15813                dumpDalvik = true;
15814            } else if ("-c".equals(opt)) {
15815                isCompact = true;
15816            } else if ("-s".equals(opt)) {
15817                dumpDetails = true;
15818                dumpSummaryOnly = true;
15819            } else if ("-S".equals(opt)) {
15820                dumpSwapPss = true;
15821            } else if ("--unreachable".equals(opt)) {
15822                dumpUnreachable = true;
15823            } else if ("--oom".equals(opt)) {
15824                oomOnly = true;
15825            } else if ("--local".equals(opt)) {
15826                localOnly = true;
15827            } else if ("--package".equals(opt)) {
15828                packages = true;
15829            } else if ("--checkin".equals(opt)) {
15830                isCheckinRequest = true;
15831
15832            } else if ("-h".equals(opt)) {
15833                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15834                pw.println("  -a: include all available information for each process.");
15835                pw.println("  -d: include dalvik details.");
15836                pw.println("  -c: dump in a compact machine-parseable representation.");
15837                pw.println("  -s: dump only summary of application memory usage.");
15838                pw.println("  -S: dump also SwapPss.");
15839                pw.println("  --oom: only show processes organized by oom adj.");
15840                pw.println("  --local: only collect details locally, don't call process.");
15841                pw.println("  --package: interpret process arg as package, dumping all");
15842                pw.println("             processes that have loaded that package.");
15843                pw.println("  --checkin: dump data for a checkin");
15844                pw.println("If [process] is specified it can be the name or ");
15845                pw.println("pid of a specific process to dump.");
15846                return;
15847            } else {
15848                pw.println("Unknown argument: " + opt + "; use -h for help");
15849            }
15850        }
15851
15852        long uptime = SystemClock.uptimeMillis();
15853        long realtime = SystemClock.elapsedRealtime();
15854        final long[] tmpLong = new long[1];
15855
15856        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15857        if (procs == null) {
15858            // No Java processes.  Maybe they want to print a native process.
15859            if (args != null && args.length > opti
15860                    && args[opti].charAt(0) != '-') {
15861                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15862                        = new ArrayList<ProcessCpuTracker.Stats>();
15863                updateCpuStatsNow();
15864                int findPid = -1;
15865                try {
15866                    findPid = Integer.parseInt(args[opti]);
15867                } catch (NumberFormatException e) {
15868                }
15869                synchronized (mProcessCpuTracker) {
15870                    final int N = mProcessCpuTracker.countStats();
15871                    for (int i=0; i<N; i++) {
15872                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15873                        if (st.pid == findPid || (st.baseName != null
15874                                && st.baseName.equals(args[opti]))) {
15875                            nativeProcs.add(st);
15876                        }
15877                    }
15878                }
15879                if (nativeProcs.size() > 0) {
15880                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15881                            isCompact);
15882                    Debug.MemoryInfo mi = null;
15883                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15884                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15885                        final int pid = r.pid;
15886                        if (!isCheckinRequest && dumpDetails) {
15887                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15888                        }
15889                        if (mi == null) {
15890                            mi = new Debug.MemoryInfo();
15891                        }
15892                        if (dumpDetails || (!brief && !oomOnly)) {
15893                            Debug.getMemoryInfo(pid, mi);
15894                        } else {
15895                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15896                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15897                        }
15898                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15899                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15900                        if (isCheckinRequest) {
15901                            pw.println();
15902                        }
15903                    }
15904                    return;
15905                }
15906            }
15907            pw.println("No process found for: " + args[opti]);
15908            return;
15909        }
15910
15911        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15912            dumpDetails = true;
15913        }
15914
15915        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15916
15917        String[] innerArgs = new String[args.length-opti];
15918        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15919
15920        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15921        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15922        long nativePss = 0;
15923        long nativeSwapPss = 0;
15924        long dalvikPss = 0;
15925        long dalvikSwapPss = 0;
15926        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15927                EmptyArray.LONG;
15928        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15929                EmptyArray.LONG;
15930        long otherPss = 0;
15931        long otherSwapPss = 0;
15932        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15933        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15934
15935        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15936        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15937        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15938                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15939
15940        long totalPss = 0;
15941        long totalSwapPss = 0;
15942        long cachedPss = 0;
15943        long cachedSwapPss = 0;
15944        boolean hasSwapPss = false;
15945
15946        Debug.MemoryInfo mi = null;
15947        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15948            final ProcessRecord r = procs.get(i);
15949            final IApplicationThread thread;
15950            final int pid;
15951            final int oomAdj;
15952            final boolean hasActivities;
15953            synchronized (this) {
15954                thread = r.thread;
15955                pid = r.pid;
15956                oomAdj = r.getSetAdjWithServices();
15957                hasActivities = r.activities.size() > 0;
15958            }
15959            if (thread != null) {
15960                if (!isCheckinRequest && dumpDetails) {
15961                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15962                }
15963                if (mi == null) {
15964                    mi = new Debug.MemoryInfo();
15965                }
15966                if (dumpDetails || (!brief && !oomOnly)) {
15967                    Debug.getMemoryInfo(pid, mi);
15968                    hasSwapPss = mi.hasSwappedOutPss;
15969                } else {
15970                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15971                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15972                }
15973                if (dumpDetails) {
15974                    if (localOnly) {
15975                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15976                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15977                        if (isCheckinRequest) {
15978                            pw.println();
15979                        }
15980                    } else {
15981                        try {
15982                            pw.flush();
15983                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15984                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15985                        } catch (RemoteException e) {
15986                            if (!isCheckinRequest) {
15987                                pw.println("Got RemoteException!");
15988                                pw.flush();
15989                            }
15990                        }
15991                    }
15992                }
15993
15994                final long myTotalPss = mi.getTotalPss();
15995                final long myTotalUss = mi.getTotalUss();
15996                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15997
15998                synchronized (this) {
15999                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16000                        // Record this for posterity if the process has been stable.
16001                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16002                    }
16003                }
16004
16005                if (!isCheckinRequest && mi != null) {
16006                    totalPss += myTotalPss;
16007                    totalSwapPss += myTotalSwapPss;
16008                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16009                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16010                            myTotalSwapPss, pid, hasActivities);
16011                    procMems.add(pssItem);
16012                    procMemsMap.put(pid, pssItem);
16013
16014                    nativePss += mi.nativePss;
16015                    nativeSwapPss += mi.nativeSwappedOutPss;
16016                    dalvikPss += mi.dalvikPss;
16017                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16018                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16019                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16020                        dalvikSubitemSwapPss[j] +=
16021                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16022                    }
16023                    otherPss += mi.otherPss;
16024                    otherSwapPss += mi.otherSwappedOutPss;
16025                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16026                        long mem = mi.getOtherPss(j);
16027                        miscPss[j] += mem;
16028                        otherPss -= mem;
16029                        mem = mi.getOtherSwappedOutPss(j);
16030                        miscSwapPss[j] += mem;
16031                        otherSwapPss -= mem;
16032                    }
16033
16034                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16035                        cachedPss += myTotalPss;
16036                        cachedSwapPss += myTotalSwapPss;
16037                    }
16038
16039                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16040                        if (oomIndex == (oomPss.length - 1)
16041                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16042                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16043                            oomPss[oomIndex] += myTotalPss;
16044                            oomSwapPss[oomIndex] += myTotalSwapPss;
16045                            if (oomProcs[oomIndex] == null) {
16046                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16047                            }
16048                            oomProcs[oomIndex].add(pssItem);
16049                            break;
16050                        }
16051                    }
16052                }
16053            }
16054        }
16055
16056        long nativeProcTotalPss = 0;
16057
16058        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16059            // If we are showing aggregations, also look for native processes to
16060            // include so that our aggregations are more accurate.
16061            updateCpuStatsNow();
16062            mi = null;
16063            synchronized (mProcessCpuTracker) {
16064                final int N = mProcessCpuTracker.countStats();
16065                for (int i=0; i<N; i++) {
16066                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16067                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16068                        if (mi == null) {
16069                            mi = new Debug.MemoryInfo();
16070                        }
16071                        if (!brief && !oomOnly) {
16072                            Debug.getMemoryInfo(st.pid, mi);
16073                        } else {
16074                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16075                            mi.nativePrivateDirty = (int)tmpLong[0];
16076                        }
16077
16078                        final long myTotalPss = mi.getTotalPss();
16079                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16080                        totalPss += myTotalPss;
16081                        nativeProcTotalPss += myTotalPss;
16082
16083                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16084                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16085                        procMems.add(pssItem);
16086
16087                        nativePss += mi.nativePss;
16088                        nativeSwapPss += mi.nativeSwappedOutPss;
16089                        dalvikPss += mi.dalvikPss;
16090                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16091                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16092                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16093                            dalvikSubitemSwapPss[j] +=
16094                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16095                        }
16096                        otherPss += mi.otherPss;
16097                        otherSwapPss += mi.otherSwappedOutPss;
16098                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16099                            long mem = mi.getOtherPss(j);
16100                            miscPss[j] += mem;
16101                            otherPss -= mem;
16102                            mem = mi.getOtherSwappedOutPss(j);
16103                            miscSwapPss[j] += mem;
16104                            otherSwapPss -= mem;
16105                        }
16106                        oomPss[0] += myTotalPss;
16107                        oomSwapPss[0] += myTotalSwapPss;
16108                        if (oomProcs[0] == null) {
16109                            oomProcs[0] = new ArrayList<MemItem>();
16110                        }
16111                        oomProcs[0].add(pssItem);
16112                    }
16113                }
16114            }
16115
16116            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16117
16118            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16119            final MemItem dalvikItem =
16120                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16121            if (dalvikSubitemPss.length > 0) {
16122                dalvikItem.subitems = new ArrayList<MemItem>();
16123                for (int j=0; j<dalvikSubitemPss.length; j++) {
16124                    final String name = Debug.MemoryInfo.getOtherLabel(
16125                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16126                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16127                                    dalvikSubitemSwapPss[j], j));
16128                }
16129            }
16130            catMems.add(dalvikItem);
16131            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16132            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16133                String label = Debug.MemoryInfo.getOtherLabel(j);
16134                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16135            }
16136
16137            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16138            for (int j=0; j<oomPss.length; j++) {
16139                if (oomPss[j] != 0) {
16140                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16141                            : DUMP_MEM_OOM_LABEL[j];
16142                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16143                            DUMP_MEM_OOM_ADJ[j]);
16144                    item.subitems = oomProcs[j];
16145                    oomMems.add(item);
16146                }
16147            }
16148
16149            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16150            if (!brief && !oomOnly && !isCompact) {
16151                pw.println();
16152                pw.println("Total PSS by process:");
16153                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16154                pw.println();
16155            }
16156            if (!isCompact) {
16157                pw.println("Total PSS by OOM adjustment:");
16158            }
16159            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16160            if (!brief && !oomOnly) {
16161                PrintWriter out = categoryPw != null ? categoryPw : pw;
16162                if (!isCompact) {
16163                    out.println();
16164                    out.println("Total PSS by category:");
16165                }
16166                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16167            }
16168            if (!isCompact) {
16169                pw.println();
16170            }
16171            MemInfoReader memInfo = new MemInfoReader();
16172            memInfo.readMemInfo();
16173            if (nativeProcTotalPss > 0) {
16174                synchronized (this) {
16175                    final long cachedKb = memInfo.getCachedSizeKb();
16176                    final long freeKb = memInfo.getFreeSizeKb();
16177                    final long zramKb = memInfo.getZramTotalSizeKb();
16178                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16179                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16180                            kernelKb*1024, nativeProcTotalPss*1024);
16181                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16182                            nativeProcTotalPss);
16183                }
16184            }
16185            if (!brief) {
16186                if (!isCompact) {
16187                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16188                    pw.print(" (status ");
16189                    switch (mLastMemoryLevel) {
16190                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16191                            pw.println("normal)");
16192                            break;
16193                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16194                            pw.println("moderate)");
16195                            break;
16196                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16197                            pw.println("low)");
16198                            break;
16199                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16200                            pw.println("critical)");
16201                            break;
16202                        default:
16203                            pw.print(mLastMemoryLevel);
16204                            pw.println(")");
16205                            break;
16206                    }
16207                    pw.print(" Free RAM: ");
16208                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16209                            + memInfo.getFreeSizeKb()));
16210                    pw.print(" (");
16211                    pw.print(stringifyKBSize(cachedPss));
16212                    pw.print(" cached pss + ");
16213                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16214                    pw.print(" cached kernel + ");
16215                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16216                    pw.println(" free)");
16217                } else {
16218                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16219                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16220                            + memInfo.getFreeSizeKb()); pw.print(",");
16221                    pw.println(totalPss - cachedPss);
16222                }
16223            }
16224            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16225                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16226                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16227            if (!isCompact) {
16228                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16229                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16230                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16231                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16232                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16233            } else {
16234                pw.print("lostram,"); pw.println(lostRAM);
16235            }
16236            if (!brief) {
16237                if (memInfo.getZramTotalSizeKb() != 0) {
16238                    if (!isCompact) {
16239                        pw.print("     ZRAM: ");
16240                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16241                                pw.print(" physical used for ");
16242                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16243                                        - memInfo.getSwapFreeSizeKb()));
16244                                pw.print(" in swap (");
16245                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16246                                pw.println(" total swap)");
16247                    } else {
16248                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16249                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16250                                pw.println(memInfo.getSwapFreeSizeKb());
16251                    }
16252                }
16253                final long[] ksm = getKsmInfo();
16254                if (!isCompact) {
16255                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16256                            || ksm[KSM_VOLATILE] != 0) {
16257                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16258                                pw.print(" saved from shared ");
16259                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16260                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16261                                pw.print(" unshared; ");
16262                                pw.print(stringifyKBSize(
16263                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16264                    }
16265                    pw.print("   Tuning: ");
16266                    pw.print(ActivityManager.staticGetMemoryClass());
16267                    pw.print(" (large ");
16268                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16269                    pw.print("), oom ");
16270                    pw.print(stringifySize(
16271                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16272                    pw.print(", restore limit ");
16273                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16274                    if (ActivityManager.isLowRamDeviceStatic()) {
16275                        pw.print(" (low-ram)");
16276                    }
16277                    if (ActivityManager.isHighEndGfx()) {
16278                        pw.print(" (high-end-gfx)");
16279                    }
16280                    pw.println();
16281                } else {
16282                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16283                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16284                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16285                    pw.print("tuning,");
16286                    pw.print(ActivityManager.staticGetMemoryClass());
16287                    pw.print(',');
16288                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16289                    pw.print(',');
16290                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16291                    if (ActivityManager.isLowRamDeviceStatic()) {
16292                        pw.print(",low-ram");
16293                    }
16294                    if (ActivityManager.isHighEndGfx()) {
16295                        pw.print(",high-end-gfx");
16296                    }
16297                    pw.println();
16298                }
16299            }
16300        }
16301    }
16302
16303    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16304            long memtrack, String name) {
16305        sb.append("  ");
16306        sb.append(ProcessList.makeOomAdjString(oomAdj));
16307        sb.append(' ');
16308        sb.append(ProcessList.makeProcStateString(procState));
16309        sb.append(' ');
16310        ProcessList.appendRamKb(sb, pss);
16311        sb.append(": ");
16312        sb.append(name);
16313        if (memtrack > 0) {
16314            sb.append(" (");
16315            sb.append(stringifyKBSize(memtrack));
16316            sb.append(" memtrack)");
16317        }
16318    }
16319
16320    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16321        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16322        sb.append(" (pid ");
16323        sb.append(mi.pid);
16324        sb.append(") ");
16325        sb.append(mi.adjType);
16326        sb.append('\n');
16327        if (mi.adjReason != null) {
16328            sb.append("                      ");
16329            sb.append(mi.adjReason);
16330            sb.append('\n');
16331        }
16332    }
16333
16334    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16335        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16336        for (int i=0, N=memInfos.size(); i<N; i++) {
16337            ProcessMemInfo mi = memInfos.get(i);
16338            infoMap.put(mi.pid, mi);
16339        }
16340        updateCpuStatsNow();
16341        long[] memtrackTmp = new long[1];
16342        synchronized (mProcessCpuTracker) {
16343            final int N = mProcessCpuTracker.countStats();
16344            for (int i=0; i<N; i++) {
16345                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16346                if (st.vsize > 0) {
16347                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16348                    if (pss > 0) {
16349                        if (infoMap.indexOfKey(st.pid) < 0) {
16350                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16351                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16352                            mi.pss = pss;
16353                            mi.memtrack = memtrackTmp[0];
16354                            memInfos.add(mi);
16355                        }
16356                    }
16357                }
16358            }
16359        }
16360
16361        long totalPss = 0;
16362        long totalMemtrack = 0;
16363        for (int i=0, N=memInfos.size(); i<N; i++) {
16364            ProcessMemInfo mi = memInfos.get(i);
16365            if (mi.pss == 0) {
16366                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16367                mi.memtrack = memtrackTmp[0];
16368            }
16369            totalPss += mi.pss;
16370            totalMemtrack += mi.memtrack;
16371        }
16372        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16373            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16374                if (lhs.oomAdj != rhs.oomAdj) {
16375                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16376                }
16377                if (lhs.pss != rhs.pss) {
16378                    return lhs.pss < rhs.pss ? 1 : -1;
16379                }
16380                return 0;
16381            }
16382        });
16383
16384        StringBuilder tag = new StringBuilder(128);
16385        StringBuilder stack = new StringBuilder(128);
16386        tag.append("Low on memory -- ");
16387        appendMemBucket(tag, totalPss, "total", false);
16388        appendMemBucket(stack, totalPss, "total", true);
16389
16390        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16391        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16392        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16393
16394        boolean firstLine = true;
16395        int lastOomAdj = Integer.MIN_VALUE;
16396        long extraNativeRam = 0;
16397        long extraNativeMemtrack = 0;
16398        long cachedPss = 0;
16399        for (int i=0, N=memInfos.size(); i<N; i++) {
16400            ProcessMemInfo mi = memInfos.get(i);
16401
16402            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16403                cachedPss += mi.pss;
16404            }
16405
16406            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16407                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16408                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16409                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16410                if (lastOomAdj != mi.oomAdj) {
16411                    lastOomAdj = mi.oomAdj;
16412                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16413                        tag.append(" / ");
16414                    }
16415                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16416                        if (firstLine) {
16417                            stack.append(":");
16418                            firstLine = false;
16419                        }
16420                        stack.append("\n\t at ");
16421                    } else {
16422                        stack.append("$");
16423                    }
16424                } else {
16425                    tag.append(" ");
16426                    stack.append("$");
16427                }
16428                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16429                    appendMemBucket(tag, mi.pss, mi.name, false);
16430                }
16431                appendMemBucket(stack, mi.pss, mi.name, true);
16432                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16433                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16434                    stack.append("(");
16435                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16436                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16437                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16438                            stack.append(":");
16439                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16440                        }
16441                    }
16442                    stack.append(")");
16443                }
16444            }
16445
16446            appendMemInfo(fullNativeBuilder, mi);
16447            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16448                // The short form only has native processes that are >= 512K.
16449                if (mi.pss >= 512) {
16450                    appendMemInfo(shortNativeBuilder, mi);
16451                } else {
16452                    extraNativeRam += mi.pss;
16453                    extraNativeMemtrack += mi.memtrack;
16454                }
16455            } else {
16456                // Short form has all other details, but if we have collected RAM
16457                // from smaller native processes let's dump a summary of that.
16458                if (extraNativeRam > 0) {
16459                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16460                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16461                    shortNativeBuilder.append('\n');
16462                    extraNativeRam = 0;
16463                }
16464                appendMemInfo(fullJavaBuilder, mi);
16465            }
16466        }
16467
16468        fullJavaBuilder.append("           ");
16469        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16470        fullJavaBuilder.append(": TOTAL");
16471        if (totalMemtrack > 0) {
16472            fullJavaBuilder.append(" (");
16473            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16474            fullJavaBuilder.append(" memtrack)");
16475        } else {
16476        }
16477        fullJavaBuilder.append("\n");
16478
16479        MemInfoReader memInfo = new MemInfoReader();
16480        memInfo.readMemInfo();
16481        final long[] infos = memInfo.getRawInfo();
16482
16483        StringBuilder memInfoBuilder = new StringBuilder(1024);
16484        Debug.getMemInfo(infos);
16485        memInfoBuilder.append("  MemInfo: ");
16486        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16487        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16488        memInfoBuilder.append(stringifyKBSize(
16489                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16490        memInfoBuilder.append(stringifyKBSize(
16491                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16492        memInfoBuilder.append(stringifyKBSize(
16493                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16494        memInfoBuilder.append("           ");
16495        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16496        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16497        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16498        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16499        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16500            memInfoBuilder.append("  ZRAM: ");
16501            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16502            memInfoBuilder.append(" RAM, ");
16503            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16504            memInfoBuilder.append(" swap total, ");
16505            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16506            memInfoBuilder.append(" swap free\n");
16507        }
16508        final long[] ksm = getKsmInfo();
16509        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16510                || ksm[KSM_VOLATILE] != 0) {
16511            memInfoBuilder.append("  KSM: ");
16512            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16513            memInfoBuilder.append(" saved from shared ");
16514            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16515            memInfoBuilder.append("\n       ");
16516            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16517            memInfoBuilder.append(" unshared; ");
16518            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16519            memInfoBuilder.append(" volatile\n");
16520        }
16521        memInfoBuilder.append("  Free RAM: ");
16522        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16523                + memInfo.getFreeSizeKb()));
16524        memInfoBuilder.append("\n");
16525        memInfoBuilder.append("  Used RAM: ");
16526        memInfoBuilder.append(stringifyKBSize(
16527                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16528        memInfoBuilder.append("\n");
16529        memInfoBuilder.append("  Lost RAM: ");
16530        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16531                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16532                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16533        memInfoBuilder.append("\n");
16534        Slog.i(TAG, "Low on memory:");
16535        Slog.i(TAG, shortNativeBuilder.toString());
16536        Slog.i(TAG, fullJavaBuilder.toString());
16537        Slog.i(TAG, memInfoBuilder.toString());
16538
16539        StringBuilder dropBuilder = new StringBuilder(1024);
16540        /*
16541        StringWriter oomSw = new StringWriter();
16542        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16543        StringWriter catSw = new StringWriter();
16544        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16545        String[] emptyArgs = new String[] { };
16546        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16547        oomPw.flush();
16548        String oomString = oomSw.toString();
16549        */
16550        dropBuilder.append("Low on memory:");
16551        dropBuilder.append(stack);
16552        dropBuilder.append('\n');
16553        dropBuilder.append(fullNativeBuilder);
16554        dropBuilder.append(fullJavaBuilder);
16555        dropBuilder.append('\n');
16556        dropBuilder.append(memInfoBuilder);
16557        dropBuilder.append('\n');
16558        /*
16559        dropBuilder.append(oomString);
16560        dropBuilder.append('\n');
16561        */
16562        StringWriter catSw = new StringWriter();
16563        synchronized (ActivityManagerService.this) {
16564            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16565            String[] emptyArgs = new String[] { };
16566            catPw.println();
16567            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16568            catPw.println();
16569            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16570                    false, null).dumpLocked();
16571            catPw.println();
16572            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16573            catPw.flush();
16574        }
16575        dropBuilder.append(catSw.toString());
16576        addErrorToDropBox("lowmem", null, "system_server", null,
16577                null, tag.toString(), dropBuilder.toString(), null, null);
16578        //Slog.i(TAG, "Sent to dropbox:");
16579        //Slog.i(TAG, dropBuilder.toString());
16580        synchronized (ActivityManagerService.this) {
16581            long now = SystemClock.uptimeMillis();
16582            if (mLastMemUsageReportTime < now) {
16583                mLastMemUsageReportTime = now;
16584            }
16585        }
16586    }
16587
16588    /**
16589     * Searches array of arguments for the specified string
16590     * @param args array of argument strings
16591     * @param value value to search for
16592     * @return true if the value is contained in the array
16593     */
16594    private static boolean scanArgs(String[] args, String value) {
16595        if (args != null) {
16596            for (String arg : args) {
16597                if (value.equals(arg)) {
16598                    return true;
16599                }
16600            }
16601        }
16602        return false;
16603    }
16604
16605    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16606            ContentProviderRecord cpr, boolean always) {
16607        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16608
16609        if (!inLaunching || always) {
16610            synchronized (cpr) {
16611                cpr.launchingApp = null;
16612                cpr.notifyAll();
16613            }
16614            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16615            String names[] = cpr.info.authority.split(";");
16616            for (int j = 0; j < names.length; j++) {
16617                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16618            }
16619        }
16620
16621        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16622            ContentProviderConnection conn = cpr.connections.get(i);
16623            if (conn.waiting) {
16624                // If this connection is waiting for the provider, then we don't
16625                // need to mess with its process unless we are always removing
16626                // or for some reason the provider is not currently launching.
16627                if (inLaunching && !always) {
16628                    continue;
16629                }
16630            }
16631            ProcessRecord capp = conn.client;
16632            conn.dead = true;
16633            if (conn.stableCount > 0) {
16634                if (!capp.persistent && capp.thread != null
16635                        && capp.pid != 0
16636                        && capp.pid != MY_PID) {
16637                    capp.kill("depends on provider "
16638                            + cpr.name.flattenToShortString()
16639                            + " in dying proc " + (proc != null ? proc.processName : "??")
16640                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16641                }
16642            } else if (capp.thread != null && conn.provider.provider != null) {
16643                try {
16644                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16645                } catch (RemoteException e) {
16646                }
16647                // In the protocol here, we don't expect the client to correctly
16648                // clean up this connection, we'll just remove it.
16649                cpr.connections.remove(i);
16650                if (conn.client.conProviders.remove(conn)) {
16651                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16652                }
16653            }
16654        }
16655
16656        if (inLaunching && always) {
16657            mLaunchingProviders.remove(cpr);
16658        }
16659        return inLaunching;
16660    }
16661
16662    /**
16663     * Main code for cleaning up a process when it has gone away.  This is
16664     * called both as a result of the process dying, or directly when stopping
16665     * a process when running in single process mode.
16666     *
16667     * @return Returns true if the given process has been restarted, so the
16668     * app that was passed in must remain on the process lists.
16669     */
16670    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16671            boolean restarting, boolean allowRestart, int index) {
16672        if (index >= 0) {
16673            removeLruProcessLocked(app);
16674            ProcessList.remove(app.pid);
16675        }
16676
16677        mProcessesToGc.remove(app);
16678        mPendingPssProcesses.remove(app);
16679
16680        // Dismiss any open dialogs.
16681        if (app.crashDialog != null && !app.forceCrashReport) {
16682            app.crashDialog.dismiss();
16683            app.crashDialog = null;
16684        }
16685        if (app.anrDialog != null) {
16686            app.anrDialog.dismiss();
16687            app.anrDialog = null;
16688        }
16689        if (app.waitDialog != null) {
16690            app.waitDialog.dismiss();
16691            app.waitDialog = null;
16692        }
16693
16694        app.crashing = false;
16695        app.notResponding = false;
16696
16697        app.resetPackageList(mProcessStats);
16698        app.unlinkDeathRecipient();
16699        app.makeInactive(mProcessStats);
16700        app.waitingToKill = null;
16701        app.forcingToForeground = null;
16702        updateProcessForegroundLocked(app, false, false);
16703        app.foregroundActivities = false;
16704        app.hasShownUi = false;
16705        app.treatLikeActivity = false;
16706        app.hasAboveClient = false;
16707        app.hasClientActivities = false;
16708
16709        mServices.killServicesLocked(app, allowRestart);
16710
16711        boolean restart = false;
16712
16713        // Remove published content providers.
16714        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16715            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16716            final boolean always = app.bad || !allowRestart;
16717            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16718            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16719                // We left the provider in the launching list, need to
16720                // restart it.
16721                restart = true;
16722            }
16723
16724            cpr.provider = null;
16725            cpr.proc = null;
16726        }
16727        app.pubProviders.clear();
16728
16729        // Take care of any launching providers waiting for this process.
16730        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16731            restart = true;
16732        }
16733
16734        // Unregister from connected content providers.
16735        if (!app.conProviders.isEmpty()) {
16736            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16737                ContentProviderConnection conn = app.conProviders.get(i);
16738                conn.provider.connections.remove(conn);
16739                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16740                        conn.provider.name);
16741            }
16742            app.conProviders.clear();
16743        }
16744
16745        // At this point there may be remaining entries in mLaunchingProviders
16746        // where we were the only one waiting, so they are no longer of use.
16747        // Look for these and clean up if found.
16748        // XXX Commented out for now.  Trying to figure out a way to reproduce
16749        // the actual situation to identify what is actually going on.
16750        if (false) {
16751            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16752                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16753                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16754                    synchronized (cpr) {
16755                        cpr.launchingApp = null;
16756                        cpr.notifyAll();
16757                    }
16758                }
16759            }
16760        }
16761
16762        skipCurrentReceiverLocked(app);
16763
16764        // Unregister any receivers.
16765        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16766            removeReceiverLocked(app.receivers.valueAt(i));
16767        }
16768        app.receivers.clear();
16769
16770        // If the app is undergoing backup, tell the backup manager about it
16771        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16772            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16773                    + mBackupTarget.appInfo + " died during backup");
16774            mHandler.post(new Runnable() {
16775                @Override
16776                public void run(){
16777                    try {
16778                        IBackupManager bm = IBackupManager.Stub.asInterface(
16779                                ServiceManager.getService(Context.BACKUP_SERVICE));
16780                        bm.agentDisconnected(app.info.packageName);
16781                    } catch (RemoteException e) {
16782                        // can't happen; backup manager is local
16783                    }
16784                }
16785            });
16786        }
16787
16788        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16789            ProcessChangeItem item = mPendingProcessChanges.get(i);
16790            if (item.pid == app.pid) {
16791                mPendingProcessChanges.remove(i);
16792                mAvailProcessChanges.add(item);
16793            }
16794        }
16795        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16796                null).sendToTarget();
16797
16798        // If the caller is restarting this app, then leave it in its
16799        // current lists and let the caller take care of it.
16800        if (restarting) {
16801            return false;
16802        }
16803
16804        if (!app.persistent || app.isolated) {
16805            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16806                    "Removing non-persistent process during cleanup: " + app);
16807            removeProcessNameLocked(app.processName, app.uid);
16808            if (mHeavyWeightProcess == app) {
16809                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16810                        mHeavyWeightProcess.userId, 0));
16811                mHeavyWeightProcess = null;
16812            }
16813        } else if (!app.removed) {
16814            // This app is persistent, so we need to keep its record around.
16815            // If it is not already on the pending app list, add it there
16816            // and start a new process for it.
16817            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16818                mPersistentStartingProcesses.add(app);
16819                restart = true;
16820            }
16821        }
16822        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16823                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16824        mProcessesOnHold.remove(app);
16825
16826        if (app == mHomeProcess) {
16827            mHomeProcess = null;
16828        }
16829        if (app == mPreviousProcess) {
16830            mPreviousProcess = null;
16831        }
16832
16833        if (restart && !app.isolated) {
16834            // We have components that still need to be running in the
16835            // process, so re-launch it.
16836            if (index < 0) {
16837                ProcessList.remove(app.pid);
16838            }
16839            addProcessNameLocked(app);
16840            startProcessLocked(app, "restart", app.processName);
16841            return true;
16842        } else if (app.pid > 0 && app.pid != MY_PID) {
16843            // Goodbye!
16844            boolean removed;
16845            synchronized (mPidsSelfLocked) {
16846                mPidsSelfLocked.remove(app.pid);
16847                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16848            }
16849            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16850            if (app.isolated) {
16851                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16852            }
16853            app.setPid(0);
16854        }
16855        return false;
16856    }
16857
16858    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16859        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16860            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16861            if (cpr.launchingApp == app) {
16862                return true;
16863            }
16864        }
16865        return false;
16866    }
16867
16868    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16869        // Look through the content providers we are waiting to have launched,
16870        // and if any run in this process then either schedule a restart of
16871        // the process or kill the client waiting for it if this process has
16872        // gone bad.
16873        boolean restart = false;
16874        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16875            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16876            if (cpr.launchingApp == app) {
16877                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16878                    restart = true;
16879                } else {
16880                    removeDyingProviderLocked(app, cpr, true);
16881                }
16882            }
16883        }
16884        return restart;
16885    }
16886
16887    // =========================================================
16888    // SERVICES
16889    // =========================================================
16890
16891    @Override
16892    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16893            int flags) {
16894        enforceNotIsolatedCaller("getServices");
16895        synchronized (this) {
16896            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16897        }
16898    }
16899
16900    @Override
16901    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16902        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16903        synchronized (this) {
16904            return mServices.getRunningServiceControlPanelLocked(name);
16905        }
16906    }
16907
16908    @Override
16909    public ComponentName startService(IApplicationThread caller, Intent service,
16910            String resolvedType, String callingPackage, int userId)
16911            throws TransactionTooLargeException {
16912        enforceNotIsolatedCaller("startService");
16913        // Refuse possible leaked file descriptors
16914        if (service != null && service.hasFileDescriptors() == true) {
16915            throw new IllegalArgumentException("File descriptors passed in Intent");
16916        }
16917
16918        if (callingPackage == null) {
16919            throw new IllegalArgumentException("callingPackage cannot be null");
16920        }
16921
16922        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16923                "startService: " + service + " type=" + resolvedType);
16924        synchronized(this) {
16925            final int callingPid = Binder.getCallingPid();
16926            final int callingUid = Binder.getCallingUid();
16927            final long origId = Binder.clearCallingIdentity();
16928            ComponentName res = mServices.startServiceLocked(caller, service,
16929                    resolvedType, callingPid, callingUid, callingPackage, userId);
16930            Binder.restoreCallingIdentity(origId);
16931            return res;
16932        }
16933    }
16934
16935    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16936            String callingPackage, int userId)
16937            throws TransactionTooLargeException {
16938        synchronized(this) {
16939            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16940                    "startServiceInPackage: " + service + " type=" + resolvedType);
16941            final long origId = Binder.clearCallingIdentity();
16942            ComponentName res = mServices.startServiceLocked(null, service,
16943                    resolvedType, -1, uid, callingPackage, userId);
16944            Binder.restoreCallingIdentity(origId);
16945            return res;
16946        }
16947    }
16948
16949    @Override
16950    public int stopService(IApplicationThread caller, Intent service,
16951            String resolvedType, int userId) {
16952        enforceNotIsolatedCaller("stopService");
16953        // Refuse possible leaked file descriptors
16954        if (service != null && service.hasFileDescriptors() == true) {
16955            throw new IllegalArgumentException("File descriptors passed in Intent");
16956        }
16957
16958        synchronized(this) {
16959            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16960        }
16961    }
16962
16963    @Override
16964    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16965        enforceNotIsolatedCaller("peekService");
16966        // Refuse possible leaked file descriptors
16967        if (service != null && service.hasFileDescriptors() == true) {
16968            throw new IllegalArgumentException("File descriptors passed in Intent");
16969        }
16970
16971        if (callingPackage == null) {
16972            throw new IllegalArgumentException("callingPackage cannot be null");
16973        }
16974
16975        synchronized(this) {
16976            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16977        }
16978    }
16979
16980    @Override
16981    public boolean stopServiceToken(ComponentName className, IBinder token,
16982            int startId) {
16983        synchronized(this) {
16984            return mServices.stopServiceTokenLocked(className, token, startId);
16985        }
16986    }
16987
16988    @Override
16989    public void setServiceForeground(ComponentName className, IBinder token,
16990            int id, Notification notification, int flags) {
16991        synchronized(this) {
16992            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16993        }
16994    }
16995
16996    @Override
16997    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16998            boolean requireFull, String name, String callerPackage) {
16999        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17000                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17001    }
17002
17003    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17004            String className, int flags) {
17005        boolean result = false;
17006        // For apps that don't have pre-defined UIDs, check for permission
17007        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17008            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17009                if (ActivityManager.checkUidPermission(
17010                        INTERACT_ACROSS_USERS,
17011                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17012                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17013                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17014                            + " requests FLAG_SINGLE_USER, but app does not hold "
17015                            + INTERACT_ACROSS_USERS;
17016                    Slog.w(TAG, msg);
17017                    throw new SecurityException(msg);
17018                }
17019                // Permission passed
17020                result = true;
17021            }
17022        } else if ("system".equals(componentProcessName)) {
17023            result = true;
17024        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17025            // Phone app and persistent apps are allowed to export singleuser providers.
17026            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17027                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17028        }
17029        if (DEBUG_MU) Slog.v(TAG_MU,
17030                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17031                + Integer.toHexString(flags) + ") = " + result);
17032        return result;
17033    }
17034
17035    /**
17036     * Checks to see if the caller is in the same app as the singleton
17037     * component, or the component is in a special app. It allows special apps
17038     * to export singleton components but prevents exporting singleton
17039     * components for regular apps.
17040     */
17041    boolean isValidSingletonCall(int callingUid, int componentUid) {
17042        int componentAppId = UserHandle.getAppId(componentUid);
17043        return UserHandle.isSameApp(callingUid, componentUid)
17044                || componentAppId == Process.SYSTEM_UID
17045                || componentAppId == Process.PHONE_UID
17046                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17047                        == PackageManager.PERMISSION_GRANTED;
17048    }
17049
17050    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17051            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17052            int userId) throws TransactionTooLargeException {
17053        enforceNotIsolatedCaller("bindService");
17054
17055        // Refuse possible leaked file descriptors
17056        if (service != null && service.hasFileDescriptors() == true) {
17057            throw new IllegalArgumentException("File descriptors passed in Intent");
17058        }
17059
17060        if (callingPackage == null) {
17061            throw new IllegalArgumentException("callingPackage cannot be null");
17062        }
17063
17064        synchronized(this) {
17065            return mServices.bindServiceLocked(caller, token, service,
17066                    resolvedType, connection, flags, callingPackage, userId);
17067        }
17068    }
17069
17070    public boolean unbindService(IServiceConnection connection) {
17071        synchronized (this) {
17072            return mServices.unbindServiceLocked(connection);
17073        }
17074    }
17075
17076    public void publishService(IBinder token, Intent intent, IBinder service) {
17077        // Refuse possible leaked file descriptors
17078        if (intent != null && intent.hasFileDescriptors() == true) {
17079            throw new IllegalArgumentException("File descriptors passed in Intent");
17080        }
17081
17082        synchronized(this) {
17083            if (!(token instanceof ServiceRecord)) {
17084                throw new IllegalArgumentException("Invalid service token");
17085            }
17086            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17087        }
17088    }
17089
17090    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17091        // Refuse possible leaked file descriptors
17092        if (intent != null && intent.hasFileDescriptors() == true) {
17093            throw new IllegalArgumentException("File descriptors passed in Intent");
17094        }
17095
17096        synchronized(this) {
17097            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17098        }
17099    }
17100
17101    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17102        synchronized(this) {
17103            if (!(token instanceof ServiceRecord)) {
17104                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17105                throw new IllegalArgumentException("Invalid service token");
17106            }
17107            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17108        }
17109    }
17110
17111    // =========================================================
17112    // BACKUP AND RESTORE
17113    // =========================================================
17114
17115    // Cause the target app to be launched if necessary and its backup agent
17116    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17117    // activity manager to announce its creation.
17118    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17119        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17120        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17121
17122        IPackageManager pm = AppGlobals.getPackageManager();
17123        ApplicationInfo app = null;
17124        try {
17125            app = pm.getApplicationInfo(packageName, 0, userId);
17126        } catch (RemoteException e) {
17127            // can't happen; package manager is process-local
17128        }
17129        if (app == null) {
17130            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17131            return false;
17132        }
17133
17134        synchronized(this) {
17135            // !!! TODO: currently no check here that we're already bound
17136            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17137            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17138            synchronized (stats) {
17139                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17140            }
17141
17142            // Backup agent is now in use, its package can't be stopped.
17143            try {
17144                AppGlobals.getPackageManager().setPackageStoppedState(
17145                        app.packageName, false, UserHandle.getUserId(app.uid));
17146            } catch (RemoteException e) {
17147            } catch (IllegalArgumentException e) {
17148                Slog.w(TAG, "Failed trying to unstop package "
17149                        + app.packageName + ": " + e);
17150            }
17151
17152            BackupRecord r = new BackupRecord(ss, app, backupMode);
17153            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17154                    ? new ComponentName(app.packageName, app.backupAgentName)
17155                    : new ComponentName("android", "FullBackupAgent");
17156            // startProcessLocked() returns existing proc's record if it's already running
17157            ProcessRecord proc = startProcessLocked(app.processName, app,
17158                    false, 0, "backup", hostingName, false, false, false);
17159            if (proc == null) {
17160                Slog.e(TAG, "Unable to start backup agent process " + r);
17161                return false;
17162            }
17163
17164            // If the app is a regular app (uid >= 10000) and not the system server or phone
17165            // process, etc, then mark it as being in full backup so that certain calls to the
17166            // process can be blocked. This is not reset to false anywhere because we kill the
17167            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17168            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17169                proc.inFullBackup = true;
17170            }
17171            r.app = proc;
17172            mBackupTarget = r;
17173            mBackupAppName = app.packageName;
17174
17175            // Try not to kill the process during backup
17176            updateOomAdjLocked(proc);
17177
17178            // If the process is already attached, schedule the creation of the backup agent now.
17179            // If it is not yet live, this will be done when it attaches to the framework.
17180            if (proc.thread != null) {
17181                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17182                try {
17183                    proc.thread.scheduleCreateBackupAgent(app,
17184                            compatibilityInfoForPackageLocked(app), backupMode);
17185                } catch (RemoteException e) {
17186                    // Will time out on the backup manager side
17187                }
17188            } else {
17189                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17190            }
17191            // Invariants: at this point, the target app process exists and the application
17192            // is either already running or in the process of coming up.  mBackupTarget and
17193            // mBackupAppName describe the app, so that when it binds back to the AM we
17194            // know that it's scheduled for a backup-agent operation.
17195        }
17196
17197        return true;
17198    }
17199
17200    @Override
17201    public void clearPendingBackup() {
17202        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17203        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17204
17205        synchronized (this) {
17206            mBackupTarget = null;
17207            mBackupAppName = null;
17208        }
17209    }
17210
17211    // A backup agent has just come up
17212    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17213        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17214                + " = " + agent);
17215
17216        synchronized(this) {
17217            if (!agentPackageName.equals(mBackupAppName)) {
17218                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17219                return;
17220            }
17221        }
17222
17223        long oldIdent = Binder.clearCallingIdentity();
17224        try {
17225            IBackupManager bm = IBackupManager.Stub.asInterface(
17226                    ServiceManager.getService(Context.BACKUP_SERVICE));
17227            bm.agentConnected(agentPackageName, agent);
17228        } catch (RemoteException e) {
17229            // can't happen; the backup manager service is local
17230        } catch (Exception e) {
17231            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17232            e.printStackTrace();
17233        } finally {
17234            Binder.restoreCallingIdentity(oldIdent);
17235        }
17236    }
17237
17238    // done with this agent
17239    public void unbindBackupAgent(ApplicationInfo appInfo) {
17240        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17241        if (appInfo == null) {
17242            Slog.w(TAG, "unbind backup agent for null app");
17243            return;
17244        }
17245
17246        synchronized(this) {
17247            try {
17248                if (mBackupAppName == null) {
17249                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17250                    return;
17251                }
17252
17253                if (!mBackupAppName.equals(appInfo.packageName)) {
17254                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17255                    return;
17256                }
17257
17258                // Not backing this app up any more; reset its OOM adjustment
17259                final ProcessRecord proc = mBackupTarget.app;
17260                updateOomAdjLocked(proc);
17261
17262                // If the app crashed during backup, 'thread' will be null here
17263                if (proc.thread != null) {
17264                    try {
17265                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17266                                compatibilityInfoForPackageLocked(appInfo));
17267                    } catch (Exception e) {
17268                        Slog.e(TAG, "Exception when unbinding backup agent:");
17269                        e.printStackTrace();
17270                    }
17271                }
17272            } finally {
17273                mBackupTarget = null;
17274                mBackupAppName = null;
17275            }
17276        }
17277    }
17278    // =========================================================
17279    // BROADCASTS
17280    // =========================================================
17281
17282    boolean isPendingBroadcastProcessLocked(int pid) {
17283        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17284                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17285    }
17286
17287    void skipPendingBroadcastLocked(int pid) {
17288            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17289            for (BroadcastQueue queue : mBroadcastQueues) {
17290                queue.skipPendingBroadcastLocked(pid);
17291            }
17292    }
17293
17294    // The app just attached; send any pending broadcasts that it should receive
17295    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17296        boolean didSomething = false;
17297        for (BroadcastQueue queue : mBroadcastQueues) {
17298            didSomething |= queue.sendPendingBroadcastsLocked(app);
17299        }
17300        return didSomething;
17301    }
17302
17303    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17304            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17305        enforceNotIsolatedCaller("registerReceiver");
17306        ArrayList<Intent> stickyIntents = null;
17307        ProcessRecord callerApp = null;
17308        int callingUid;
17309        int callingPid;
17310        synchronized(this) {
17311            if (caller != null) {
17312                callerApp = getRecordForAppLocked(caller);
17313                if (callerApp == null) {
17314                    throw new SecurityException(
17315                            "Unable to find app for caller " + caller
17316                            + " (pid=" + Binder.getCallingPid()
17317                            + ") when registering receiver " + receiver);
17318                }
17319                if (callerApp.info.uid != Process.SYSTEM_UID &&
17320                        !callerApp.pkgList.containsKey(callerPackage) &&
17321                        !"android".equals(callerPackage)) {
17322                    throw new SecurityException("Given caller package " + callerPackage
17323                            + " is not running in process " + callerApp);
17324                }
17325                callingUid = callerApp.info.uid;
17326                callingPid = callerApp.pid;
17327            } else {
17328                callerPackage = null;
17329                callingUid = Binder.getCallingUid();
17330                callingPid = Binder.getCallingPid();
17331            }
17332
17333            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17334                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17335
17336            Iterator<String> actions = filter.actionsIterator();
17337            if (actions == null) {
17338                ArrayList<String> noAction = new ArrayList<String>(1);
17339                noAction.add(null);
17340                actions = noAction.iterator();
17341            }
17342
17343            // Collect stickies of users
17344            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17345            while (actions.hasNext()) {
17346                String action = actions.next();
17347                for (int id : userIds) {
17348                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17349                    if (stickies != null) {
17350                        ArrayList<Intent> intents = stickies.get(action);
17351                        if (intents != null) {
17352                            if (stickyIntents == null) {
17353                                stickyIntents = new ArrayList<Intent>();
17354                            }
17355                            stickyIntents.addAll(intents);
17356                        }
17357                    }
17358                }
17359            }
17360        }
17361
17362        ArrayList<Intent> allSticky = null;
17363        if (stickyIntents != null) {
17364            final ContentResolver resolver = mContext.getContentResolver();
17365            // Look for any matching sticky broadcasts...
17366            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17367                Intent intent = stickyIntents.get(i);
17368                // If intent has scheme "content", it will need to acccess
17369                // provider that needs to lock mProviderMap in ActivityThread
17370                // and also it may need to wait application response, so we
17371                // cannot lock ActivityManagerService here.
17372                if (filter.match(resolver, intent, true, TAG) >= 0) {
17373                    if (allSticky == null) {
17374                        allSticky = new ArrayList<Intent>();
17375                    }
17376                    allSticky.add(intent);
17377                }
17378            }
17379        }
17380
17381        // The first sticky in the list is returned directly back to the client.
17382        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17383        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17384        if (receiver == null) {
17385            return sticky;
17386        }
17387
17388        synchronized (this) {
17389            if (callerApp != null && (callerApp.thread == null
17390                    || callerApp.thread.asBinder() != caller.asBinder())) {
17391                // Original caller already died
17392                return null;
17393            }
17394            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17395            if (rl == null) {
17396                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17397                        userId, receiver);
17398                if (rl.app != null) {
17399                    rl.app.receivers.add(rl);
17400                } else {
17401                    try {
17402                        receiver.asBinder().linkToDeath(rl, 0);
17403                    } catch (RemoteException e) {
17404                        return sticky;
17405                    }
17406                    rl.linkedToDeath = true;
17407                }
17408                mRegisteredReceivers.put(receiver.asBinder(), rl);
17409            } else if (rl.uid != callingUid) {
17410                throw new IllegalArgumentException(
17411                        "Receiver requested to register for uid " + callingUid
17412                        + " was previously registered for uid " + rl.uid);
17413            } else if (rl.pid != callingPid) {
17414                throw new IllegalArgumentException(
17415                        "Receiver requested to register for pid " + callingPid
17416                        + " was previously registered for pid " + rl.pid);
17417            } else if (rl.userId != userId) {
17418                throw new IllegalArgumentException(
17419                        "Receiver requested to register for user " + userId
17420                        + " was previously registered for user " + rl.userId);
17421            }
17422            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17423                    permission, callingUid, userId);
17424            rl.add(bf);
17425            if (!bf.debugCheck()) {
17426                Slog.w(TAG, "==> For Dynamic broadcast");
17427            }
17428            mReceiverResolver.addFilter(bf);
17429
17430            // Enqueue broadcasts for all existing stickies that match
17431            // this filter.
17432            if (allSticky != null) {
17433                ArrayList receivers = new ArrayList();
17434                receivers.add(bf);
17435
17436                final int stickyCount = allSticky.size();
17437                for (int i = 0; i < stickyCount; i++) {
17438                    Intent intent = allSticky.get(i);
17439                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17440                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17441                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17442                            null, 0, null, null, false, true, true, -1);
17443                    queue.enqueueParallelBroadcastLocked(r);
17444                    queue.scheduleBroadcastsLocked();
17445                }
17446            }
17447
17448            return sticky;
17449        }
17450    }
17451
17452    public void unregisterReceiver(IIntentReceiver receiver) {
17453        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17454
17455        final long origId = Binder.clearCallingIdentity();
17456        try {
17457            boolean doTrim = false;
17458
17459            synchronized(this) {
17460                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17461                if (rl != null) {
17462                    final BroadcastRecord r = rl.curBroadcast;
17463                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17464                        final boolean doNext = r.queue.finishReceiverLocked(
17465                                r, r.resultCode, r.resultData, r.resultExtras,
17466                                r.resultAbort, false);
17467                        if (doNext) {
17468                            doTrim = true;
17469                            r.queue.processNextBroadcast(false);
17470                        }
17471                    }
17472
17473                    if (rl.app != null) {
17474                        rl.app.receivers.remove(rl);
17475                    }
17476                    removeReceiverLocked(rl);
17477                    if (rl.linkedToDeath) {
17478                        rl.linkedToDeath = false;
17479                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17480                    }
17481                }
17482            }
17483
17484            // If we actually concluded any broadcasts, we might now be able
17485            // to trim the recipients' apps from our working set
17486            if (doTrim) {
17487                trimApplications();
17488                return;
17489            }
17490
17491        } finally {
17492            Binder.restoreCallingIdentity(origId);
17493        }
17494    }
17495
17496    void removeReceiverLocked(ReceiverList rl) {
17497        mRegisteredReceivers.remove(rl.receiver.asBinder());
17498        for (int i = rl.size() - 1; i >= 0; i--) {
17499            mReceiverResolver.removeFilter(rl.get(i));
17500        }
17501    }
17502
17503    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17504        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17505            ProcessRecord r = mLruProcesses.get(i);
17506            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17507                try {
17508                    r.thread.dispatchPackageBroadcast(cmd, packages);
17509                } catch (RemoteException ex) {
17510                }
17511            }
17512        }
17513    }
17514
17515    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17516            int callingUid, int[] users) {
17517        // TODO: come back and remove this assumption to triage all broadcasts
17518        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17519
17520        List<ResolveInfo> receivers = null;
17521        try {
17522            HashSet<ComponentName> singleUserReceivers = null;
17523            boolean scannedFirstReceivers = false;
17524            for (int user : users) {
17525                // Skip users that have Shell restrictions, with exception of always permitted
17526                // Shell broadcasts
17527                if (callingUid == Process.SHELL_UID
17528                        && mUserController.hasUserRestriction(
17529                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17530                        && !isPermittedShellBroadcast(intent)) {
17531                    continue;
17532                }
17533                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17534                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17535                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17536                    // If this is not the system user, we need to check for
17537                    // any receivers that should be filtered out.
17538                    for (int i=0; i<newReceivers.size(); i++) {
17539                        ResolveInfo ri = newReceivers.get(i);
17540                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17541                            newReceivers.remove(i);
17542                            i--;
17543                        }
17544                    }
17545                }
17546                if (newReceivers != null && newReceivers.size() == 0) {
17547                    newReceivers = null;
17548                }
17549                if (receivers == null) {
17550                    receivers = newReceivers;
17551                } else if (newReceivers != null) {
17552                    // We need to concatenate the additional receivers
17553                    // found with what we have do far.  This would be easy,
17554                    // but we also need to de-dup any receivers that are
17555                    // singleUser.
17556                    if (!scannedFirstReceivers) {
17557                        // Collect any single user receivers we had already retrieved.
17558                        scannedFirstReceivers = true;
17559                        for (int i=0; i<receivers.size(); i++) {
17560                            ResolveInfo ri = receivers.get(i);
17561                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17562                                ComponentName cn = new ComponentName(
17563                                        ri.activityInfo.packageName, ri.activityInfo.name);
17564                                if (singleUserReceivers == null) {
17565                                    singleUserReceivers = new HashSet<ComponentName>();
17566                                }
17567                                singleUserReceivers.add(cn);
17568                            }
17569                        }
17570                    }
17571                    // Add the new results to the existing results, tracking
17572                    // and de-dupping single user receivers.
17573                    for (int i=0; i<newReceivers.size(); i++) {
17574                        ResolveInfo ri = newReceivers.get(i);
17575                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17576                            ComponentName cn = new ComponentName(
17577                                    ri.activityInfo.packageName, ri.activityInfo.name);
17578                            if (singleUserReceivers == null) {
17579                                singleUserReceivers = new HashSet<ComponentName>();
17580                            }
17581                            if (!singleUserReceivers.contains(cn)) {
17582                                singleUserReceivers.add(cn);
17583                                receivers.add(ri);
17584                            }
17585                        } else {
17586                            receivers.add(ri);
17587                        }
17588                    }
17589                }
17590            }
17591        } catch (RemoteException ex) {
17592            // pm is in same process, this will never happen.
17593        }
17594        return receivers;
17595    }
17596
17597    private boolean isPermittedShellBroadcast(Intent intent) {
17598        // remote bugreport should always be allowed to be taken
17599        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17600    }
17601
17602    final int broadcastIntentLocked(ProcessRecord callerApp,
17603            String callerPackage, Intent intent, String resolvedType,
17604            IIntentReceiver resultTo, int resultCode, String resultData,
17605            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17606            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17607        intent = new Intent(intent);
17608
17609        // By default broadcasts do not go to stopped apps.
17610        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17611
17612        // If we have not finished booting, don't allow this to launch new processes.
17613        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17614            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17615        }
17616
17617        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17618                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17619                + " ordered=" + ordered + " userid=" + userId);
17620        if ((resultTo != null) && !ordered) {
17621            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17622        }
17623
17624        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17625                ALLOW_NON_FULL, "broadcast", callerPackage);
17626
17627        // Make sure that the user who is receiving this broadcast is running.
17628        // If not, we will just skip it. Make an exception for shutdown broadcasts
17629        // and upgrade steps.
17630
17631        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17632            if ((callingUid != Process.SYSTEM_UID
17633                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17634                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17635                Slog.w(TAG, "Skipping broadcast of " + intent
17636                        + ": user " + userId + " is stopped");
17637                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17638            }
17639        }
17640
17641        BroadcastOptions brOptions = null;
17642        if (bOptions != null) {
17643            brOptions = new BroadcastOptions(bOptions);
17644            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17645                // See if the caller is allowed to do this.  Note we are checking against
17646                // the actual real caller (not whoever provided the operation as say a
17647                // PendingIntent), because that who is actually supplied the arguments.
17648                if (checkComponentPermission(
17649                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17650                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17651                        != PackageManager.PERMISSION_GRANTED) {
17652                    String msg = "Permission Denial: " + intent.getAction()
17653                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17654                            + ", uid=" + callingUid + ")"
17655                            + " requires "
17656                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17657                    Slog.w(TAG, msg);
17658                    throw new SecurityException(msg);
17659                }
17660            }
17661        }
17662
17663        // Verify that protected broadcasts are only being sent by system code,
17664        // and that system code is only sending protected broadcasts.
17665        final String action = intent.getAction();
17666        final boolean isProtectedBroadcast;
17667        try {
17668            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17669        } catch (RemoteException e) {
17670            Slog.w(TAG, "Remote exception", e);
17671            return ActivityManager.BROADCAST_SUCCESS;
17672        }
17673
17674        final boolean isCallerSystem;
17675        switch (UserHandle.getAppId(callingUid)) {
17676            case Process.ROOT_UID:
17677            case Process.SYSTEM_UID:
17678            case Process.PHONE_UID:
17679            case Process.BLUETOOTH_UID:
17680            case Process.NFC_UID:
17681                isCallerSystem = true;
17682                break;
17683            default:
17684                isCallerSystem = (callerApp != null) && callerApp.persistent;
17685                break;
17686        }
17687
17688        if (isCallerSystem) {
17689            if (isProtectedBroadcast
17690                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17691                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17692                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17693                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17694                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17695                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17696                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17697                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17698                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17699                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17700                // Broadcast is either protected, or it's a public action that
17701                // we've relaxed, so it's fine for system internals to send.
17702            } else {
17703                // The vast majority of broadcasts sent from system internals
17704                // should be protected to avoid security holes, so yell loudly
17705                // to ensure we examine these cases.
17706                if (callerApp != null) {
17707                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17708                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17709                            new Throwable());
17710                } else {
17711                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17712                            + " from system uid " + UserHandle.formatUid(callingUid)
17713                            + " pkg " + callerPackage,
17714                            new Throwable());
17715                }
17716            }
17717
17718        } else {
17719            if (isProtectedBroadcast) {
17720                String msg = "Permission Denial: not allowed to send broadcast "
17721                        + action + " from pid="
17722                        + callingPid + ", uid=" + callingUid;
17723                Slog.w(TAG, msg);
17724                throw new SecurityException(msg);
17725
17726            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17727                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17728                // Special case for compatibility: we don't want apps to send this,
17729                // but historically it has not been protected and apps may be using it
17730                // to poke their own app widget.  So, instead of making it protected,
17731                // just limit it to the caller.
17732                if (callerPackage == null) {
17733                    String msg = "Permission Denial: not allowed to send broadcast "
17734                            + action + " from unknown caller.";
17735                    Slog.w(TAG, msg);
17736                    throw new SecurityException(msg);
17737                } else if (intent.getComponent() != null) {
17738                    // They are good enough to send to an explicit component...  verify
17739                    // it is being sent to the calling app.
17740                    if (!intent.getComponent().getPackageName().equals(
17741                            callerPackage)) {
17742                        String msg = "Permission Denial: not allowed to send broadcast "
17743                                + action + " to "
17744                                + intent.getComponent().getPackageName() + " from "
17745                                + callerPackage;
17746                        Slog.w(TAG, msg);
17747                        throw new SecurityException(msg);
17748                    }
17749                } else {
17750                    // Limit broadcast to their own package.
17751                    intent.setPackage(callerPackage);
17752                }
17753            }
17754        }
17755
17756        if (action != null) {
17757            switch (action) {
17758                case Intent.ACTION_UID_REMOVED:
17759                case Intent.ACTION_PACKAGE_REMOVED:
17760                case Intent.ACTION_PACKAGE_CHANGED:
17761                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17762                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17763                case Intent.ACTION_PACKAGES_SUSPENDED:
17764                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17765                    // Handle special intents: if this broadcast is from the package
17766                    // manager about a package being removed, we need to remove all of
17767                    // its activities from the history stack.
17768                    if (checkComponentPermission(
17769                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17770                            callingPid, callingUid, -1, true)
17771                            != PackageManager.PERMISSION_GRANTED) {
17772                        String msg = "Permission Denial: " + intent.getAction()
17773                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17774                                + ", uid=" + callingUid + ")"
17775                                + " requires "
17776                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17777                        Slog.w(TAG, msg);
17778                        throw new SecurityException(msg);
17779                    }
17780                    switch (action) {
17781                        case Intent.ACTION_UID_REMOVED:
17782                            final Bundle intentExtras = intent.getExtras();
17783                            final int uid = intentExtras != null
17784                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17785                            if (uid >= 0) {
17786                                mBatteryStatsService.removeUid(uid);
17787                                mAppOpsService.uidRemoved(uid);
17788                            }
17789                            break;
17790                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17791                            // If resources are unavailable just force stop all those packages
17792                            // and flush the attribute cache as well.
17793                            String list[] =
17794                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17795                            if (list != null && list.length > 0) {
17796                                for (int i = 0; i < list.length; i++) {
17797                                    forceStopPackageLocked(list[i], -1, false, true, true,
17798                                            false, false, userId, "storage unmount");
17799                                }
17800                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17801                                sendPackageBroadcastLocked(
17802                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17803                                        userId);
17804                            }
17805                            break;
17806                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17807                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17808                            break;
17809                        case Intent.ACTION_PACKAGE_REMOVED:
17810                        case Intent.ACTION_PACKAGE_CHANGED:
17811                            Uri data = intent.getData();
17812                            String ssp;
17813                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17814                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17815                                final boolean replacing =
17816                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17817                                final boolean killProcess =
17818                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17819                                final boolean fullUninstall = removed && !replacing;
17820                                if (removed) {
17821                                    if (killProcess) {
17822                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17823                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17824                                                false, true, true, false, fullUninstall, userId,
17825                                                removed ? "pkg removed" : "pkg changed");
17826                                    }
17827                                    final int cmd = killProcess
17828                                            ? IApplicationThread.PACKAGE_REMOVED
17829                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17830                                    sendPackageBroadcastLocked(cmd,
17831                                            new String[] {ssp}, userId);
17832                                    if (fullUninstall) {
17833                                        mAppOpsService.packageRemoved(
17834                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17835
17836                                        // Remove all permissions granted from/to this package
17837                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17838
17839                                        removeTasksByPackageNameLocked(ssp, userId);
17840
17841                                        // Hide the "unsupported display" dialog if necessary.
17842                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17843                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17844                                            mUnsupportedDisplaySizeDialog.dismiss();
17845                                            mUnsupportedDisplaySizeDialog = null;
17846                                        }
17847                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17848                                        mBatteryStatsService.notePackageUninstalled(ssp);
17849                                    }
17850                                } else {
17851                                    if (killProcess) {
17852                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17853                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17854                                                userId, ProcessList.INVALID_ADJ,
17855                                                false, true, true, false, "change " + ssp);
17856                                    }
17857                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17858                                            intent.getStringArrayExtra(
17859                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17860                                }
17861                            }
17862                            break;
17863                        case Intent.ACTION_PACKAGES_SUSPENDED:
17864                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17865                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17866                                    intent.getAction());
17867                            final String[] packageNames = intent.getStringArrayExtra(
17868                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17869                            final int userHandle = intent.getIntExtra(
17870                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17871
17872                            synchronized(ActivityManagerService.this) {
17873                                mRecentTasks.onPackagesSuspendedChanged(
17874                                        packageNames, suspended, userHandle);
17875                            }
17876                            break;
17877                    }
17878                    break;
17879                case Intent.ACTION_PACKAGE_REPLACED:
17880                {
17881                    final Uri data = intent.getData();
17882                    final String ssp;
17883                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17884                        final ApplicationInfo aInfo =
17885                                getPackageManagerInternalLocked().getApplicationInfo(
17886                                        ssp,
17887                                        userId);
17888                        if (aInfo == null) {
17889                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17890                                    + " ssp=" + ssp + " data=" + data);
17891                            return ActivityManager.BROADCAST_SUCCESS;
17892                        }
17893                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17894                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17895                                new String[] {ssp}, userId);
17896                    }
17897                    break;
17898                }
17899                case Intent.ACTION_PACKAGE_ADDED:
17900                {
17901                    // Special case for adding a package: by default turn on compatibility mode.
17902                    Uri data = intent.getData();
17903                    String ssp;
17904                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17905                        final boolean replacing =
17906                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17907                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17908
17909                        try {
17910                            ApplicationInfo ai = AppGlobals.getPackageManager().
17911                                    getApplicationInfo(ssp, 0, 0);
17912                            mBatteryStatsService.notePackageInstalled(ssp,
17913                                    ai != null ? ai.versionCode : 0);
17914                        } catch (RemoteException e) {
17915                        }
17916                    }
17917                    break;
17918                }
17919                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17920                {
17921                    Uri data = intent.getData();
17922                    String ssp;
17923                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17924                        // Hide the "unsupported display" dialog if necessary.
17925                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17926                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17927                            mUnsupportedDisplaySizeDialog.dismiss();
17928                            mUnsupportedDisplaySizeDialog = null;
17929                        }
17930                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17931                    }
17932                    break;
17933                }
17934                case Intent.ACTION_TIMEZONE_CHANGED:
17935                    // If this is the time zone changed action, queue up a message that will reset
17936                    // the timezone of all currently running processes. This message will get
17937                    // queued up before the broadcast happens.
17938                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17939                    break;
17940                case Intent.ACTION_TIME_CHANGED:
17941                    // If the user set the time, let all running processes know.
17942                    final int is24Hour =
17943                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17944                                    : 0;
17945                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17946                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17947                    synchronized (stats) {
17948                        stats.noteCurrentTimeChangedLocked();
17949                    }
17950                    break;
17951                case Intent.ACTION_CLEAR_DNS_CACHE:
17952                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17953                    break;
17954                case Proxy.PROXY_CHANGE_ACTION:
17955                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17956                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17957                    break;
17958                case android.hardware.Camera.ACTION_NEW_PICTURE:
17959                case android.hardware.Camera.ACTION_NEW_VIDEO:
17960                    // These broadcasts are no longer allowed by the system, since they can
17961                    // cause significant thrashing at a crictical point (using the camera).
17962                    // Apps should use JobScehduler to monitor for media provider changes.
17963                    Slog.w(TAG, action + " no longer allowed; dropping from "
17964                            + UserHandle.formatUid(callingUid));
17965                    if (resultTo != null) {
17966                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17967                        try {
17968                            queue.performReceiveLocked(callerApp, resultTo, intent,
17969                                    Activity.RESULT_CANCELED, null, null,
17970                                    false, false, userId);
17971                        } catch (RemoteException e) {
17972                            Slog.w(TAG, "Failure ["
17973                                    + queue.mQueueName + "] sending broadcast result of "
17974                                    + intent, e);
17975
17976                        }
17977                    }
17978                    // Lie; we don't want to crash the app.
17979                    return ActivityManager.BROADCAST_SUCCESS;
17980            }
17981        }
17982
17983        // Add to the sticky list if requested.
17984        if (sticky) {
17985            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17986                    callingPid, callingUid)
17987                    != PackageManager.PERMISSION_GRANTED) {
17988                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17989                        + callingPid + ", uid=" + callingUid
17990                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17991                Slog.w(TAG, msg);
17992                throw new SecurityException(msg);
17993            }
17994            if (requiredPermissions != null && requiredPermissions.length > 0) {
17995                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17996                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17997                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17998            }
17999            if (intent.getComponent() != null) {
18000                throw new SecurityException(
18001                        "Sticky broadcasts can't target a specific component");
18002            }
18003            // We use userId directly here, since the "all" target is maintained
18004            // as a separate set of sticky broadcasts.
18005            if (userId != UserHandle.USER_ALL) {
18006                // But first, if this is not a broadcast to all users, then
18007                // make sure it doesn't conflict with an existing broadcast to
18008                // all users.
18009                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18010                        UserHandle.USER_ALL);
18011                if (stickies != null) {
18012                    ArrayList<Intent> list = stickies.get(intent.getAction());
18013                    if (list != null) {
18014                        int N = list.size();
18015                        int i;
18016                        for (i=0; i<N; i++) {
18017                            if (intent.filterEquals(list.get(i))) {
18018                                throw new IllegalArgumentException(
18019                                        "Sticky broadcast " + intent + " for user "
18020                                        + userId + " conflicts with existing global broadcast");
18021                            }
18022                        }
18023                    }
18024                }
18025            }
18026            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18027            if (stickies == null) {
18028                stickies = new ArrayMap<>();
18029                mStickyBroadcasts.put(userId, stickies);
18030            }
18031            ArrayList<Intent> list = stickies.get(intent.getAction());
18032            if (list == null) {
18033                list = new ArrayList<>();
18034                stickies.put(intent.getAction(), list);
18035            }
18036            final int stickiesCount = list.size();
18037            int i;
18038            for (i = 0; i < stickiesCount; i++) {
18039                if (intent.filterEquals(list.get(i))) {
18040                    // This sticky already exists, replace it.
18041                    list.set(i, new Intent(intent));
18042                    break;
18043                }
18044            }
18045            if (i >= stickiesCount) {
18046                list.add(new Intent(intent));
18047            }
18048        }
18049
18050        int[] users;
18051        if (userId == UserHandle.USER_ALL) {
18052            // Caller wants broadcast to go to all started users.
18053            users = mUserController.getStartedUserArrayLocked();
18054        } else {
18055            // Caller wants broadcast to go to one specific user.
18056            users = new int[] {userId};
18057        }
18058
18059        // Figure out who all will receive this broadcast.
18060        List receivers = null;
18061        List<BroadcastFilter> registeredReceivers = null;
18062        // Need to resolve the intent to interested receivers...
18063        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18064                 == 0) {
18065            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18066        }
18067        if (intent.getComponent() == null) {
18068            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18069                // Query one target user at a time, excluding shell-restricted users
18070                for (int i = 0; i < users.length; i++) {
18071                    if (mUserController.hasUserRestriction(
18072                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18073                        continue;
18074                    }
18075                    List<BroadcastFilter> registeredReceiversForUser =
18076                            mReceiverResolver.queryIntent(intent,
18077                                    resolvedType, false, users[i]);
18078                    if (registeredReceivers == null) {
18079                        registeredReceivers = registeredReceiversForUser;
18080                    } else if (registeredReceiversForUser != null) {
18081                        registeredReceivers.addAll(registeredReceiversForUser);
18082                    }
18083                }
18084            } else {
18085                registeredReceivers = mReceiverResolver.queryIntent(intent,
18086                        resolvedType, false, userId);
18087            }
18088        }
18089
18090        final boolean replacePending =
18091                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18092
18093        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18094                + " replacePending=" + replacePending);
18095
18096        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18097        if (!ordered && NR > 0) {
18098            // If we are not serializing this broadcast, then send the
18099            // registered receivers separately so they don't wait for the
18100            // components to be launched.
18101            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18102            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18103                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18104                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18105                    resultExtras, ordered, sticky, false, userId);
18106            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18107            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18108            if (!replaced) {
18109                queue.enqueueParallelBroadcastLocked(r);
18110                queue.scheduleBroadcastsLocked();
18111            }
18112            registeredReceivers = null;
18113            NR = 0;
18114        }
18115
18116        // Merge into one list.
18117        int ir = 0;
18118        if (receivers != null) {
18119            // A special case for PACKAGE_ADDED: do not allow the package
18120            // being added to see this broadcast.  This prevents them from
18121            // using this as a back door to get run as soon as they are
18122            // installed.  Maybe in the future we want to have a special install
18123            // broadcast or such for apps, but we'd like to deliberately make
18124            // this decision.
18125            String skipPackages[] = null;
18126            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18127                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18128                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18129                Uri data = intent.getData();
18130                if (data != null) {
18131                    String pkgName = data.getSchemeSpecificPart();
18132                    if (pkgName != null) {
18133                        skipPackages = new String[] { pkgName };
18134                    }
18135                }
18136            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18137                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18138            }
18139            if (skipPackages != null && (skipPackages.length > 0)) {
18140                for (String skipPackage : skipPackages) {
18141                    if (skipPackage != null) {
18142                        int NT = receivers.size();
18143                        for (int it=0; it<NT; it++) {
18144                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18145                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18146                                receivers.remove(it);
18147                                it--;
18148                                NT--;
18149                            }
18150                        }
18151                    }
18152                }
18153            }
18154
18155            int NT = receivers != null ? receivers.size() : 0;
18156            int it = 0;
18157            ResolveInfo curt = null;
18158            BroadcastFilter curr = null;
18159            while (it < NT && ir < NR) {
18160                if (curt == null) {
18161                    curt = (ResolveInfo)receivers.get(it);
18162                }
18163                if (curr == null) {
18164                    curr = registeredReceivers.get(ir);
18165                }
18166                if (curr.getPriority() >= curt.priority) {
18167                    // Insert this broadcast record into the final list.
18168                    receivers.add(it, curr);
18169                    ir++;
18170                    curr = null;
18171                    it++;
18172                    NT++;
18173                } else {
18174                    // Skip to the next ResolveInfo in the final list.
18175                    it++;
18176                    curt = null;
18177                }
18178            }
18179        }
18180        while (ir < NR) {
18181            if (receivers == null) {
18182                receivers = new ArrayList();
18183            }
18184            receivers.add(registeredReceivers.get(ir));
18185            ir++;
18186        }
18187
18188        if ((receivers != null && receivers.size() > 0)
18189                || resultTo != null) {
18190            BroadcastQueue queue = broadcastQueueForIntent(intent);
18191            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18192                    callerPackage, callingPid, callingUid, resolvedType,
18193                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18194                    resultData, resultExtras, ordered, sticky, false, userId);
18195
18196            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18197                    + ": prev had " + queue.mOrderedBroadcasts.size());
18198            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18199                    "Enqueueing broadcast " + r.intent.getAction());
18200
18201            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18202            if (!replaced) {
18203                queue.enqueueOrderedBroadcastLocked(r);
18204                queue.scheduleBroadcastsLocked();
18205            }
18206        } else {
18207            // There was nobody interested in the broadcast, but we still want to record
18208            // that it happened.
18209            if (intent.getComponent() == null && intent.getPackage() == null
18210                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18211                // This was an implicit broadcast... let's record it for posterity.
18212                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18213            }
18214        }
18215
18216        return ActivityManager.BROADCAST_SUCCESS;
18217    }
18218
18219    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18220            int skipCount, long dispatchTime) {
18221        final long now = SystemClock.elapsedRealtime();
18222        if (mCurBroadcastStats == null ||
18223                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18224            mLastBroadcastStats = mCurBroadcastStats;
18225            if (mLastBroadcastStats != null) {
18226                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18227                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18228            }
18229            mCurBroadcastStats = new BroadcastStats();
18230        }
18231        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18232    }
18233
18234    final Intent verifyBroadcastLocked(Intent intent) {
18235        // Refuse possible leaked file descriptors
18236        if (intent != null && intent.hasFileDescriptors() == true) {
18237            throw new IllegalArgumentException("File descriptors passed in Intent");
18238        }
18239
18240        int flags = intent.getFlags();
18241
18242        if (!mProcessesReady) {
18243            // if the caller really truly claims to know what they're doing, go
18244            // ahead and allow the broadcast without launching any receivers
18245            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18246                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18247            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18248                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18249                        + " before boot completion");
18250                throw new IllegalStateException("Cannot broadcast before boot completed");
18251            }
18252        }
18253
18254        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18255            throw new IllegalArgumentException(
18256                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18257        }
18258
18259        return intent;
18260    }
18261
18262    public final int broadcastIntent(IApplicationThread caller,
18263            Intent intent, String resolvedType, IIntentReceiver resultTo,
18264            int resultCode, String resultData, Bundle resultExtras,
18265            String[] requiredPermissions, int appOp, Bundle bOptions,
18266            boolean serialized, boolean sticky, int userId) {
18267        enforceNotIsolatedCaller("broadcastIntent");
18268        synchronized(this) {
18269            intent = verifyBroadcastLocked(intent);
18270
18271            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18272            final int callingPid = Binder.getCallingPid();
18273            final int callingUid = Binder.getCallingUid();
18274            final long origId = Binder.clearCallingIdentity();
18275            int res = broadcastIntentLocked(callerApp,
18276                    callerApp != null ? callerApp.info.packageName : null,
18277                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18278                    requiredPermissions, appOp, bOptions, serialized, sticky,
18279                    callingPid, callingUid, userId);
18280            Binder.restoreCallingIdentity(origId);
18281            return res;
18282        }
18283    }
18284
18285
18286    int broadcastIntentInPackage(String packageName, int uid,
18287            Intent intent, String resolvedType, IIntentReceiver resultTo,
18288            int resultCode, String resultData, Bundle resultExtras,
18289            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18290            int userId) {
18291        synchronized(this) {
18292            intent = verifyBroadcastLocked(intent);
18293
18294            final long origId = Binder.clearCallingIdentity();
18295            String[] requiredPermissions = requiredPermission == null ? null
18296                    : new String[] {requiredPermission};
18297            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18298                    resultTo, resultCode, resultData, resultExtras,
18299                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18300                    sticky, -1, uid, userId);
18301            Binder.restoreCallingIdentity(origId);
18302            return res;
18303        }
18304    }
18305
18306    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18307        // Refuse possible leaked file descriptors
18308        if (intent != null && intent.hasFileDescriptors() == true) {
18309            throw new IllegalArgumentException("File descriptors passed in Intent");
18310        }
18311
18312        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18313                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18314
18315        synchronized(this) {
18316            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18317                    != PackageManager.PERMISSION_GRANTED) {
18318                String msg = "Permission Denial: unbroadcastIntent() from pid="
18319                        + Binder.getCallingPid()
18320                        + ", uid=" + Binder.getCallingUid()
18321                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18322                Slog.w(TAG, msg);
18323                throw new SecurityException(msg);
18324            }
18325            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18326            if (stickies != null) {
18327                ArrayList<Intent> list = stickies.get(intent.getAction());
18328                if (list != null) {
18329                    int N = list.size();
18330                    int i;
18331                    for (i=0; i<N; i++) {
18332                        if (intent.filterEquals(list.get(i))) {
18333                            list.remove(i);
18334                            break;
18335                        }
18336                    }
18337                    if (list.size() <= 0) {
18338                        stickies.remove(intent.getAction());
18339                    }
18340                }
18341                if (stickies.size() <= 0) {
18342                    mStickyBroadcasts.remove(userId);
18343                }
18344            }
18345        }
18346    }
18347
18348    void backgroundServicesFinishedLocked(int userId) {
18349        for (BroadcastQueue queue : mBroadcastQueues) {
18350            queue.backgroundServicesFinishedLocked(userId);
18351        }
18352    }
18353
18354    public void finishReceiver(IBinder who, int resultCode, String resultData,
18355            Bundle resultExtras, boolean resultAbort, int flags) {
18356        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18357
18358        // Refuse possible leaked file descriptors
18359        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18360            throw new IllegalArgumentException("File descriptors passed in Bundle");
18361        }
18362
18363        final long origId = Binder.clearCallingIdentity();
18364        try {
18365            boolean doNext = false;
18366            BroadcastRecord r;
18367
18368            synchronized(this) {
18369                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18370                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18371                r = queue.getMatchingOrderedReceiver(who);
18372                if (r != null) {
18373                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18374                        resultData, resultExtras, resultAbort, true);
18375                }
18376            }
18377
18378            if (doNext) {
18379                r.queue.processNextBroadcast(false);
18380            }
18381            trimApplications();
18382        } finally {
18383            Binder.restoreCallingIdentity(origId);
18384        }
18385    }
18386
18387    // =========================================================
18388    // INSTRUMENTATION
18389    // =========================================================
18390
18391    public boolean startInstrumentation(ComponentName className,
18392            String profileFile, int flags, Bundle arguments,
18393            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18394            int userId, String abiOverride) {
18395        enforceNotIsolatedCaller("startInstrumentation");
18396        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18397                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18398        // Refuse possible leaked file descriptors
18399        if (arguments != null && arguments.hasFileDescriptors()) {
18400            throw new IllegalArgumentException("File descriptors passed in Bundle");
18401        }
18402
18403        synchronized(this) {
18404            InstrumentationInfo ii = null;
18405            ApplicationInfo ai = null;
18406            try {
18407                ii = mContext.getPackageManager().getInstrumentationInfo(
18408                    className, STOCK_PM_FLAGS);
18409                ai = AppGlobals.getPackageManager().getApplicationInfo(
18410                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18411            } catch (PackageManager.NameNotFoundException e) {
18412            } catch (RemoteException e) {
18413            }
18414            if (ii == null) {
18415                reportStartInstrumentationFailureLocked(watcher, className,
18416                        "Unable to find instrumentation info for: " + className);
18417                return false;
18418            }
18419            if (ai == null) {
18420                reportStartInstrumentationFailureLocked(watcher, className,
18421                        "Unable to find instrumentation target package: " + ii.targetPackage);
18422                return false;
18423            }
18424            if (!ai.hasCode()) {
18425                reportStartInstrumentationFailureLocked(watcher, className,
18426                        "Instrumentation target has no code: " + ii.targetPackage);
18427                return false;
18428            }
18429
18430            int match = mContext.getPackageManager().checkSignatures(
18431                    ii.targetPackage, ii.packageName);
18432            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18433                String msg = "Permission Denial: starting instrumentation "
18434                        + className + " from pid="
18435                        + Binder.getCallingPid()
18436                        + ", uid=" + Binder.getCallingPid()
18437                        + " not allowed because package " + ii.packageName
18438                        + " does not have a signature matching the target "
18439                        + ii.targetPackage;
18440                reportStartInstrumentationFailureLocked(watcher, className, msg);
18441                throw new SecurityException(msg);
18442            }
18443
18444            final long origId = Binder.clearCallingIdentity();
18445            // Instrumentation can kill and relaunch even persistent processes
18446            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18447                    "start instr");
18448            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18449            app.instrumentationClass = className;
18450            app.instrumentationInfo = ai;
18451            app.instrumentationProfileFile = profileFile;
18452            app.instrumentationArguments = arguments;
18453            app.instrumentationWatcher = watcher;
18454            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18455            app.instrumentationResultClass = className;
18456            Binder.restoreCallingIdentity(origId);
18457        }
18458
18459        return true;
18460    }
18461
18462    /**
18463     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18464     * error to the logs, but if somebody is watching, send the report there too.  This enables
18465     * the "am" command to report errors with more information.
18466     *
18467     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18468     * @param cn The component name of the instrumentation.
18469     * @param report The error report.
18470     */
18471    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18472            ComponentName cn, String report) {
18473        Slog.w(TAG, report);
18474        if (watcher != null) {
18475            Bundle results = new Bundle();
18476            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18477            results.putString("Error", report);
18478            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18479        }
18480    }
18481
18482    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18483        if (app.instrumentationWatcher != null) {
18484            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18485                    app.instrumentationClass, resultCode, results);
18486        }
18487
18488        // Can't call out of the system process with a lock held, so post a message.
18489        if (app.instrumentationUiAutomationConnection != null) {
18490            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18491                    app.instrumentationUiAutomationConnection).sendToTarget();
18492        }
18493
18494        app.instrumentationWatcher = null;
18495        app.instrumentationUiAutomationConnection = null;
18496        app.instrumentationClass = null;
18497        app.instrumentationInfo = null;
18498        app.instrumentationProfileFile = null;
18499        app.instrumentationArguments = null;
18500
18501        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18502                "finished inst");
18503    }
18504
18505    public void finishInstrumentation(IApplicationThread target,
18506            int resultCode, Bundle results) {
18507        int userId = UserHandle.getCallingUserId();
18508        // Refuse possible leaked file descriptors
18509        if (results != null && results.hasFileDescriptors()) {
18510            throw new IllegalArgumentException("File descriptors passed in Intent");
18511        }
18512
18513        synchronized(this) {
18514            ProcessRecord app = getRecordForAppLocked(target);
18515            if (app == null) {
18516                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18517                return;
18518            }
18519            final long origId = Binder.clearCallingIdentity();
18520            finishInstrumentationLocked(app, resultCode, results);
18521            Binder.restoreCallingIdentity(origId);
18522        }
18523    }
18524
18525    // =========================================================
18526    // CONFIGURATION
18527    // =========================================================
18528
18529    public ConfigurationInfo getDeviceConfigurationInfo() {
18530        ConfigurationInfo config = new ConfigurationInfo();
18531        synchronized (this) {
18532            config.reqTouchScreen = mConfiguration.touchscreen;
18533            config.reqKeyboardType = mConfiguration.keyboard;
18534            config.reqNavigation = mConfiguration.navigation;
18535            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18536                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18537                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18538            }
18539            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18540                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18541                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18542            }
18543            config.reqGlEsVersion = GL_ES_VERSION;
18544        }
18545        return config;
18546    }
18547
18548    ActivityStack getFocusedStack() {
18549        return mStackSupervisor.getFocusedStack();
18550    }
18551
18552    @Override
18553    public int getFocusedStackId() throws RemoteException {
18554        ActivityStack focusedStack = getFocusedStack();
18555        if (focusedStack != null) {
18556            return focusedStack.getStackId();
18557        }
18558        return -1;
18559    }
18560
18561    public Configuration getConfiguration() {
18562        Configuration ci;
18563        synchronized(this) {
18564            ci = new Configuration(mConfiguration);
18565            ci.userSetLocale = false;
18566        }
18567        return ci;
18568    }
18569
18570    @Override
18571    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18572        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18573        synchronized (this) {
18574            mSuppressResizeConfigChanges = suppress;
18575        }
18576    }
18577
18578    @Override
18579    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18580        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18581        if (fromStackId == HOME_STACK_ID) {
18582            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18583        }
18584        synchronized (this) {
18585            final long origId = Binder.clearCallingIdentity();
18586            try {
18587                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18588            } finally {
18589                Binder.restoreCallingIdentity(origId);
18590            }
18591        }
18592    }
18593
18594    @Override
18595    public void updatePersistentConfiguration(Configuration values) {
18596        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18597                "updateConfiguration()");
18598        enforceWriteSettingsPermission("updateConfiguration()");
18599        if (values == null) {
18600            throw new NullPointerException("Configuration must not be null");
18601        }
18602
18603        int userId = UserHandle.getCallingUserId();
18604
18605        synchronized(this) {
18606            final long origId = Binder.clearCallingIdentity();
18607            updateConfigurationLocked(values, null, false, true, userId);
18608            Binder.restoreCallingIdentity(origId);
18609        }
18610    }
18611
18612    private void updateFontScaleIfNeeded() {
18613        final int currentUserId;
18614        synchronized(this) {
18615            currentUserId = mUserController.getCurrentUserIdLocked();
18616        }
18617        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18618                FONT_SCALE, 1.0f, currentUserId);
18619        if (mConfiguration.fontScale != scaleFactor) {
18620            final Configuration configuration = mWindowManager.computeNewConfiguration();
18621            configuration.fontScale = scaleFactor;
18622            updatePersistentConfiguration(configuration);
18623        }
18624    }
18625
18626    private void enforceWriteSettingsPermission(String func) {
18627        int uid = Binder.getCallingUid();
18628        if (uid == Process.ROOT_UID) {
18629            return;
18630        }
18631
18632        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18633                Settings.getPackageNameForUid(mContext, uid), false)) {
18634            return;
18635        }
18636
18637        String msg = "Permission Denial: " + func + " from pid="
18638                + Binder.getCallingPid()
18639                + ", uid=" + uid
18640                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18641        Slog.w(TAG, msg);
18642        throw new SecurityException(msg);
18643    }
18644
18645    public void updateConfiguration(Configuration values) {
18646        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18647                "updateConfiguration()");
18648
18649        synchronized(this) {
18650            if (values == null && mWindowManager != null) {
18651                // sentinel: fetch the current configuration from the window manager
18652                values = mWindowManager.computeNewConfiguration();
18653            }
18654
18655            if (mWindowManager != null) {
18656                mProcessList.applyDisplaySize(mWindowManager);
18657            }
18658
18659            final long origId = Binder.clearCallingIdentity();
18660            if (values != null) {
18661                Settings.System.clearConfiguration(values);
18662            }
18663            updateConfigurationLocked(values, null, false);
18664            Binder.restoreCallingIdentity(origId);
18665        }
18666    }
18667
18668    void updateUserConfigurationLocked() {
18669        Configuration configuration = new Configuration(mConfiguration);
18670        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18671                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18672        updateConfigurationLocked(configuration, null, false);
18673    }
18674
18675    boolean updateConfigurationLocked(Configuration values,
18676            ActivityRecord starting, boolean initLocale) {
18677        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18678        return updateConfigurationLocked(values, starting, initLocale, false,
18679                UserHandle.USER_NULL);
18680    }
18681
18682    // To cache the list of supported system locales
18683    private String[] mSupportedSystemLocales = null;
18684
18685    /**
18686     * Do either or both things: (1) change the current configuration, and (2)
18687     * make sure the given activity is running with the (now) current
18688     * configuration.  Returns true if the activity has been left running, or
18689     * false if <var>starting</var> is being destroyed to match the new
18690     * configuration.
18691     *
18692     * @param userId is only used when persistent parameter is set to true to persist configuration
18693     *               for that particular user
18694     */
18695    private boolean updateConfigurationLocked(Configuration values,
18696            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18697        int changes = 0;
18698
18699        if (mWindowManager != null) {
18700            mWindowManager.deferSurfaceLayout();
18701        }
18702        if (values != null) {
18703            Configuration newConfig = new Configuration(mConfiguration);
18704            changes = newConfig.updateFrom(values);
18705            if (changes != 0) {
18706                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18707                        "Updating configuration to: " + values);
18708
18709                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18710
18711                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18712                    final LocaleList locales = values.getLocales();
18713                    int bestLocaleIndex = 0;
18714                    if (locales.size() > 1) {
18715                        if (mSupportedSystemLocales == null) {
18716                            mSupportedSystemLocales =
18717                                    Resources.getSystem().getAssets().getLocales();
18718                        }
18719                        bestLocaleIndex = Math.max(0,
18720                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18721                    }
18722                    SystemProperties.set("persist.sys.locale",
18723                            locales.get(bestLocaleIndex).toLanguageTag());
18724                    LocaleList.setDefault(locales, bestLocaleIndex);
18725                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18726                            locales.get(bestLocaleIndex)));
18727                }
18728
18729                mConfigurationSeq++;
18730                if (mConfigurationSeq <= 0) {
18731                    mConfigurationSeq = 1;
18732                }
18733                newConfig.seq = mConfigurationSeq;
18734                mConfiguration = newConfig;
18735                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18736                mUsageStatsService.reportConfigurationChange(newConfig,
18737                        mUserController.getCurrentUserIdLocked());
18738                //mUsageStatsService.noteStartConfig(newConfig);
18739
18740                final Configuration configCopy = new Configuration(mConfiguration);
18741
18742                // TODO: If our config changes, should we auto dismiss any currently
18743                // showing dialogs?
18744                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18745
18746                AttributeCache ac = AttributeCache.instance();
18747                if (ac != null) {
18748                    ac.updateConfiguration(configCopy);
18749                }
18750
18751                // Make sure all resources in our process are updated
18752                // right now, so that anyone who is going to retrieve
18753                // resource values after we return will be sure to get
18754                // the new ones.  This is especially important during
18755                // boot, where the first config change needs to guarantee
18756                // all resources have that config before following boot
18757                // code is executed.
18758                mSystemThread.applyConfigurationToResources(configCopy);
18759
18760                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18761                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18762                    msg.obj = new Configuration(configCopy);
18763                    msg.arg1 = userId;
18764                    mHandler.sendMessage(msg);
18765                }
18766
18767                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18768                if (isDensityChange) {
18769                    // Reset the unsupported display size dialog.
18770                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18771
18772                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18773                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18774                }
18775
18776                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18777                    ProcessRecord app = mLruProcesses.get(i);
18778                    try {
18779                        if (app.thread != null) {
18780                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18781                                    + app.processName + " new config " + mConfiguration);
18782                            app.thread.scheduleConfigurationChanged(configCopy);
18783                        }
18784                    } catch (Exception e) {
18785                    }
18786                }
18787                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18788                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18789                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18790                        | Intent.FLAG_RECEIVER_FOREGROUND);
18791                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18792                        null, AppOpsManager.OP_NONE, null, false, false,
18793                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18794                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18795                    // Tell the shortcut manager that the system locale changed.  It needs to know
18796                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18797                    // we "push" from here, rather than having the service listen to the broadcast.
18798                    final ShortcutServiceInternal shortcutService =
18799                            LocalServices.getService(ShortcutServiceInternal.class);
18800                    if (shortcutService != null) {
18801                        shortcutService.onSystemLocaleChangedNoLock();
18802                    }
18803
18804                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18805                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18806                    if (!mProcessesReady) {
18807                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18808                    }
18809                    broadcastIntentLocked(null, null, intent,
18810                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18811                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18812                }
18813            }
18814            // Update the configuration with WM first and check if any of the stacks need to be
18815            // resized due to the configuration change. If so, resize the stacks now and do any
18816            // relaunches if necessary. This way we don't need to relaunch again below in
18817            // ensureActivityConfigurationLocked().
18818            if (mWindowManager != null) {
18819                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18820                if (resizedStacks != null) {
18821                    for (int stackId : resizedStacks) {
18822                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18823                        mStackSupervisor.resizeStackLocked(
18824                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18825                    }
18826                }
18827            }
18828        }
18829
18830        boolean kept = true;
18831        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18832        // mainStack is null during startup.
18833        if (mainStack != null) {
18834            if (changes != 0 && starting == null) {
18835                // If the configuration changed, and the caller is not already
18836                // in the process of starting an activity, then find the top
18837                // activity to check if its configuration needs to change.
18838                starting = mainStack.topRunningActivityLocked();
18839            }
18840
18841            if (starting != null) {
18842                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18843                // And we need to make sure at this point that all other activities
18844                // are made visible with the correct configuration.
18845                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18846                        !PRESERVE_WINDOWS);
18847            }
18848        }
18849        if (mWindowManager != null) {
18850            mWindowManager.continueSurfaceLayout();
18851        }
18852        return kept;
18853    }
18854
18855    /**
18856     * Decide based on the configuration whether we should shouw the ANR,
18857     * crash, etc dialogs.  The idea is that if there is no affordnace to
18858     * press the on-screen buttons, we shouldn't show the dialog.
18859     *
18860     * A thought: SystemUI might also want to get told about this, the Power
18861     * dialog / global actions also might want different behaviors.
18862     */
18863    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18864        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18865                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18866                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18867        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18868                                    == Configuration.UI_MODE_TYPE_CAR);
18869        return inputMethodExists && uiIsNotCarType && !inVrMode;
18870    }
18871
18872    @Override
18873    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18874        synchronized (this) {
18875            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18876            if (srec != null) {
18877                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18878            }
18879        }
18880        return false;
18881    }
18882
18883    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18884            Intent resultData) {
18885
18886        synchronized (this) {
18887            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18888            if (r != null) {
18889                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18890            }
18891            return false;
18892        }
18893    }
18894
18895    public int getLaunchedFromUid(IBinder activityToken) {
18896        ActivityRecord srec;
18897        synchronized (this) {
18898            srec = ActivityRecord.forTokenLocked(activityToken);
18899        }
18900        if (srec == null) {
18901            return -1;
18902        }
18903        return srec.launchedFromUid;
18904    }
18905
18906    public String getLaunchedFromPackage(IBinder activityToken) {
18907        ActivityRecord srec;
18908        synchronized (this) {
18909            srec = ActivityRecord.forTokenLocked(activityToken);
18910        }
18911        if (srec == null) {
18912            return null;
18913        }
18914        return srec.launchedFromPackage;
18915    }
18916
18917    // =========================================================
18918    // LIFETIME MANAGEMENT
18919    // =========================================================
18920
18921    // Returns whether the app is receiving broadcast.
18922    // If receiving, fetch all broadcast queues which the app is
18923    // the current [or imminent] receiver on.
18924    private boolean isReceivingBroadcastLocked(ProcessRecord app,
18925            ArraySet<BroadcastQueue> receivingQueues) {
18926        if (!app.curReceivers.isEmpty()) {
18927            for (BroadcastRecord r : app.curReceivers) {
18928                receivingQueues.add(r.queue);
18929            }
18930            return true;
18931        }
18932
18933        // It's not the current receiver, but it might be starting up to become one
18934        for (BroadcastQueue queue : mBroadcastQueues) {
18935            final BroadcastRecord r = queue.mPendingBroadcast;
18936            if (r != null && r.curApp == app) {
18937                // found it; report which queue it's in
18938                receivingQueues.add(queue);
18939            }
18940        }
18941
18942        return !receivingQueues.isEmpty();
18943    }
18944
18945    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18946            int targetUid, ComponentName targetComponent, String targetProcess) {
18947        if (!mTrackingAssociations) {
18948            return null;
18949        }
18950        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18951                = mAssociations.get(targetUid);
18952        if (components == null) {
18953            components = new ArrayMap<>();
18954            mAssociations.put(targetUid, components);
18955        }
18956        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18957        if (sourceUids == null) {
18958            sourceUids = new SparseArray<>();
18959            components.put(targetComponent, sourceUids);
18960        }
18961        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18962        if (sourceProcesses == null) {
18963            sourceProcesses = new ArrayMap<>();
18964            sourceUids.put(sourceUid, sourceProcesses);
18965        }
18966        Association ass = sourceProcesses.get(sourceProcess);
18967        if (ass == null) {
18968            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18969                    targetProcess);
18970            sourceProcesses.put(sourceProcess, ass);
18971        }
18972        ass.mCount++;
18973        ass.mNesting++;
18974        if (ass.mNesting == 1) {
18975            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18976            ass.mLastState = sourceState;
18977        }
18978        return ass;
18979    }
18980
18981    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18982            ComponentName targetComponent) {
18983        if (!mTrackingAssociations) {
18984            return;
18985        }
18986        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18987                = mAssociations.get(targetUid);
18988        if (components == null) {
18989            return;
18990        }
18991        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18992        if (sourceUids == null) {
18993            return;
18994        }
18995        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18996        if (sourceProcesses == null) {
18997            return;
18998        }
18999        Association ass = sourceProcesses.get(sourceProcess);
19000        if (ass == null || ass.mNesting <= 0) {
19001            return;
19002        }
19003        ass.mNesting--;
19004        if (ass.mNesting == 0) {
19005            long uptime = SystemClock.uptimeMillis();
19006            ass.mTime += uptime - ass.mStartTime;
19007            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19008                    += uptime - ass.mLastStateUptime;
19009            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19010        }
19011    }
19012
19013    private void noteUidProcessState(final int uid, final int state) {
19014        mBatteryStatsService.noteUidProcessState(uid, state);
19015        if (mTrackingAssociations) {
19016            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19017                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19018                        = mAssociations.valueAt(i1);
19019                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19020                    SparseArray<ArrayMap<String, Association>> sourceUids
19021                            = targetComponents.valueAt(i2);
19022                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19023                    if (sourceProcesses != null) {
19024                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19025                            Association ass = sourceProcesses.valueAt(i4);
19026                            if (ass.mNesting >= 1) {
19027                                // currently associated
19028                                long uptime = SystemClock.uptimeMillis();
19029                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19030                                        += uptime - ass.mLastStateUptime;
19031                                ass.mLastState = state;
19032                                ass.mLastStateUptime = uptime;
19033                            }
19034                        }
19035                    }
19036                }
19037            }
19038        }
19039    }
19040
19041    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19042            boolean doingAll, long now) {
19043        if (mAdjSeq == app.adjSeq) {
19044            // This adjustment has already been computed.
19045            return app.curRawAdj;
19046        }
19047
19048        if (app.thread == null) {
19049            app.adjSeq = mAdjSeq;
19050            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19051            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19052            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19053        }
19054
19055        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19056        app.adjSource = null;
19057        app.adjTarget = null;
19058        app.empty = false;
19059        app.cached = false;
19060
19061        final int activitiesSize = app.activities.size();
19062
19063        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19064            // The max adjustment doesn't allow this app to be anything
19065            // below foreground, so it is not worth doing work for it.
19066            app.adjType = "fixed";
19067            app.adjSeq = mAdjSeq;
19068            app.curRawAdj = app.maxAdj;
19069            app.foregroundActivities = false;
19070            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19071            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19072            // System processes can do UI, and when they do we want to have
19073            // them trim their memory after the user leaves the UI.  To
19074            // facilitate this, here we need to determine whether or not it
19075            // is currently showing UI.
19076            app.systemNoUi = true;
19077            if (app == TOP_APP) {
19078                app.systemNoUi = false;
19079                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19080                app.adjType = "pers-top-activity";
19081            } else if (activitiesSize > 0) {
19082                for (int j = 0; j < activitiesSize; j++) {
19083                    final ActivityRecord r = app.activities.get(j);
19084                    if (r.visible) {
19085                        app.systemNoUi = false;
19086                    }
19087                }
19088            }
19089            if (!app.systemNoUi) {
19090                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19091            }
19092            return (app.curAdj=app.maxAdj);
19093        }
19094
19095        app.systemNoUi = false;
19096
19097        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19098
19099        // Determine the importance of the process, starting with most
19100        // important to least, and assign an appropriate OOM adjustment.
19101        int adj;
19102        int schedGroup;
19103        int procState;
19104        boolean foregroundActivities = false;
19105        final ArraySet<BroadcastQueue> queues = new ArraySet<BroadcastQueue>();
19106        if (app == TOP_APP) {
19107            // The last app on the list is the foreground app.
19108            adj = ProcessList.FOREGROUND_APP_ADJ;
19109            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19110            app.adjType = "top-activity";
19111            foregroundActivities = true;
19112            procState = PROCESS_STATE_CUR_TOP;
19113        } else if (app.instrumentationClass != null) {
19114            // Don't want to kill running instrumentation.
19115            adj = ProcessList.FOREGROUND_APP_ADJ;
19116            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19117            app.adjType = "instrumentation";
19118            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19119        } else if (isReceivingBroadcastLocked(app, queues)) {
19120            // An app that is currently receiving a broadcast also
19121            // counts as being in the foreground for OOM killer purposes.
19122            // It's placed in a sched group based on the nature of the
19123            // broadcast as reflected by which queue it's active in.
19124            adj = ProcessList.FOREGROUND_APP_ADJ;
19125            schedGroup = (queues.contains(mFgBroadcastQueue))
19126                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19127            app.adjType = "broadcast";
19128            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19129        } else if (app.executingServices.size() > 0) {
19130            // An app that is currently executing a service callback also
19131            // counts as being in the foreground.
19132            adj = ProcessList.FOREGROUND_APP_ADJ;
19133            schedGroup = app.execServicesFg ?
19134                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19135            app.adjType = "exec-service";
19136            procState = ActivityManager.PROCESS_STATE_SERVICE;
19137            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19138        } else {
19139            // As far as we know the process is empty.  We may change our mind later.
19140            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19141            // At this point we don't actually know the adjustment.  Use the cached adj
19142            // value that the caller wants us to.
19143            adj = cachedAdj;
19144            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19145            app.cached = true;
19146            app.empty = true;
19147            app.adjType = "cch-empty";
19148        }
19149
19150        // Examine all activities if not already foreground.
19151        if (!foregroundActivities && activitiesSize > 0) {
19152            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19153            for (int j = 0; j < activitiesSize; j++) {
19154                final ActivityRecord r = app.activities.get(j);
19155                if (r.app != app) {
19156                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19157                            + " instead of expected " + app);
19158                    if (r.app == null || (r.app.uid == app.uid)) {
19159                        // Only fix things up when they look sane
19160                        r.app = app;
19161                    } else {
19162                        continue;
19163                    }
19164                }
19165                if (r.visible) {
19166                    // App has a visible activity; only upgrade adjustment.
19167                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19168                        adj = ProcessList.VISIBLE_APP_ADJ;
19169                        app.adjType = "visible";
19170                    }
19171                    if (procState > PROCESS_STATE_CUR_TOP) {
19172                        procState = PROCESS_STATE_CUR_TOP;
19173                    }
19174                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19175                    app.cached = false;
19176                    app.empty = false;
19177                    foregroundActivities = true;
19178                    if (r.task != null && minLayer > 0) {
19179                        final int layer = r.task.mLayerRank;
19180                        if (layer >= 0 && minLayer > layer) {
19181                            minLayer = layer;
19182                        }
19183                    }
19184                    break;
19185                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19186                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19187                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19188                        app.adjType = "pausing";
19189                    }
19190                    if (procState > PROCESS_STATE_CUR_TOP) {
19191                        procState = PROCESS_STATE_CUR_TOP;
19192                    }
19193                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19194                    app.cached = false;
19195                    app.empty = false;
19196                    foregroundActivities = true;
19197                } else if (r.state == ActivityState.STOPPING) {
19198                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19199                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19200                        app.adjType = "stopping";
19201                    }
19202                    // For the process state, we will at this point consider the
19203                    // process to be cached.  It will be cached either as an activity
19204                    // or empty depending on whether the activity is finishing.  We do
19205                    // this so that we can treat the process as cached for purposes of
19206                    // memory trimming (determing current memory level, trim command to
19207                    // send to process) since there can be an arbitrary number of stopping
19208                    // processes and they should soon all go into the cached state.
19209                    if (!r.finishing) {
19210                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19211                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19212                        }
19213                    }
19214                    app.cached = false;
19215                    app.empty = false;
19216                    foregroundActivities = true;
19217                } else {
19218                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19219                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19220                        app.adjType = "cch-act";
19221                    }
19222                }
19223            }
19224            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19225                adj += minLayer;
19226            }
19227        }
19228
19229        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19230                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19231            if (app.foregroundServices) {
19232                // The user is aware of this app, so make it visible.
19233                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19234                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19235                app.cached = false;
19236                app.adjType = "fg-service";
19237                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19238            } else if (app.forcingToForeground != null) {
19239                // The user is aware of this app, so make it visible.
19240                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19241                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19242                app.cached = false;
19243                app.adjType = "force-fg";
19244                app.adjSource = app.forcingToForeground;
19245                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19246            }
19247        }
19248
19249        if (app == mHeavyWeightProcess) {
19250            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19251                // We don't want to kill the current heavy-weight process.
19252                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19253                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19254                app.cached = false;
19255                app.adjType = "heavy";
19256            }
19257            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19258                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19259            }
19260        }
19261
19262        if (app == mHomeProcess) {
19263            if (adj > ProcessList.HOME_APP_ADJ) {
19264                // This process is hosting what we currently consider to be the
19265                // home app, so we don't want to let it go into the background.
19266                adj = ProcessList.HOME_APP_ADJ;
19267                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19268                app.cached = false;
19269                app.adjType = "home";
19270            }
19271            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19272                procState = ActivityManager.PROCESS_STATE_HOME;
19273            }
19274        }
19275
19276        if (app == mPreviousProcess && app.activities.size() > 0) {
19277            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19278                // This was the previous process that showed UI to the user.
19279                // We want to try to keep it around more aggressively, to give
19280                // a good experience around switching between two apps.
19281                adj = ProcessList.PREVIOUS_APP_ADJ;
19282                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19283                app.cached = false;
19284                app.adjType = "previous";
19285            }
19286            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19287                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19288            }
19289        }
19290
19291        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19292                + " reason=" + app.adjType);
19293
19294        // By default, we use the computed adjustment.  It may be changed if
19295        // there are applications dependent on our services or providers, but
19296        // this gives us a baseline and makes sure we don't get into an
19297        // infinite recursion.
19298        app.adjSeq = mAdjSeq;
19299        app.curRawAdj = adj;
19300        app.hasStartedServices = false;
19301
19302        if (mBackupTarget != null && app == mBackupTarget.app) {
19303            // If possible we want to avoid killing apps while they're being backed up
19304            if (adj > ProcessList.BACKUP_APP_ADJ) {
19305                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19306                adj = ProcessList.BACKUP_APP_ADJ;
19307                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19308                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19309                }
19310                app.adjType = "backup";
19311                app.cached = false;
19312            }
19313            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19314                procState = ActivityManager.PROCESS_STATE_BACKUP;
19315            }
19316        }
19317
19318        boolean mayBeTop = false;
19319
19320        for (int is = app.services.size()-1;
19321                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19322                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19323                        || procState > ActivityManager.PROCESS_STATE_TOP);
19324                is--) {
19325            ServiceRecord s = app.services.valueAt(is);
19326            if (s.startRequested) {
19327                app.hasStartedServices = true;
19328                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19329                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19330                }
19331                if (app.hasShownUi && app != mHomeProcess) {
19332                    // If this process has shown some UI, let it immediately
19333                    // go to the LRU list because it may be pretty heavy with
19334                    // UI stuff.  We'll tag it with a label just to help
19335                    // debug and understand what is going on.
19336                    if (adj > ProcessList.SERVICE_ADJ) {
19337                        app.adjType = "cch-started-ui-services";
19338                    }
19339                } else {
19340                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19341                        // This service has seen some activity within
19342                        // recent memory, so we will keep its process ahead
19343                        // of the background processes.
19344                        if (adj > ProcessList.SERVICE_ADJ) {
19345                            adj = ProcessList.SERVICE_ADJ;
19346                            app.adjType = "started-services";
19347                            app.cached = false;
19348                        }
19349                    }
19350                    // If we have let the service slide into the background
19351                    // state, still have some text describing what it is doing
19352                    // even though the service no longer has an impact.
19353                    if (adj > ProcessList.SERVICE_ADJ) {
19354                        app.adjType = "cch-started-services";
19355                    }
19356                }
19357            }
19358
19359            for (int conni = s.connections.size()-1;
19360                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19361                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19362                            || procState > ActivityManager.PROCESS_STATE_TOP);
19363                    conni--) {
19364                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19365                for (int i = 0;
19366                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19367                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19368                                || procState > ActivityManager.PROCESS_STATE_TOP);
19369                        i++) {
19370                    // XXX should compute this based on the max of
19371                    // all connected clients.
19372                    ConnectionRecord cr = clist.get(i);
19373                    if (cr.binding.client == app) {
19374                        // Binding to ourself is not interesting.
19375                        continue;
19376                    }
19377
19378                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19379                        ProcessRecord client = cr.binding.client;
19380                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19381                                TOP_APP, doingAll, now);
19382                        int clientProcState = client.curProcState;
19383                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19384                            // If the other app is cached for any reason, for purposes here
19385                            // we are going to consider it empty.  The specific cached state
19386                            // doesn't propagate except under certain conditions.
19387                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19388                        }
19389                        String adjType = null;
19390                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19391                            // Not doing bind OOM management, so treat
19392                            // this guy more like a started service.
19393                            if (app.hasShownUi && app != mHomeProcess) {
19394                                // If this process has shown some UI, let it immediately
19395                                // go to the LRU list because it may be pretty heavy with
19396                                // UI stuff.  We'll tag it with a label just to help
19397                                // debug and understand what is going on.
19398                                if (adj > clientAdj) {
19399                                    adjType = "cch-bound-ui-services";
19400                                }
19401                                app.cached = false;
19402                                clientAdj = adj;
19403                                clientProcState = procState;
19404                            } else {
19405                                if (now >= (s.lastActivity
19406                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19407                                    // This service has not seen activity within
19408                                    // recent memory, so allow it to drop to the
19409                                    // LRU list if there is no other reason to keep
19410                                    // it around.  We'll also tag it with a label just
19411                                    // to help debug and undertand what is going on.
19412                                    if (adj > clientAdj) {
19413                                        adjType = "cch-bound-services";
19414                                    }
19415                                    clientAdj = adj;
19416                                }
19417                            }
19418                        }
19419                        if (adj > clientAdj) {
19420                            // If this process has recently shown UI, and
19421                            // the process that is binding to it is less
19422                            // important than being visible, then we don't
19423                            // care about the binding as much as we care
19424                            // about letting this process get into the LRU
19425                            // list to be killed and restarted if needed for
19426                            // memory.
19427                            if (app.hasShownUi && app != mHomeProcess
19428                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19429                                adjType = "cch-bound-ui-services";
19430                            } else {
19431                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19432                                        |Context.BIND_IMPORTANT)) != 0) {
19433                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19434                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19435                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19436                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19437                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19438                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19439                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19440                                    adj = clientAdj;
19441                                } else {
19442                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19443                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19444                                    }
19445                                }
19446                                if (!client.cached) {
19447                                    app.cached = false;
19448                                }
19449                                adjType = "service";
19450                            }
19451                        }
19452                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19453                            // This will treat important bound services identically to
19454                            // the top app, which may behave differently than generic
19455                            // foreground work.
19456                            if (client.curSchedGroup > schedGroup) {
19457                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19458                                    schedGroup = client.curSchedGroup;
19459                                } else {
19460                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19461                                }
19462                            }
19463                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19464                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19465                                    // Special handling of clients who are in the top state.
19466                                    // We *may* want to consider this process to be in the
19467                                    // top state as well, but only if there is not another
19468                                    // reason for it to be running.  Being on the top is a
19469                                    // special state, meaning you are specifically running
19470                                    // for the current top app.  If the process is already
19471                                    // running in the background for some other reason, it
19472                                    // is more important to continue considering it to be
19473                                    // in the background state.
19474                                    mayBeTop = true;
19475                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19476                                } else {
19477                                    // Special handling for above-top states (persistent
19478                                    // processes).  These should not bring the current process
19479                                    // into the top state, since they are not on top.  Instead
19480                                    // give them the best state after that.
19481                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19482                                        clientProcState =
19483                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19484                                    } else if (mWakefulness
19485                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19486                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19487                                                    != 0) {
19488                                        clientProcState =
19489                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19490                                    } else {
19491                                        clientProcState =
19492                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19493                                    }
19494                                }
19495                            }
19496                        } else {
19497                            if (clientProcState <
19498                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19499                                clientProcState =
19500                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19501                            }
19502                        }
19503                        if (procState > clientProcState) {
19504                            procState = clientProcState;
19505                        }
19506                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19507                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19508                            app.pendingUiClean = true;
19509                        }
19510                        if (adjType != null) {
19511                            app.adjType = adjType;
19512                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19513                                    .REASON_SERVICE_IN_USE;
19514                            app.adjSource = cr.binding.client;
19515                            app.adjSourceProcState = clientProcState;
19516                            app.adjTarget = s.name;
19517                        }
19518                    }
19519                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19520                        app.treatLikeActivity = true;
19521                    }
19522                    final ActivityRecord a = cr.activity;
19523                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19524                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19525                            (a.visible || a.state == ActivityState.RESUMED ||
19526                             a.state == ActivityState.PAUSING)) {
19527                            adj = ProcessList.FOREGROUND_APP_ADJ;
19528                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19529                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19530                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19531                                } else {
19532                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19533                                }
19534                            }
19535                            app.cached = false;
19536                            app.adjType = "service";
19537                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19538                                    .REASON_SERVICE_IN_USE;
19539                            app.adjSource = a;
19540                            app.adjSourceProcState = procState;
19541                            app.adjTarget = s.name;
19542                        }
19543                    }
19544                }
19545            }
19546        }
19547
19548        for (int provi = app.pubProviders.size()-1;
19549                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19550                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19551                        || procState > ActivityManager.PROCESS_STATE_TOP);
19552                provi--) {
19553            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19554            for (int i = cpr.connections.size()-1;
19555                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19556                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19557                            || procState > ActivityManager.PROCESS_STATE_TOP);
19558                    i--) {
19559                ContentProviderConnection conn = cpr.connections.get(i);
19560                ProcessRecord client = conn.client;
19561                if (client == app) {
19562                    // Being our own client is not interesting.
19563                    continue;
19564                }
19565                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19566                int clientProcState = client.curProcState;
19567                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19568                    // If the other app is cached for any reason, for purposes here
19569                    // we are going to consider it empty.
19570                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19571                }
19572                if (adj > clientAdj) {
19573                    if (app.hasShownUi && app != mHomeProcess
19574                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19575                        app.adjType = "cch-ui-provider";
19576                    } else {
19577                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19578                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19579                        app.adjType = "provider";
19580                    }
19581                    app.cached &= client.cached;
19582                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19583                            .REASON_PROVIDER_IN_USE;
19584                    app.adjSource = client;
19585                    app.adjSourceProcState = clientProcState;
19586                    app.adjTarget = cpr.name;
19587                }
19588                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19589                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19590                        // Special handling of clients who are in the top state.
19591                        // We *may* want to consider this process to be in the
19592                        // top state as well, but only if there is not another
19593                        // reason for it to be running.  Being on the top is a
19594                        // special state, meaning you are specifically running
19595                        // for the current top app.  If the process is already
19596                        // running in the background for some other reason, it
19597                        // is more important to continue considering it to be
19598                        // in the background state.
19599                        mayBeTop = true;
19600                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19601                    } else {
19602                        // Special handling for above-top states (persistent
19603                        // processes).  These should not bring the current process
19604                        // into the top state, since they are not on top.  Instead
19605                        // give them the best state after that.
19606                        clientProcState =
19607                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19608                    }
19609                }
19610                if (procState > clientProcState) {
19611                    procState = clientProcState;
19612                }
19613                if (client.curSchedGroup > schedGroup) {
19614                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19615                }
19616            }
19617            // If the provider has external (non-framework) process
19618            // dependencies, ensure that its adjustment is at least
19619            // FOREGROUND_APP_ADJ.
19620            if (cpr.hasExternalProcessHandles()) {
19621                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19622                    adj = ProcessList.FOREGROUND_APP_ADJ;
19623                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19624                    app.cached = false;
19625                    app.adjType = "provider";
19626                    app.adjTarget = cpr.name;
19627                }
19628                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19629                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19630                }
19631            }
19632        }
19633
19634        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19635            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19636                adj = ProcessList.PREVIOUS_APP_ADJ;
19637                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19638                app.cached = false;
19639                app.adjType = "provider";
19640            }
19641            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19642                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19643            }
19644        }
19645
19646        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19647            // A client of one of our services or providers is in the top state.  We
19648            // *may* want to be in the top state, but not if we are already running in
19649            // the background for some other reason.  For the decision here, we are going
19650            // to pick out a few specific states that we want to remain in when a client
19651            // is top (states that tend to be longer-term) and otherwise allow it to go
19652            // to the top state.
19653            switch (procState) {
19654                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19655                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19656                case ActivityManager.PROCESS_STATE_SERVICE:
19657                    // These all are longer-term states, so pull them up to the top
19658                    // of the background states, but not all the way to the top state.
19659                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19660                    break;
19661                default:
19662                    // Otherwise, top is a better choice, so take it.
19663                    procState = ActivityManager.PROCESS_STATE_TOP;
19664                    break;
19665            }
19666        }
19667
19668        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19669            if (app.hasClientActivities) {
19670                // This is a cached process, but with client activities.  Mark it so.
19671                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19672                app.adjType = "cch-client-act";
19673            } else if (app.treatLikeActivity) {
19674                // This is a cached process, but somebody wants us to treat it like it has
19675                // an activity, okay!
19676                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19677                app.adjType = "cch-as-act";
19678            }
19679        }
19680
19681        if (adj == ProcessList.SERVICE_ADJ) {
19682            if (doingAll) {
19683                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19684                mNewNumServiceProcs++;
19685                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19686                if (!app.serviceb) {
19687                    // This service isn't far enough down on the LRU list to
19688                    // normally be a B service, but if we are low on RAM and it
19689                    // is large we want to force it down since we would prefer to
19690                    // keep launcher over it.
19691                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19692                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19693                        app.serviceHighRam = true;
19694                        app.serviceb = true;
19695                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19696                    } else {
19697                        mNewNumAServiceProcs++;
19698                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19699                    }
19700                } else {
19701                    app.serviceHighRam = false;
19702                }
19703            }
19704            if (app.serviceb) {
19705                adj = ProcessList.SERVICE_B_ADJ;
19706            }
19707        }
19708
19709        app.curRawAdj = adj;
19710
19711        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19712        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19713        if (adj > app.maxAdj) {
19714            adj = app.maxAdj;
19715            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19716                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19717            }
19718        }
19719
19720        // Do final modification to adj.  Everything we do between here and applying
19721        // the final setAdj must be done in this function, because we will also use
19722        // it when computing the final cached adj later.  Note that we don't need to
19723        // worry about this for max adj above, since max adj will always be used to
19724        // keep it out of the cached vaues.
19725        app.curAdj = app.modifyRawOomAdj(adj);
19726        app.curSchedGroup = schedGroup;
19727        app.curProcState = procState;
19728        app.foregroundActivities = foregroundActivities;
19729
19730        return app.curRawAdj;
19731    }
19732
19733    /**
19734     * Record new PSS sample for a process.
19735     */
19736    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19737            long now) {
19738        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19739                swapPss * 1024);
19740        proc.lastPssTime = now;
19741        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19742        if (DEBUG_PSS) Slog.d(TAG_PSS,
19743                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19744                + " state=" + ProcessList.makeProcStateString(procState));
19745        if (proc.initialIdlePss == 0) {
19746            proc.initialIdlePss = pss;
19747        }
19748        proc.lastPss = pss;
19749        proc.lastSwapPss = swapPss;
19750        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19751            proc.lastCachedPss = pss;
19752            proc.lastCachedSwapPss = swapPss;
19753        }
19754
19755        final SparseArray<Pair<Long, String>> watchUids
19756                = mMemWatchProcesses.getMap().get(proc.processName);
19757        Long check = null;
19758        if (watchUids != null) {
19759            Pair<Long, String> val = watchUids.get(proc.uid);
19760            if (val == null) {
19761                val = watchUids.get(0);
19762            }
19763            if (val != null) {
19764                check = val.first;
19765            }
19766        }
19767        if (check != null) {
19768            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19769                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19770                if (!isDebuggable) {
19771                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19772                        isDebuggable = true;
19773                    }
19774                }
19775                if (isDebuggable) {
19776                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19777                    final ProcessRecord myProc = proc;
19778                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19779                    mMemWatchDumpProcName = proc.processName;
19780                    mMemWatchDumpFile = heapdumpFile.toString();
19781                    mMemWatchDumpPid = proc.pid;
19782                    mMemWatchDumpUid = proc.uid;
19783                    BackgroundThread.getHandler().post(new Runnable() {
19784                        @Override
19785                        public void run() {
19786                            revokeUriPermission(ActivityThread.currentActivityThread()
19787                                            .getApplicationThread(),
19788                                    DumpHeapActivity.JAVA_URI,
19789                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19790                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19791                                    UserHandle.myUserId());
19792                            ParcelFileDescriptor fd = null;
19793                            try {
19794                                heapdumpFile.delete();
19795                                fd = ParcelFileDescriptor.open(heapdumpFile,
19796                                        ParcelFileDescriptor.MODE_CREATE |
19797                                                ParcelFileDescriptor.MODE_TRUNCATE |
19798                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19799                                                ParcelFileDescriptor.MODE_APPEND);
19800                                IApplicationThread thread = myProc.thread;
19801                                if (thread != null) {
19802                                    try {
19803                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19804                                                "Requesting dump heap from "
19805                                                + myProc + " to " + heapdumpFile);
19806                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19807                                    } catch (RemoteException e) {
19808                                    }
19809                                }
19810                            } catch (FileNotFoundException e) {
19811                                e.printStackTrace();
19812                            } finally {
19813                                if (fd != null) {
19814                                    try {
19815                                        fd.close();
19816                                    } catch (IOException e) {
19817                                    }
19818                                }
19819                            }
19820                        }
19821                    });
19822                } else {
19823                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19824                            + ", but debugging not enabled");
19825                }
19826            }
19827        }
19828    }
19829
19830    /**
19831     * Schedule PSS collection of a process.
19832     */
19833    void requestPssLocked(ProcessRecord proc, int procState) {
19834        if (mPendingPssProcesses.contains(proc)) {
19835            return;
19836        }
19837        if (mPendingPssProcesses.size() == 0) {
19838            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19839        }
19840        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19841        proc.pssProcState = procState;
19842        mPendingPssProcesses.add(proc);
19843    }
19844
19845    /**
19846     * Schedule PSS collection of all processes.
19847     */
19848    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19849        if (!always) {
19850            if (now < (mLastFullPssTime +
19851                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19852                return;
19853            }
19854        }
19855        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19856        mLastFullPssTime = now;
19857        mFullPssPending = true;
19858        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19859        mPendingPssProcesses.clear();
19860        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19861            ProcessRecord app = mLruProcesses.get(i);
19862            if (app.thread == null
19863                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19864                continue;
19865            }
19866            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19867                app.pssProcState = app.setProcState;
19868                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19869                        mTestPssMode, isSleepingLocked(), now);
19870                mPendingPssProcesses.add(app);
19871            }
19872        }
19873        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19874    }
19875
19876    public void setTestPssMode(boolean enabled) {
19877        synchronized (this) {
19878            mTestPssMode = enabled;
19879            if (enabled) {
19880                // Whenever we enable the mode, we want to take a snapshot all of current
19881                // process mem use.
19882                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19883            }
19884        }
19885    }
19886
19887    /**
19888     * Ask a given process to GC right now.
19889     */
19890    final void performAppGcLocked(ProcessRecord app) {
19891        try {
19892            app.lastRequestedGc = SystemClock.uptimeMillis();
19893            if (app.thread != null) {
19894                if (app.reportLowMemory) {
19895                    app.reportLowMemory = false;
19896                    app.thread.scheduleLowMemory();
19897                } else {
19898                    app.thread.processInBackground();
19899                }
19900            }
19901        } catch (Exception e) {
19902            // whatever.
19903        }
19904    }
19905
19906    /**
19907     * Returns true if things are idle enough to perform GCs.
19908     */
19909    private final boolean canGcNowLocked() {
19910        boolean processingBroadcasts = false;
19911        for (BroadcastQueue q : mBroadcastQueues) {
19912            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19913                processingBroadcasts = true;
19914            }
19915        }
19916        return !processingBroadcasts
19917                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19918    }
19919
19920    /**
19921     * Perform GCs on all processes that are waiting for it, but only
19922     * if things are idle.
19923     */
19924    final void performAppGcsLocked() {
19925        final int N = mProcessesToGc.size();
19926        if (N <= 0) {
19927            return;
19928        }
19929        if (canGcNowLocked()) {
19930            while (mProcessesToGc.size() > 0) {
19931                ProcessRecord proc = mProcessesToGc.remove(0);
19932                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19933                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19934                            <= SystemClock.uptimeMillis()) {
19935                        // To avoid spamming the system, we will GC processes one
19936                        // at a time, waiting a few seconds between each.
19937                        performAppGcLocked(proc);
19938                        scheduleAppGcsLocked();
19939                        return;
19940                    } else {
19941                        // It hasn't been long enough since we last GCed this
19942                        // process...  put it in the list to wait for its time.
19943                        addProcessToGcListLocked(proc);
19944                        break;
19945                    }
19946                }
19947            }
19948
19949            scheduleAppGcsLocked();
19950        }
19951    }
19952
19953    /**
19954     * If all looks good, perform GCs on all processes waiting for them.
19955     */
19956    final void performAppGcsIfAppropriateLocked() {
19957        if (canGcNowLocked()) {
19958            performAppGcsLocked();
19959            return;
19960        }
19961        // Still not idle, wait some more.
19962        scheduleAppGcsLocked();
19963    }
19964
19965    /**
19966     * Schedule the execution of all pending app GCs.
19967     */
19968    final void scheduleAppGcsLocked() {
19969        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19970
19971        if (mProcessesToGc.size() > 0) {
19972            // Schedule a GC for the time to the next process.
19973            ProcessRecord proc = mProcessesToGc.get(0);
19974            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19975
19976            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19977            long now = SystemClock.uptimeMillis();
19978            if (when < (now+GC_TIMEOUT)) {
19979                when = now + GC_TIMEOUT;
19980            }
19981            mHandler.sendMessageAtTime(msg, when);
19982        }
19983    }
19984
19985    /**
19986     * Add a process to the array of processes waiting to be GCed.  Keeps the
19987     * list in sorted order by the last GC time.  The process can't already be
19988     * on the list.
19989     */
19990    final void addProcessToGcListLocked(ProcessRecord proc) {
19991        boolean added = false;
19992        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19993            if (mProcessesToGc.get(i).lastRequestedGc <
19994                    proc.lastRequestedGc) {
19995                added = true;
19996                mProcessesToGc.add(i+1, proc);
19997                break;
19998            }
19999        }
20000        if (!added) {
20001            mProcessesToGc.add(0, proc);
20002        }
20003    }
20004
20005    /**
20006     * Set up to ask a process to GC itself.  This will either do it
20007     * immediately, or put it on the list of processes to gc the next
20008     * time things are idle.
20009     */
20010    final void scheduleAppGcLocked(ProcessRecord app) {
20011        long now = SystemClock.uptimeMillis();
20012        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20013            return;
20014        }
20015        if (!mProcessesToGc.contains(app)) {
20016            addProcessToGcListLocked(app);
20017            scheduleAppGcsLocked();
20018        }
20019    }
20020
20021    final void checkExcessivePowerUsageLocked(boolean doKills) {
20022        updateCpuStatsNow();
20023
20024        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20025        boolean doWakeKills = doKills;
20026        boolean doCpuKills = doKills;
20027        if (mLastPowerCheckRealtime == 0) {
20028            doWakeKills = false;
20029        }
20030        if (mLastPowerCheckUptime == 0) {
20031            doCpuKills = false;
20032        }
20033        if (stats.isScreenOn()) {
20034            doWakeKills = false;
20035        }
20036        final long curRealtime = SystemClock.elapsedRealtime();
20037        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20038        final long curUptime = SystemClock.uptimeMillis();
20039        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20040        mLastPowerCheckRealtime = curRealtime;
20041        mLastPowerCheckUptime = curUptime;
20042        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20043            doWakeKills = false;
20044        }
20045        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20046            doCpuKills = false;
20047        }
20048        int i = mLruProcesses.size();
20049        while (i > 0) {
20050            i--;
20051            ProcessRecord app = mLruProcesses.get(i);
20052            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20053                long wtime;
20054                synchronized (stats) {
20055                    wtime = stats.getProcessWakeTime(app.info.uid,
20056                            app.pid, curRealtime);
20057                }
20058                long wtimeUsed = wtime - app.lastWakeTime;
20059                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20060                if (DEBUG_POWER) {
20061                    StringBuilder sb = new StringBuilder(128);
20062                    sb.append("Wake for ");
20063                    app.toShortString(sb);
20064                    sb.append(": over ");
20065                    TimeUtils.formatDuration(realtimeSince, sb);
20066                    sb.append(" used ");
20067                    TimeUtils.formatDuration(wtimeUsed, sb);
20068                    sb.append(" (");
20069                    sb.append((wtimeUsed*100)/realtimeSince);
20070                    sb.append("%)");
20071                    Slog.i(TAG_POWER, sb.toString());
20072                    sb.setLength(0);
20073                    sb.append("CPU for ");
20074                    app.toShortString(sb);
20075                    sb.append(": over ");
20076                    TimeUtils.formatDuration(uptimeSince, sb);
20077                    sb.append(" used ");
20078                    TimeUtils.formatDuration(cputimeUsed, sb);
20079                    sb.append(" (");
20080                    sb.append((cputimeUsed*100)/uptimeSince);
20081                    sb.append("%)");
20082                    Slog.i(TAG_POWER, sb.toString());
20083                }
20084                // If a process has held a wake lock for more
20085                // than 50% of the time during this period,
20086                // that sounds bad.  Kill!
20087                if (doWakeKills && realtimeSince > 0
20088                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20089                    synchronized (stats) {
20090                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20091                                realtimeSince, wtimeUsed);
20092                    }
20093                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20094                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20095                } else if (doCpuKills && uptimeSince > 0
20096                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20097                    synchronized (stats) {
20098                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20099                                uptimeSince, cputimeUsed);
20100                    }
20101                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20102                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20103                } else {
20104                    app.lastWakeTime = wtime;
20105                    app.lastCpuTime = app.curCpuTime;
20106                }
20107            }
20108        }
20109    }
20110
20111    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20112            long nowElapsed) {
20113        boolean success = true;
20114
20115        if (app.curRawAdj != app.setRawAdj) {
20116            app.setRawAdj = app.curRawAdj;
20117        }
20118
20119        int changes = 0;
20120
20121        if (app.curAdj != app.setAdj) {
20122            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20123            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20124                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20125                    + app.adjType);
20126            app.setAdj = app.curAdj;
20127            app.verifiedAdj = ProcessList.INVALID_ADJ;
20128        }
20129
20130        if (app.setSchedGroup != app.curSchedGroup) {
20131            app.setSchedGroup = app.curSchedGroup;
20132            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20133                    "Setting sched group of " + app.processName
20134                    + " to " + app.curSchedGroup);
20135            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20136                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20137                app.kill(app.waitingToKill, true);
20138                success = false;
20139            } else {
20140                int processGroup;
20141                switch (app.curSchedGroup) {
20142                    case ProcessList.SCHED_GROUP_BACKGROUND:
20143                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20144                        break;
20145                    case ProcessList.SCHED_GROUP_TOP_APP:
20146                        processGroup = Process.THREAD_GROUP_TOP_APP;
20147                        break;
20148                    default:
20149                        processGroup = Process.THREAD_GROUP_DEFAULT;
20150                        break;
20151                }
20152                if (true) {
20153                    long oldId = Binder.clearCallingIdentity();
20154                    try {
20155                        Process.setProcessGroup(app.pid, processGroup);
20156                    } catch (Exception e) {
20157                        Slog.w(TAG, "Failed setting process group of " + app.pid
20158                                + " to " + app.curSchedGroup);
20159                        e.printStackTrace();
20160                    } finally {
20161                        Binder.restoreCallingIdentity(oldId);
20162                    }
20163                } else {
20164                    if (app.thread != null) {
20165                        try {
20166                            app.thread.setSchedulingGroup(processGroup);
20167                        } catch (RemoteException e) {
20168                        }
20169                    }
20170                }
20171            }
20172        }
20173        if (app.repForegroundActivities != app.foregroundActivities) {
20174            app.repForegroundActivities = app.foregroundActivities;
20175            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20176        }
20177        if (app.repProcState != app.curProcState) {
20178            app.repProcState = app.curProcState;
20179            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20180            if (app.thread != null) {
20181                try {
20182                    if (false) {
20183                        //RuntimeException h = new RuntimeException("here");
20184                        Slog.i(TAG, "Sending new process state " + app.repProcState
20185                                + " to " + app /*, h*/);
20186                    }
20187                    app.thread.setProcessState(app.repProcState);
20188                } catch (RemoteException e) {
20189                }
20190            }
20191        }
20192        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20193                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20194            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20195                // Experimental code to more aggressively collect pss while
20196                // running test...  the problem is that this tends to collect
20197                // the data right when a process is transitioning between process
20198                // states, which well tend to give noisy data.
20199                long start = SystemClock.uptimeMillis();
20200                long pss = Debug.getPss(app.pid, mTmpLong, null);
20201                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20202                mPendingPssProcesses.remove(app);
20203                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20204                        + " to " + app.curProcState + ": "
20205                        + (SystemClock.uptimeMillis()-start) + "ms");
20206            }
20207            app.lastStateTime = now;
20208            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20209                    mTestPssMode, isSleepingLocked(), now);
20210            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20211                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20212                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20213                    + (app.nextPssTime-now) + ": " + app);
20214        } else {
20215            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20216                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20217                    mTestPssMode)))) {
20218                requestPssLocked(app, app.setProcState);
20219                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20220                        mTestPssMode, isSleepingLocked(), now);
20221            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20222                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20223        }
20224        if (app.setProcState != app.curProcState) {
20225            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20226                    "Proc state change of " + app.processName
20227                            + " to " + app.curProcState);
20228            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20229            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20230            if (setImportant && !curImportant) {
20231                // This app is no longer something we consider important enough to allow to
20232                // use arbitrary amounts of battery power.  Note
20233                // its current wake lock time to later know to kill it if
20234                // it is not behaving well.
20235                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20236                synchronized (stats) {
20237                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20238                            app.pid, nowElapsed);
20239                }
20240                app.lastCpuTime = app.curCpuTime;
20241
20242            }
20243            // Inform UsageStats of important process state change
20244            // Must be called before updating setProcState
20245            maybeUpdateUsageStatsLocked(app, nowElapsed);
20246
20247            app.setProcState = app.curProcState;
20248            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20249                app.notCachedSinceIdle = false;
20250            }
20251            if (!doingAll) {
20252                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20253            } else {
20254                app.procStateChanged = true;
20255            }
20256        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20257                > USAGE_STATS_INTERACTION_INTERVAL) {
20258            // For apps that sit around for a long time in the interactive state, we need
20259            // to report this at least once a day so they don't go idle.
20260            maybeUpdateUsageStatsLocked(app, nowElapsed);
20261        }
20262
20263        if (changes != 0) {
20264            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20265                    "Changes in " + app + ": " + changes);
20266            int i = mPendingProcessChanges.size()-1;
20267            ProcessChangeItem item = null;
20268            while (i >= 0) {
20269                item = mPendingProcessChanges.get(i);
20270                if (item.pid == app.pid) {
20271                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20272                            "Re-using existing item: " + item);
20273                    break;
20274                }
20275                i--;
20276            }
20277            if (i < 0) {
20278                // No existing item in pending changes; need a new one.
20279                final int NA = mAvailProcessChanges.size();
20280                if (NA > 0) {
20281                    item = mAvailProcessChanges.remove(NA-1);
20282                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20283                            "Retrieving available item: " + item);
20284                } else {
20285                    item = new ProcessChangeItem();
20286                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20287                            "Allocating new item: " + item);
20288                }
20289                item.changes = 0;
20290                item.pid = app.pid;
20291                item.uid = app.info.uid;
20292                if (mPendingProcessChanges.size() == 0) {
20293                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20294                            "*** Enqueueing dispatch processes changed!");
20295                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20296                }
20297                mPendingProcessChanges.add(item);
20298            }
20299            item.changes |= changes;
20300            item.processState = app.repProcState;
20301            item.foregroundActivities = app.repForegroundActivities;
20302            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20303                    "Item " + Integer.toHexString(System.identityHashCode(item))
20304                    + " " + app.toShortString() + ": changes=" + item.changes
20305                    + " procState=" + item.processState
20306                    + " foreground=" + item.foregroundActivities
20307                    + " type=" + app.adjType + " source=" + app.adjSource
20308                    + " target=" + app.adjTarget);
20309        }
20310
20311        return success;
20312    }
20313
20314    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20315        final UidRecord.ChangeItem pendingChange;
20316        if (uidRec == null || uidRec.pendingChange == null) {
20317            if (mPendingUidChanges.size() == 0) {
20318                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20319                        "*** Enqueueing dispatch uid changed!");
20320                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20321            }
20322            final int NA = mAvailUidChanges.size();
20323            if (NA > 0) {
20324                pendingChange = mAvailUidChanges.remove(NA-1);
20325                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20326                        "Retrieving available item: " + pendingChange);
20327            } else {
20328                pendingChange = new UidRecord.ChangeItem();
20329                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20330                        "Allocating new item: " + pendingChange);
20331            }
20332            if (uidRec != null) {
20333                uidRec.pendingChange = pendingChange;
20334                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20335                    // If this uid is going away, and we haven't yet reported it is gone,
20336                    // then do so now.
20337                    change = UidRecord.CHANGE_GONE_IDLE;
20338                }
20339            } else if (uid < 0) {
20340                throw new IllegalArgumentException("No UidRecord or uid");
20341            }
20342            pendingChange.uidRecord = uidRec;
20343            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20344            mPendingUidChanges.add(pendingChange);
20345        } else {
20346            pendingChange = uidRec.pendingChange;
20347            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20348                change = UidRecord.CHANGE_GONE_IDLE;
20349            }
20350        }
20351        pendingChange.change = change;
20352        pendingChange.processState = uidRec != null
20353                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20354    }
20355
20356    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20357            String authority) {
20358        if (app == null) return;
20359        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20360            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20361            if (userState == null) return;
20362            final long now = SystemClock.elapsedRealtime();
20363            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20364            if (lastReported == null || lastReported < now - 60 * 1000L) {
20365                mUsageStatsService.reportContentProviderUsage(
20366                        authority, providerPkgName, app.userId);
20367                userState.mProviderLastReportedFg.put(authority, now);
20368            }
20369        }
20370    }
20371
20372    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20373        if (DEBUG_USAGE_STATS) {
20374            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20375                    + "] state changes: old = " + app.setProcState + ", new = "
20376                    + app.curProcState);
20377        }
20378        if (mUsageStatsService == null) {
20379            return;
20380        }
20381        boolean isInteraction;
20382        // To avoid some abuse patterns, we are going to be careful about what we consider
20383        // to be an app interaction.  Being the top activity doesn't count while the display
20384        // is sleeping, nor do short foreground services.
20385        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20386            isInteraction = true;
20387            app.fgInteractionTime = 0;
20388        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20389            if (app.fgInteractionTime == 0) {
20390                app.fgInteractionTime = nowElapsed;
20391                isInteraction = false;
20392            } else {
20393                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20394            }
20395        } else {
20396            isInteraction = app.curProcState
20397                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20398            app.fgInteractionTime = 0;
20399        }
20400        if (isInteraction && (!app.reportedInteraction
20401                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20402            app.interactionEventTime = nowElapsed;
20403            String[] packages = app.getPackageList();
20404            if (packages != null) {
20405                for (int i = 0; i < packages.length; i++) {
20406                    mUsageStatsService.reportEvent(packages[i], app.userId,
20407                            UsageEvents.Event.SYSTEM_INTERACTION);
20408                }
20409            }
20410        }
20411        app.reportedInteraction = isInteraction;
20412        if (!isInteraction) {
20413            app.interactionEventTime = 0;
20414        }
20415    }
20416
20417    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20418        if (proc.thread != null) {
20419            if (proc.baseProcessTracker != null) {
20420                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20421            }
20422        }
20423    }
20424
20425    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20426            ProcessRecord TOP_APP, boolean doingAll, long now) {
20427        if (app.thread == null) {
20428            return false;
20429        }
20430
20431        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20432
20433        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20434    }
20435
20436    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20437            boolean oomAdj) {
20438        if (isForeground != proc.foregroundServices) {
20439            proc.foregroundServices = isForeground;
20440            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20441                    proc.info.uid);
20442            if (isForeground) {
20443                if (curProcs == null) {
20444                    curProcs = new ArrayList<ProcessRecord>();
20445                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20446                }
20447                if (!curProcs.contains(proc)) {
20448                    curProcs.add(proc);
20449                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20450                            proc.info.packageName, proc.info.uid);
20451                }
20452            } else {
20453                if (curProcs != null) {
20454                    if (curProcs.remove(proc)) {
20455                        mBatteryStatsService.noteEvent(
20456                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20457                                proc.info.packageName, proc.info.uid);
20458                        if (curProcs.size() <= 0) {
20459                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20460                        }
20461                    }
20462                }
20463            }
20464            if (oomAdj) {
20465                updateOomAdjLocked();
20466            }
20467        }
20468    }
20469
20470    private final ActivityRecord resumedAppLocked() {
20471        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20472        String pkg;
20473        int uid;
20474        if (act != null) {
20475            pkg = act.packageName;
20476            uid = act.info.applicationInfo.uid;
20477        } else {
20478            pkg = null;
20479            uid = -1;
20480        }
20481        // Has the UID or resumed package name changed?
20482        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20483                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20484            if (mCurResumedPackage != null) {
20485                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20486                        mCurResumedPackage, mCurResumedUid);
20487            }
20488            mCurResumedPackage = pkg;
20489            mCurResumedUid = uid;
20490            if (mCurResumedPackage != null) {
20491                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20492                        mCurResumedPackage, mCurResumedUid);
20493            }
20494        }
20495        return act;
20496    }
20497
20498    final boolean updateOomAdjLocked(ProcessRecord app) {
20499        final ActivityRecord TOP_ACT = resumedAppLocked();
20500        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20501        final boolean wasCached = app.cached;
20502
20503        mAdjSeq++;
20504
20505        // This is the desired cached adjusment we want to tell it to use.
20506        // If our app is currently cached, we know it, and that is it.  Otherwise,
20507        // we don't know it yet, and it needs to now be cached we will then
20508        // need to do a complete oom adj.
20509        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20510                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20511        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20512                SystemClock.uptimeMillis());
20513        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20514            // Changed to/from cached state, so apps after it in the LRU
20515            // list may also be changed.
20516            updateOomAdjLocked();
20517        }
20518        return success;
20519    }
20520
20521    final void updateOomAdjLocked() {
20522        final ActivityRecord TOP_ACT = resumedAppLocked();
20523        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20524        final long now = SystemClock.uptimeMillis();
20525        final long nowElapsed = SystemClock.elapsedRealtime();
20526        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20527        final int N = mLruProcesses.size();
20528
20529        if (false) {
20530            RuntimeException e = new RuntimeException();
20531            e.fillInStackTrace();
20532            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20533        }
20534
20535        // Reset state in all uid records.
20536        for (int i=mActiveUids.size()-1; i>=0; i--) {
20537            final UidRecord uidRec = mActiveUids.valueAt(i);
20538            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20539                    "Starting update of " + uidRec);
20540            uidRec.reset();
20541        }
20542
20543        mStackSupervisor.rankTaskLayersIfNeeded();
20544
20545        mAdjSeq++;
20546        mNewNumServiceProcs = 0;
20547        mNewNumAServiceProcs = 0;
20548
20549        final int emptyProcessLimit;
20550        final int cachedProcessLimit;
20551        if (mProcessLimit <= 0) {
20552            emptyProcessLimit = cachedProcessLimit = 0;
20553        } else if (mProcessLimit == 1) {
20554            emptyProcessLimit = 1;
20555            cachedProcessLimit = 0;
20556        } else {
20557            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20558            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20559        }
20560
20561        // Let's determine how many processes we have running vs.
20562        // how many slots we have for background processes; we may want
20563        // to put multiple processes in a slot of there are enough of
20564        // them.
20565        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20566                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20567        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20568        if (numEmptyProcs > cachedProcessLimit) {
20569            // If there are more empty processes than our limit on cached
20570            // processes, then use the cached process limit for the factor.
20571            // This ensures that the really old empty processes get pushed
20572            // down to the bottom, so if we are running low on memory we will
20573            // have a better chance at keeping around more cached processes
20574            // instead of a gazillion empty processes.
20575            numEmptyProcs = cachedProcessLimit;
20576        }
20577        int emptyFactor = numEmptyProcs/numSlots;
20578        if (emptyFactor < 1) emptyFactor = 1;
20579        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20580        if (cachedFactor < 1) cachedFactor = 1;
20581        int stepCached = 0;
20582        int stepEmpty = 0;
20583        int numCached = 0;
20584        int numEmpty = 0;
20585        int numTrimming = 0;
20586
20587        mNumNonCachedProcs = 0;
20588        mNumCachedHiddenProcs = 0;
20589
20590        // First update the OOM adjustment for each of the
20591        // application processes based on their current state.
20592        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20593        int nextCachedAdj = curCachedAdj+1;
20594        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20595        int nextEmptyAdj = curEmptyAdj+2;
20596        for (int i=N-1; i>=0; i--) {
20597            ProcessRecord app = mLruProcesses.get(i);
20598            if (!app.killedByAm && app.thread != null) {
20599                app.procStateChanged = false;
20600                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20601
20602                // If we haven't yet assigned the final cached adj
20603                // to the process, do that now.
20604                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20605                    switch (app.curProcState) {
20606                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20607                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20608                            // This process is a cached process holding activities...
20609                            // assign it the next cached value for that type, and then
20610                            // step that cached level.
20611                            app.curRawAdj = curCachedAdj;
20612                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20613                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20614                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20615                                    + ")");
20616                            if (curCachedAdj != nextCachedAdj) {
20617                                stepCached++;
20618                                if (stepCached >= cachedFactor) {
20619                                    stepCached = 0;
20620                                    curCachedAdj = nextCachedAdj;
20621                                    nextCachedAdj += 2;
20622                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20623                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20624                                    }
20625                                }
20626                            }
20627                            break;
20628                        default:
20629                            // For everything else, assign next empty cached process
20630                            // level and bump that up.  Note that this means that
20631                            // long-running services that have dropped down to the
20632                            // cached level will be treated as empty (since their process
20633                            // state is still as a service), which is what we want.
20634                            app.curRawAdj = curEmptyAdj;
20635                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20636                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20637                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20638                                    + ")");
20639                            if (curEmptyAdj != nextEmptyAdj) {
20640                                stepEmpty++;
20641                                if (stepEmpty >= emptyFactor) {
20642                                    stepEmpty = 0;
20643                                    curEmptyAdj = nextEmptyAdj;
20644                                    nextEmptyAdj += 2;
20645                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20646                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20647                                    }
20648                                }
20649                            }
20650                            break;
20651                    }
20652                }
20653
20654                applyOomAdjLocked(app, true, now, nowElapsed);
20655
20656                // Count the number of process types.
20657                switch (app.curProcState) {
20658                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20659                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20660                        mNumCachedHiddenProcs++;
20661                        numCached++;
20662                        if (numCached > cachedProcessLimit) {
20663                            app.kill("cached #" + numCached, true);
20664                        }
20665                        break;
20666                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20667                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20668                                && app.lastActivityTime < oldTime) {
20669                            app.kill("empty for "
20670                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20671                                    / 1000) + "s", true);
20672                        } else {
20673                            numEmpty++;
20674                            if (numEmpty > emptyProcessLimit) {
20675                                app.kill("empty #" + numEmpty, true);
20676                            }
20677                        }
20678                        break;
20679                    default:
20680                        mNumNonCachedProcs++;
20681                        break;
20682                }
20683
20684                if (app.isolated && app.services.size() <= 0) {
20685                    // If this is an isolated process, and there are no
20686                    // services running in it, then the process is no longer
20687                    // needed.  We agressively kill these because we can by
20688                    // definition not re-use the same process again, and it is
20689                    // good to avoid having whatever code was running in them
20690                    // left sitting around after no longer needed.
20691                    app.kill("isolated not needed", true);
20692                } else {
20693                    // Keeping this process, update its uid.
20694                    final UidRecord uidRec = app.uidRecord;
20695                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20696                        uidRec.curProcState = app.curProcState;
20697                    }
20698                }
20699
20700                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20701                        && !app.killedByAm) {
20702                    numTrimming++;
20703                }
20704            }
20705        }
20706
20707        mNumServiceProcs = mNewNumServiceProcs;
20708
20709        // Now determine the memory trimming level of background processes.
20710        // Unfortunately we need to start at the back of the list to do this
20711        // properly.  We only do this if the number of background apps we
20712        // are managing to keep around is less than half the maximum we desire;
20713        // if we are keeping a good number around, we'll let them use whatever
20714        // memory they want.
20715        final int numCachedAndEmpty = numCached + numEmpty;
20716        int memFactor;
20717        if (numCached <= ProcessList.TRIM_CACHED_APPS
20718                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20719            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20720                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20721            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20722                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20723            } else {
20724                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20725            }
20726        } else {
20727            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20728        }
20729        // We always allow the memory level to go up (better).  We only allow it to go
20730        // down if we are in a state where that is allowed, *and* the total number of processes
20731        // has gone down since last time.
20732        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20733                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20734                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20735        if (memFactor > mLastMemoryLevel) {
20736            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20737                memFactor = mLastMemoryLevel;
20738                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20739            }
20740        }
20741        if (memFactor != mLastMemoryLevel) {
20742            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20743        }
20744        mLastMemoryLevel = memFactor;
20745        mLastNumProcesses = mLruProcesses.size();
20746        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20747        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20748        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20749            if (mLowRamStartTime == 0) {
20750                mLowRamStartTime = now;
20751            }
20752            int step = 0;
20753            int fgTrimLevel;
20754            switch (memFactor) {
20755                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20756                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20757                    break;
20758                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20759                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20760                    break;
20761                default:
20762                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20763                    break;
20764            }
20765            int factor = numTrimming/3;
20766            int minFactor = 2;
20767            if (mHomeProcess != null) minFactor++;
20768            if (mPreviousProcess != null) minFactor++;
20769            if (factor < minFactor) factor = minFactor;
20770            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20771            for (int i=N-1; i>=0; i--) {
20772                ProcessRecord app = mLruProcesses.get(i);
20773                if (allChanged || app.procStateChanged) {
20774                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20775                    app.procStateChanged = false;
20776                }
20777                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20778                        && !app.killedByAm) {
20779                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20780                        try {
20781                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20782                                    "Trimming memory of " + app.processName + " to " + curLevel);
20783                            app.thread.scheduleTrimMemory(curLevel);
20784                        } catch (RemoteException e) {
20785                        }
20786                        if (false) {
20787                            // For now we won't do this; our memory trimming seems
20788                            // to be good enough at this point that destroying
20789                            // activities causes more harm than good.
20790                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20791                                    && app != mHomeProcess && app != mPreviousProcess) {
20792                                // Need to do this on its own message because the stack may not
20793                                // be in a consistent state at this point.
20794                                // For these apps we will also finish their activities
20795                                // to help them free memory.
20796                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20797                            }
20798                        }
20799                    }
20800                    app.trimMemoryLevel = curLevel;
20801                    step++;
20802                    if (step >= factor) {
20803                        step = 0;
20804                        switch (curLevel) {
20805                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20806                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20807                                break;
20808                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20809                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20810                                break;
20811                        }
20812                    }
20813                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20814                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20815                            && app.thread != null) {
20816                        try {
20817                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20818                                    "Trimming memory of heavy-weight " + app.processName
20819                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20820                            app.thread.scheduleTrimMemory(
20821                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20822                        } catch (RemoteException e) {
20823                        }
20824                    }
20825                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20826                } else {
20827                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20828                            || app.systemNoUi) && app.pendingUiClean) {
20829                        // If this application is now in the background and it
20830                        // had done UI, then give it the special trim level to
20831                        // have it free UI resources.
20832                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20833                        if (app.trimMemoryLevel < level && app.thread != null) {
20834                            try {
20835                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20836                                        "Trimming memory of bg-ui " + app.processName
20837                                        + " to " + level);
20838                                app.thread.scheduleTrimMemory(level);
20839                            } catch (RemoteException e) {
20840                            }
20841                        }
20842                        app.pendingUiClean = false;
20843                    }
20844                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20845                        try {
20846                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20847                                    "Trimming memory of fg " + app.processName
20848                                    + " to " + fgTrimLevel);
20849                            app.thread.scheduleTrimMemory(fgTrimLevel);
20850                        } catch (RemoteException e) {
20851                        }
20852                    }
20853                    app.trimMemoryLevel = fgTrimLevel;
20854                }
20855            }
20856        } else {
20857            if (mLowRamStartTime != 0) {
20858                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20859                mLowRamStartTime = 0;
20860            }
20861            for (int i=N-1; i>=0; i--) {
20862                ProcessRecord app = mLruProcesses.get(i);
20863                if (allChanged || app.procStateChanged) {
20864                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20865                    app.procStateChanged = false;
20866                }
20867                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20868                        || app.systemNoUi) && app.pendingUiClean) {
20869                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20870                            && app.thread != null) {
20871                        try {
20872                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20873                                    "Trimming memory of ui hidden " + app.processName
20874                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20875                            app.thread.scheduleTrimMemory(
20876                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20877                        } catch (RemoteException e) {
20878                        }
20879                    }
20880                    app.pendingUiClean = false;
20881                }
20882                app.trimMemoryLevel = 0;
20883            }
20884        }
20885
20886        if (mAlwaysFinishActivities) {
20887            // Need to do this on its own message because the stack may not
20888            // be in a consistent state at this point.
20889            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20890        }
20891
20892        if (allChanged) {
20893            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20894        }
20895
20896        // Update from any uid changes.
20897        for (int i=mActiveUids.size()-1; i>=0; i--) {
20898            final UidRecord uidRec = mActiveUids.valueAt(i);
20899            int uidChange = UidRecord.CHANGE_PROCSTATE;
20900            if (uidRec.setProcState != uidRec.curProcState) {
20901                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20902                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20903                        + " to " + uidRec.curProcState);
20904                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20905                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20906                        uidRec.lastBackgroundTime = nowElapsed;
20907                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20908                            // Note: the background settle time is in elapsed realtime, while
20909                            // the handler time base is uptime.  All this means is that we may
20910                            // stop background uids later than we had intended, but that only
20911                            // happens because the device was sleeping so we are okay anyway.
20912                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20913                        }
20914                    }
20915                } else {
20916                    if (uidRec.idle) {
20917                        uidChange = UidRecord.CHANGE_ACTIVE;
20918                        uidRec.idle = false;
20919                    }
20920                    uidRec.lastBackgroundTime = 0;
20921                }
20922                uidRec.setProcState = uidRec.curProcState;
20923                enqueueUidChangeLocked(uidRec, -1, uidChange);
20924                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20925            }
20926        }
20927
20928        if (mProcessStats.shouldWriteNowLocked(now)) {
20929            mHandler.post(new Runnable() {
20930                @Override public void run() {
20931                    synchronized (ActivityManagerService.this) {
20932                        mProcessStats.writeStateAsyncLocked();
20933                    }
20934                }
20935            });
20936        }
20937
20938        if (DEBUG_OOM_ADJ) {
20939            final long duration = SystemClock.uptimeMillis() - now;
20940            if (false) {
20941                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20942                        new RuntimeException("here").fillInStackTrace());
20943            } else {
20944                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20945            }
20946        }
20947    }
20948
20949    final void idleUids() {
20950        synchronized (this) {
20951            final long nowElapsed = SystemClock.elapsedRealtime();
20952            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20953            long nextTime = 0;
20954            for (int i=mActiveUids.size()-1; i>=0; i--) {
20955                final UidRecord uidRec = mActiveUids.valueAt(i);
20956                final long bgTime = uidRec.lastBackgroundTime;
20957                if (bgTime > 0 && !uidRec.idle) {
20958                    if (bgTime <= maxBgTime) {
20959                        uidRec.idle = true;
20960                        doStopUidLocked(uidRec.uid, uidRec);
20961                    } else {
20962                        if (nextTime == 0 || nextTime > bgTime) {
20963                            nextTime = bgTime;
20964                        }
20965                    }
20966                }
20967            }
20968            if (nextTime > 0) {
20969                mHandler.removeMessages(IDLE_UIDS_MSG);
20970                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20971                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20972            }
20973        }
20974    }
20975
20976    final void runInBackgroundDisabled(int uid) {
20977        synchronized (this) {
20978            UidRecord uidRec = mActiveUids.get(uid);
20979            if (uidRec != null) {
20980                // This uid is actually running...  should it be considered background now?
20981                if (uidRec.idle) {
20982                    doStopUidLocked(uidRec.uid, uidRec);
20983                }
20984            } else {
20985                // This uid isn't actually running...  still send a report about it being "stopped".
20986                doStopUidLocked(uid, null);
20987            }
20988        }
20989    }
20990
20991    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20992        mServices.stopInBackgroundLocked(uid);
20993        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20994    }
20995
20996    final void trimApplications() {
20997        synchronized (this) {
20998            int i;
20999
21000            // First remove any unused application processes whose package
21001            // has been removed.
21002            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21003                final ProcessRecord app = mRemovedProcesses.get(i);
21004                if (app.activities.size() == 0
21005                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21006                    Slog.i(
21007                        TAG, "Exiting empty application process "
21008                        + app.toShortString() + " ("
21009                        + (app.thread != null ? app.thread.asBinder() : null)
21010                        + ")\n");
21011                    if (app.pid > 0 && app.pid != MY_PID) {
21012                        app.kill("empty", false);
21013                    } else {
21014                        try {
21015                            app.thread.scheduleExit();
21016                        } catch (Exception e) {
21017                            // Ignore exceptions.
21018                        }
21019                    }
21020                    cleanUpApplicationRecordLocked(app, false, true, -1);
21021                    mRemovedProcesses.remove(i);
21022
21023                    if (app.persistent) {
21024                        addAppLocked(app.info, false, null /* ABI override */);
21025                    }
21026                }
21027            }
21028
21029            // Now update the oom adj for all processes.
21030            updateOomAdjLocked();
21031        }
21032    }
21033
21034    /** This method sends the specified signal to each of the persistent apps */
21035    public void signalPersistentProcesses(int sig) throws RemoteException {
21036        if (sig != Process.SIGNAL_USR1) {
21037            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21038        }
21039
21040        synchronized (this) {
21041            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21042                    != PackageManager.PERMISSION_GRANTED) {
21043                throw new SecurityException("Requires permission "
21044                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21045            }
21046
21047            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21048                ProcessRecord r = mLruProcesses.get(i);
21049                if (r.thread != null && r.persistent) {
21050                    Process.sendSignal(r.pid, sig);
21051                }
21052            }
21053        }
21054    }
21055
21056    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21057        if (proc == null || proc == mProfileProc) {
21058            proc = mProfileProc;
21059            profileType = mProfileType;
21060            clearProfilerLocked();
21061        }
21062        if (proc == null) {
21063            return;
21064        }
21065        try {
21066            proc.thread.profilerControl(false, null, profileType);
21067        } catch (RemoteException e) {
21068            throw new IllegalStateException("Process disappeared");
21069        }
21070    }
21071
21072    private void clearProfilerLocked() {
21073        if (mProfileFd != null) {
21074            try {
21075                mProfileFd.close();
21076            } catch (IOException e) {
21077            }
21078        }
21079        mProfileApp = null;
21080        mProfileProc = null;
21081        mProfileFile = null;
21082        mProfileType = 0;
21083        mAutoStopProfiler = false;
21084        mSamplingInterval = 0;
21085    }
21086
21087    public boolean profileControl(String process, int userId, boolean start,
21088            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21089
21090        try {
21091            synchronized (this) {
21092                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21093                // its own permission.
21094                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21095                        != PackageManager.PERMISSION_GRANTED) {
21096                    throw new SecurityException("Requires permission "
21097                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21098                }
21099
21100                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21101                    throw new IllegalArgumentException("null profile info or fd");
21102                }
21103
21104                ProcessRecord proc = null;
21105                if (process != null) {
21106                    proc = findProcessLocked(process, userId, "profileControl");
21107                }
21108
21109                if (start && (proc == null || proc.thread == null)) {
21110                    throw new IllegalArgumentException("Unknown process: " + process);
21111                }
21112
21113                if (start) {
21114                    stopProfilerLocked(null, 0);
21115                    setProfileApp(proc.info, proc.processName, profilerInfo);
21116                    mProfileProc = proc;
21117                    mProfileType = profileType;
21118                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21119                    try {
21120                        fd = fd.dup();
21121                    } catch (IOException e) {
21122                        fd = null;
21123                    }
21124                    profilerInfo.profileFd = fd;
21125                    proc.thread.profilerControl(start, profilerInfo, profileType);
21126                    fd = null;
21127                    mProfileFd = null;
21128                } else {
21129                    stopProfilerLocked(proc, profileType);
21130                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21131                        try {
21132                            profilerInfo.profileFd.close();
21133                        } catch (IOException e) {
21134                        }
21135                    }
21136                }
21137
21138                return true;
21139            }
21140        } catch (RemoteException e) {
21141            throw new IllegalStateException("Process disappeared");
21142        } finally {
21143            if (profilerInfo != null && profilerInfo.profileFd != null) {
21144                try {
21145                    profilerInfo.profileFd.close();
21146                } catch (IOException e) {
21147                }
21148            }
21149        }
21150    }
21151
21152    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21153        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21154                userId, true, ALLOW_FULL_ONLY, callName, null);
21155        ProcessRecord proc = null;
21156        try {
21157            int pid = Integer.parseInt(process);
21158            synchronized (mPidsSelfLocked) {
21159                proc = mPidsSelfLocked.get(pid);
21160            }
21161        } catch (NumberFormatException e) {
21162        }
21163
21164        if (proc == null) {
21165            ArrayMap<String, SparseArray<ProcessRecord>> all
21166                    = mProcessNames.getMap();
21167            SparseArray<ProcessRecord> procs = all.get(process);
21168            if (procs != null && procs.size() > 0) {
21169                proc = procs.valueAt(0);
21170                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21171                    for (int i=1; i<procs.size(); i++) {
21172                        ProcessRecord thisProc = procs.valueAt(i);
21173                        if (thisProc.userId == userId) {
21174                            proc = thisProc;
21175                            break;
21176                        }
21177                    }
21178                }
21179            }
21180        }
21181
21182        return proc;
21183    }
21184
21185    public boolean dumpHeap(String process, int userId, boolean managed,
21186            String path, ParcelFileDescriptor fd) throws RemoteException {
21187
21188        try {
21189            synchronized (this) {
21190                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21191                // its own permission (same as profileControl).
21192                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21193                        != PackageManager.PERMISSION_GRANTED) {
21194                    throw new SecurityException("Requires permission "
21195                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21196                }
21197
21198                if (fd == null) {
21199                    throw new IllegalArgumentException("null fd");
21200                }
21201
21202                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21203                if (proc == null || proc.thread == null) {
21204                    throw new IllegalArgumentException("Unknown process: " + process);
21205                }
21206
21207                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21208                if (!isDebuggable) {
21209                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21210                        throw new SecurityException("Process not debuggable: " + proc);
21211                    }
21212                }
21213
21214                proc.thread.dumpHeap(managed, path, fd);
21215                fd = null;
21216                return true;
21217            }
21218        } catch (RemoteException e) {
21219            throw new IllegalStateException("Process disappeared");
21220        } finally {
21221            if (fd != null) {
21222                try {
21223                    fd.close();
21224                } catch (IOException e) {
21225                }
21226            }
21227        }
21228    }
21229
21230    @Override
21231    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21232            String reportPackage) {
21233        if (processName != null) {
21234            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21235                    "setDumpHeapDebugLimit()");
21236        } else {
21237            synchronized (mPidsSelfLocked) {
21238                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21239                if (proc == null) {
21240                    throw new SecurityException("No process found for calling pid "
21241                            + Binder.getCallingPid());
21242                }
21243                if (!Build.IS_DEBUGGABLE
21244                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21245                    throw new SecurityException("Not running a debuggable build");
21246                }
21247                processName = proc.processName;
21248                uid = proc.uid;
21249                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21250                    throw new SecurityException("Package " + reportPackage + " is not running in "
21251                            + proc);
21252                }
21253            }
21254        }
21255        synchronized (this) {
21256            if (maxMemSize > 0) {
21257                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21258            } else {
21259                if (uid != 0) {
21260                    mMemWatchProcesses.remove(processName, uid);
21261                } else {
21262                    mMemWatchProcesses.getMap().remove(processName);
21263                }
21264            }
21265        }
21266    }
21267
21268    @Override
21269    public void dumpHeapFinished(String path) {
21270        synchronized (this) {
21271            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21272                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21273                        + " does not match last pid " + mMemWatchDumpPid);
21274                return;
21275            }
21276            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21277                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21278                        + " does not match last path " + mMemWatchDumpFile);
21279                return;
21280            }
21281            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21282            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21283        }
21284    }
21285
21286    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21287    public void monitor() {
21288        synchronized (this) { }
21289    }
21290
21291    void onCoreSettingsChange(Bundle settings) {
21292        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21293            ProcessRecord processRecord = mLruProcesses.get(i);
21294            try {
21295                if (processRecord.thread != null) {
21296                    processRecord.thread.setCoreSettings(settings);
21297                }
21298            } catch (RemoteException re) {
21299                /* ignore */
21300            }
21301        }
21302    }
21303
21304    // Multi-user methods
21305
21306    /**
21307     * Start user, if its not already running, but don't bring it to foreground.
21308     */
21309    @Override
21310    public boolean startUserInBackground(final int userId) {
21311        return mUserController.startUser(userId, /* foreground */ false);
21312    }
21313
21314    @Override
21315    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21316        return mUserController.unlockUser(userId, token, secret, listener);
21317    }
21318
21319    @Override
21320    public boolean switchUser(final int targetUserId) {
21321        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21322        UserInfo currentUserInfo;
21323        UserInfo targetUserInfo;
21324        synchronized (this) {
21325            int currentUserId = mUserController.getCurrentUserIdLocked();
21326            currentUserInfo = mUserController.getUserInfo(currentUserId);
21327            targetUserInfo = mUserController.getUserInfo(targetUserId);
21328            if (targetUserInfo == null) {
21329                Slog.w(TAG, "No user info for user #" + targetUserId);
21330                return false;
21331            }
21332            if (!targetUserInfo.supportsSwitchTo()) {
21333                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21334                return false;
21335            }
21336            if (targetUserInfo.isManagedProfile()) {
21337                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21338                return false;
21339            }
21340            mUserController.setTargetUserIdLocked(targetUserId);
21341        }
21342        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21343        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21344        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21345        return true;
21346    }
21347
21348    void scheduleStartProfilesLocked() {
21349        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21350            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21351                    DateUtils.SECOND_IN_MILLIS);
21352        }
21353    }
21354
21355    @Override
21356    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21357        return mUserController.stopUser(userId, force, callback);
21358    }
21359
21360    @Override
21361    public UserInfo getCurrentUser() {
21362        return mUserController.getCurrentUser();
21363    }
21364
21365    @Override
21366    public boolean isUserRunning(int userId, int flags) {
21367        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21368                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21369            String msg = "Permission Denial: isUserRunning() from pid="
21370                    + Binder.getCallingPid()
21371                    + ", uid=" + Binder.getCallingUid()
21372                    + " requires " + INTERACT_ACROSS_USERS;
21373            Slog.w(TAG, msg);
21374            throw new SecurityException(msg);
21375        }
21376        synchronized (this) {
21377            return mUserController.isUserRunningLocked(userId, flags);
21378        }
21379    }
21380
21381    @Override
21382    public int[] getRunningUserIds() {
21383        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21384                != PackageManager.PERMISSION_GRANTED) {
21385            String msg = "Permission Denial: isUserRunning() from pid="
21386                    + Binder.getCallingPid()
21387                    + ", uid=" + Binder.getCallingUid()
21388                    + " requires " + INTERACT_ACROSS_USERS;
21389            Slog.w(TAG, msg);
21390            throw new SecurityException(msg);
21391        }
21392        synchronized (this) {
21393            return mUserController.getStartedUserArrayLocked();
21394        }
21395    }
21396
21397    @Override
21398    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21399        mUserController.registerUserSwitchObserver(observer);
21400    }
21401
21402    @Override
21403    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21404        mUserController.unregisterUserSwitchObserver(observer);
21405    }
21406
21407    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21408        if (info == null) return null;
21409        ApplicationInfo newInfo = new ApplicationInfo(info);
21410        newInfo.initForUser(userId);
21411        return newInfo;
21412    }
21413
21414    public boolean isUserStopped(int userId) {
21415        synchronized (this) {
21416            return mUserController.getStartedUserStateLocked(userId) == null;
21417        }
21418    }
21419
21420    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21421        if (aInfo == null
21422                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21423            return aInfo;
21424        }
21425
21426        ActivityInfo info = new ActivityInfo(aInfo);
21427        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21428        return info;
21429    }
21430
21431    private boolean processSanityChecksLocked(ProcessRecord process) {
21432        if (process == null || process.thread == null) {
21433            return false;
21434        }
21435
21436        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21437        if (!isDebuggable) {
21438            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21439                return false;
21440            }
21441        }
21442
21443        return true;
21444    }
21445
21446    public boolean startBinderTracking() throws RemoteException {
21447        synchronized (this) {
21448            mBinderTransactionTrackingEnabled = true;
21449            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21450            // permission (same as profileControl).
21451            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21452                    != PackageManager.PERMISSION_GRANTED) {
21453                throw new SecurityException("Requires permission "
21454                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21455            }
21456
21457            for (int i = 0; i < mLruProcesses.size(); i++) {
21458                ProcessRecord process = mLruProcesses.get(i);
21459                if (!processSanityChecksLocked(process)) {
21460                    continue;
21461                }
21462                try {
21463                    process.thread.startBinderTracking();
21464                } catch (RemoteException e) {
21465                    Log.v(TAG, "Process disappared");
21466                }
21467            }
21468            return true;
21469        }
21470    }
21471
21472    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21473        try {
21474            synchronized (this) {
21475                mBinderTransactionTrackingEnabled = false;
21476                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21477                // permission (same as profileControl).
21478                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21479                        != PackageManager.PERMISSION_GRANTED) {
21480                    throw new SecurityException("Requires permission "
21481                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21482                }
21483
21484                if (fd == null) {
21485                    throw new IllegalArgumentException("null fd");
21486                }
21487
21488                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21489                pw.println("Binder transaction traces for all processes.\n");
21490                for (ProcessRecord process : mLruProcesses) {
21491                    if (!processSanityChecksLocked(process)) {
21492                        continue;
21493                    }
21494
21495                    pw.println("Traces for process: " + process.processName);
21496                    pw.flush();
21497                    try {
21498                        TransferPipe tp = new TransferPipe();
21499                        try {
21500                            process.thread.stopBinderTrackingAndDump(
21501                                    tp.getWriteFd().getFileDescriptor());
21502                            tp.go(fd.getFileDescriptor());
21503                        } finally {
21504                            tp.kill();
21505                        }
21506                    } catch (IOException e) {
21507                        pw.println("Failure while dumping IPC traces from " + process +
21508                                ".  Exception: " + e);
21509                        pw.flush();
21510                    } catch (RemoteException e) {
21511                        pw.println("Got a RemoteException while dumping IPC traces from " +
21512                                process + ".  Exception: " + e);
21513                        pw.flush();
21514                    }
21515                }
21516                fd = null;
21517                return true;
21518            }
21519        } finally {
21520            if (fd != null) {
21521                try {
21522                    fd.close();
21523                } catch (IOException e) {
21524                }
21525            }
21526        }
21527    }
21528
21529    private final class LocalService extends ActivityManagerInternal {
21530        @Override
21531        public void onWakefulnessChanged(int wakefulness) {
21532            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21533        }
21534
21535        @Override
21536        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21537                String processName, String abiOverride, int uid, Runnable crashHandler) {
21538            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21539                    processName, abiOverride, uid, crashHandler);
21540        }
21541
21542        @Override
21543        public SleepToken acquireSleepToken(String tag) {
21544            Preconditions.checkNotNull(tag);
21545
21546            ComponentName requestedVrService = null;
21547            ComponentName callingVrActivity = null;
21548            int userId = -1;
21549            synchronized (ActivityManagerService.this) {
21550                if (mFocusedActivity != null) {
21551                    requestedVrService = mFocusedActivity.requestedVrComponent;
21552                    callingVrActivity = mFocusedActivity.info.getComponentName();
21553                    userId = mFocusedActivity.userId;
21554                }
21555            }
21556
21557            if (requestedVrService != null) {
21558                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21559            }
21560
21561            synchronized (ActivityManagerService.this) {
21562                SleepTokenImpl token = new SleepTokenImpl(tag);
21563                mSleepTokens.add(token);
21564                updateSleepIfNeededLocked();
21565                return token;
21566            }
21567        }
21568
21569        @Override
21570        public ComponentName getHomeActivityForUser(int userId) {
21571            synchronized (ActivityManagerService.this) {
21572                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21573                return homeActivity == null ? null : homeActivity.realActivity;
21574            }
21575        }
21576
21577        @Override
21578        public void onUserRemoved(int userId) {
21579            synchronized (ActivityManagerService.this) {
21580                ActivityManagerService.this.onUserStoppedLocked(userId);
21581            }
21582        }
21583
21584        @Override
21585        public void onLocalVoiceInteractionStarted(IBinder activity,
21586                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21587            synchronized (ActivityManagerService.this) {
21588                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21589                        voiceSession, voiceInteractor);
21590            }
21591        }
21592
21593        @Override
21594        public void notifyStartingWindowDrawn() {
21595            synchronized (ActivityManagerService.this) {
21596                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21597            }
21598        }
21599
21600        @Override
21601        public void notifyAppTransitionStarting(int reason) {
21602            synchronized (ActivityManagerService.this) {
21603                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21604            }
21605        }
21606
21607        @Override
21608        public void notifyAppTransitionFinished() {
21609            synchronized (ActivityManagerService.this) {
21610                mStackSupervisor.notifyAppTransitionDone();
21611            }
21612        }
21613
21614        @Override
21615        public void notifyAppTransitionCancelled() {
21616            synchronized (ActivityManagerService.this) {
21617                mStackSupervisor.notifyAppTransitionDone();
21618            }
21619        }
21620
21621        @Override
21622        public List<IBinder> getTopVisibleActivities() {
21623            synchronized (ActivityManagerService.this) {
21624                return mStackSupervisor.getTopVisibleActivities();
21625            }
21626        }
21627
21628        @Override
21629        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21630            synchronized (ActivityManagerService.this) {
21631                mStackSupervisor.setDockedStackMinimized(minimized);
21632            }
21633        }
21634
21635        @Override
21636        public void killForegroundAppsForUser(int userHandle) {
21637            synchronized (ActivityManagerService.this) {
21638                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21639                final int NP = mProcessNames.getMap().size();
21640                for (int ip = 0; ip < NP; ip++) {
21641                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21642                    final int NA = apps.size();
21643                    for (int ia = 0; ia < NA; ia++) {
21644                        final ProcessRecord app = apps.valueAt(ia);
21645                        if (app.persistent) {
21646                            // We don't kill persistent processes.
21647                            continue;
21648                        }
21649                        if (app.removed) {
21650                            procs.add(app);
21651                        } else if (app.userId == userHandle && app.foregroundActivities) {
21652                            app.removed = true;
21653                            procs.add(app);
21654                        }
21655                    }
21656                }
21657
21658                final int N = procs.size();
21659                for (int i = 0; i < N; i++) {
21660                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21661                }
21662            }
21663        }
21664
21665        @Override
21666        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21667            if (!(target instanceof PendingIntentRecord)) {
21668                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21669                return;
21670            }
21671            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21672        }
21673    }
21674
21675    private final class SleepTokenImpl extends SleepToken {
21676        private final String mTag;
21677        private final long mAcquireTime;
21678
21679        public SleepTokenImpl(String tag) {
21680            mTag = tag;
21681            mAcquireTime = SystemClock.uptimeMillis();
21682        }
21683
21684        @Override
21685        public void release() {
21686            synchronized (ActivityManagerService.this) {
21687                if (mSleepTokens.remove(this)) {
21688                    updateSleepIfNeededLocked();
21689                }
21690            }
21691        }
21692
21693        @Override
21694        public String toString() {
21695            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21696        }
21697    }
21698
21699    /**
21700     * An implementation of IAppTask, that allows an app to manage its own tasks via
21701     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21702     * only the process that calls getAppTasks() can call the AppTask methods.
21703     */
21704    class AppTaskImpl extends IAppTask.Stub {
21705        private int mTaskId;
21706        private int mCallingUid;
21707
21708        public AppTaskImpl(int taskId, int callingUid) {
21709            mTaskId = taskId;
21710            mCallingUid = callingUid;
21711        }
21712
21713        private void checkCaller() {
21714            if (mCallingUid != Binder.getCallingUid()) {
21715                throw new SecurityException("Caller " + mCallingUid
21716                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21717            }
21718        }
21719
21720        @Override
21721        public void finishAndRemoveTask() {
21722            checkCaller();
21723
21724            synchronized (ActivityManagerService.this) {
21725                long origId = Binder.clearCallingIdentity();
21726                try {
21727                    // We remove the task from recents to preserve backwards
21728                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21729                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21730                    }
21731                } finally {
21732                    Binder.restoreCallingIdentity(origId);
21733                }
21734            }
21735        }
21736
21737        @Override
21738        public ActivityManager.RecentTaskInfo getTaskInfo() {
21739            checkCaller();
21740
21741            synchronized (ActivityManagerService.this) {
21742                long origId = Binder.clearCallingIdentity();
21743                try {
21744                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21745                    if (tr == null) {
21746                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21747                    }
21748                    return createRecentTaskInfoFromTaskRecord(tr);
21749                } finally {
21750                    Binder.restoreCallingIdentity(origId);
21751                }
21752            }
21753        }
21754
21755        @Override
21756        public void moveToFront() {
21757            checkCaller();
21758            // Will bring task to front if it already has a root activity.
21759            final long origId = Binder.clearCallingIdentity();
21760            try {
21761                synchronized (this) {
21762                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21763                }
21764            } finally {
21765                Binder.restoreCallingIdentity(origId);
21766            }
21767        }
21768
21769        @Override
21770        public int startActivity(IBinder whoThread, String callingPackage,
21771                Intent intent, String resolvedType, Bundle bOptions) {
21772            checkCaller();
21773
21774            int callingUser = UserHandle.getCallingUserId();
21775            TaskRecord tr;
21776            IApplicationThread appThread;
21777            synchronized (ActivityManagerService.this) {
21778                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21779                if (tr == null) {
21780                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21781                }
21782                appThread = ApplicationThreadNative.asInterface(whoThread);
21783                if (appThread == null) {
21784                    throw new IllegalArgumentException("Bad app thread " + appThread);
21785                }
21786            }
21787            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21788                    resolvedType, null, null, null, null, 0, 0, null, null,
21789                    null, bOptions, false, callingUser, null, tr);
21790        }
21791
21792        @Override
21793        public void setExcludeFromRecents(boolean exclude) {
21794            checkCaller();
21795
21796            synchronized (ActivityManagerService.this) {
21797                long origId = Binder.clearCallingIdentity();
21798                try {
21799                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21800                    if (tr == null) {
21801                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21802                    }
21803                    Intent intent = tr.getBaseIntent();
21804                    if (exclude) {
21805                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21806                    } else {
21807                        intent.setFlags(intent.getFlags()
21808                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21809                    }
21810                } finally {
21811                    Binder.restoreCallingIdentity(origId);
21812                }
21813            }
21814        }
21815    }
21816
21817    /**
21818     * Kill processes for the user with id userId and that depend on the package named packageName
21819     */
21820    @Override
21821    public void killPackageDependents(String packageName, int userId) {
21822        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21823        if (packageName == null) {
21824            throw new NullPointerException(
21825                    "Cannot kill the dependents of a package without its name.");
21826        }
21827
21828        long callingId = Binder.clearCallingIdentity();
21829        IPackageManager pm = AppGlobals.getPackageManager();
21830        int pkgUid = -1;
21831        try {
21832            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21833        } catch (RemoteException e) {
21834        }
21835        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21836            throw new IllegalArgumentException(
21837                    "Cannot kill dependents of non-existing package " + packageName);
21838        }
21839        try {
21840            synchronized(this) {
21841                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21842                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21843                        "dep: " + packageName);
21844            }
21845        } finally {
21846            Binder.restoreCallingIdentity(callingId);
21847        }
21848    }
21849
21850    /**
21851     * Attach an agent to the specified process (proces name or PID)
21852     */
21853    public void attachAgent(String process, String path) {
21854        try {
21855            synchronized (this) {
21856                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
21857                if (proc == null || proc.thread == null) {
21858                    throw new IllegalArgumentException("Unknown process: " + process);
21859                }
21860
21861                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21862                if (!isDebuggable) {
21863                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21864                        throw new SecurityException("Process not debuggable: " + proc);
21865                    }
21866                }
21867
21868                proc.thread.attachAgent(path);
21869            }
21870        } catch (RemoteException e) {
21871            throw new IllegalStateException("Process disappeared");
21872        }
21873    }
21874}
21875