ActivityManagerService.java revision a8e6f875bc07dc12d3c8284cef5b5d83d93ff743
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.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.text.format.DateUtils;
203import android.text.format.Time;
204import android.text.style.SuggestionSpan;
205import android.util.ArrayMap;
206import android.util.ArraySet;
207import android.util.AtomicFile;
208import android.util.DebugUtils;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
267import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
268import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
269import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270import static android.content.pm.PackageManager.GET_PROVIDERS;
271import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
278import static android.provider.Settings.Global.DEBUG_APP;
279import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
281import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
282import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
283import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
284import static android.provider.Settings.System.FONT_SCALE;
285import static com.android.internal.util.XmlUtils.readBooleanAttribute;
286import static com.android.internal.util.XmlUtils.readIntAttribute;
287import static com.android.internal.util.XmlUtils.readLongAttribute;
288import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
289import static com.android.internal.util.XmlUtils.writeIntAttribute;
290import static com.android.internal.util.XmlUtils.writeLongAttribute;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastQueue broadcastQueueForIntent(Intent intent) {
571        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
572        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
573                "Broadcast intent " + intent + " on "
574                + (isFg ? "foreground" : "background") + " queue");
575        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
576    }
577
578    /**
579     * Activity we have told the window manager to have key focus.
580     */
581    ActivityRecord mFocusedActivity = null;
582
583    /**
584     * User id of the last activity mFocusedActivity was set to.
585     */
586    private int mLastFocusedUserId;
587
588    /**
589     * If non-null, we are tracking the time the user spends in the currently focused app.
590     */
591    private AppTimeTracker mCurAppTimeTracker;
592
593    /**
594     * List of intents that were used to start the most recent tasks.
595     */
596    final RecentTasks mRecentTasks;
597
598    /**
599     * For addAppTask: cached of the last activity component that was added.
600     */
601    ComponentName mLastAddedTaskComponent;
602
603    /**
604     * For addAppTask: cached of the last activity uid that was added.
605     */
606    int mLastAddedTaskUid;
607
608    /**
609     * For addAppTask: cached of the last ActivityInfo that was added.
610     */
611    ActivityInfo mLastAddedTaskActivity;
612
613    /**
614     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
615     */
616    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
617
618    /**
619     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
620     */
621    String mDeviceOwnerName;
622
623    final UserController mUserController;
624
625    final AppErrors mAppErrors;
626
627    boolean mDoingSetFocusedActivity;
628
629    public boolean canShowErrorDialogs() {
630        return mShowDialogs && !mSleeping && !mShuttingDown;
631    }
632
633    // it's a semaphore; boost when 0->1, reset when 1->0
634    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
635        @Override protected Integer initialValue() {
636            return 0;
637        }
638    };
639
640    static void boostPriorityForLockedSection() {
641        if (sIsBoosted.get() == 0) {
642            // boost to prio 118 while holding a global lock
643            Process.setThreadPriority(Process.myTid(), -2);
644            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
645        }
646        int cur = sIsBoosted.get();
647        sIsBoosted.set(cur + 1);
648    }
649
650    static void resetPriorityAfterLockedSection() {
651        sIsBoosted.set(sIsBoosted.get() - 1);
652        if (sIsBoosted.get() == 0) {
653            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
654            Process.setThreadPriority(Process.myTid(), 0);
655        }
656    }
657    public class PendingAssistExtras extends Binder implements Runnable {
658        public final ActivityRecord activity;
659        public final Bundle extras;
660        public final Intent intent;
661        public final String hint;
662        public final IResultReceiver receiver;
663        public final int userHandle;
664        public boolean haveResult = false;
665        public Bundle result = null;
666        public AssistStructure structure = null;
667        public AssistContent content = null;
668        public Bundle receiverExtras;
669
670        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
671                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
672            activity = _activity;
673            extras = _extras;
674            intent = _intent;
675            hint = _hint;
676            receiver = _receiver;
677            receiverExtras = _receiverExtras;
678            userHandle = _userHandle;
679        }
680        @Override
681        public void run() {
682            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
683            synchronized (this) {
684                haveResult = true;
685                notifyAll();
686            }
687            pendingAssistExtrasTimedOut(this);
688        }
689    }
690
691    final ArrayList<PendingAssistExtras> mPendingAssistExtras
692            = new ArrayList<PendingAssistExtras>();
693
694    /**
695     * Process management.
696     */
697    final ProcessList mProcessList = new ProcessList();
698
699    /**
700     * All of the applications we currently have running organized by name.
701     * The keys are strings of the application package name (as
702     * returned by the package manager), and the keys are ApplicationRecord
703     * objects.
704     */
705    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
706
707    /**
708     * Tracking long-term execution of processes to look for abuse and other
709     * bad app behavior.
710     */
711    final ProcessStatsService mProcessStats;
712
713    /**
714     * The currently running isolated processes.
715     */
716    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
717
718    /**
719     * Counter for assigning isolated process uids, to avoid frequently reusing the
720     * same ones.
721     */
722    int mNextIsolatedProcessUid = 0;
723
724    /**
725     * The currently running heavy-weight process, if any.
726     */
727    ProcessRecord mHeavyWeightProcess = null;
728
729    /**
730     * All of the processes we currently have running organized by pid.
731     * The keys are the pid running the application.
732     *
733     * <p>NOTE: This object is protected by its own lock, NOT the global
734     * activity manager lock!
735     */
736    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
737
738    /**
739     * All of the processes that have been forced to be foreground.  The key
740     * is the pid of the caller who requested it (we hold a death
741     * link on it).
742     */
743    abstract class ForegroundToken implements IBinder.DeathRecipient {
744        int pid;
745        IBinder token;
746    }
747    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
748
749    /**
750     * List of records for processes that someone had tried to start before the
751     * system was ready.  We don't start them at that point, but ensure they
752     * are started by the time booting is complete.
753     */
754    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
755
756    /**
757     * List of persistent applications that are in the process
758     * of being started.
759     */
760    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes that are being forcibly torn down.
764     */
765    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
766
767    /**
768     * List of running applications, sorted by recent usage.
769     * The first entry in the list is the least recently used.
770     */
771    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * Where in mLruProcesses that the processes hosting activities start.
775     */
776    int mLruProcessActivityStart = 0;
777
778    /**
779     * Where in mLruProcesses that the processes hosting services start.
780     * This is after (lower index) than mLruProcessesActivityStart.
781     */
782    int mLruProcessServiceStart = 0;
783
784    /**
785     * List of processes that should gc as soon as things are idle.
786     */
787    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes we want to collect PSS data from.
791     */
792    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
793
794    private boolean mBinderTransactionTrackingEnabled = false;
795
796    /**
797     * Last time we requested PSS data of all processes.
798     */
799    long mLastFullPssTime = SystemClock.uptimeMillis();
800
801    /**
802     * If set, the next time we collect PSS data we should do a full collection
803     * with data from native processes and the kernel.
804     */
805    boolean mFullPssPending = false;
806
807    /**
808     * This is the process holding what we currently consider to be
809     * the "home" activity.
810     */
811    ProcessRecord mHomeProcess;
812
813    /**
814     * This is the process holding the activity the user last visited that
815     * is in a different process from the one they are currently in.
816     */
817    ProcessRecord mPreviousProcess;
818
819    /**
820     * The time at which the previous process was last visible.
821     */
822    long mPreviousProcessVisibleTime;
823
824    /**
825     * Track all uids that have actively running processes.
826     */
827    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
828
829    /**
830     * This is for verifying the UID report flow.
831     */
832    static final boolean VALIDATE_UID_STATES = true;
833    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
834
835    /**
836     * Packages that the user has asked to have run in screen size
837     * compatibility mode instead of filling the screen.
838     */
839    final CompatModePackages mCompatModePackages;
840
841    /**
842     * Set of IntentSenderRecord objects that are currently active.
843     */
844    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
845            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
846
847    /**
848     * Fingerprints (hashCode()) of stack traces that we've
849     * already logged DropBox entries for.  Guarded by itself.  If
850     * something (rogue user app) forces this over
851     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
852     */
853    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
854    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
855
856    /**
857     * Strict Mode background batched logging state.
858     *
859     * The string buffer is guarded by itself, and its lock is also
860     * used to determine if another batched write is already
861     * in-flight.
862     */
863    private final StringBuilder mStrictModeBuffer = new StringBuilder();
864
865    /**
866     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
867     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
868     */
869    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
870
871    /**
872     * Resolver for broadcast intents to registered receivers.
873     * Holds BroadcastFilter (subclass of IntentFilter).
874     */
875    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
876            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
877        @Override
878        protected boolean allowFilterResult(
879                BroadcastFilter filter, List<BroadcastFilter> dest) {
880            IBinder target = filter.receiverList.receiver.asBinder();
881            for (int i = dest.size() - 1; i >= 0; i--) {
882                if (dest.get(i).receiverList.receiver.asBinder() == target) {
883                    return false;
884                }
885            }
886            return true;
887        }
888
889        @Override
890        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
891            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
892                    || userId == filter.owningUserId) {
893                return super.newResult(filter, match, userId);
894            }
895            return null;
896        }
897
898        @Override
899        protected BroadcastFilter[] newArray(int size) {
900            return new BroadcastFilter[size];
901        }
902
903        @Override
904        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
905            return packageName.equals(filter.packageName);
906        }
907    };
908
909    /**
910     * State of all active sticky broadcasts per user.  Keys are the action of the
911     * sticky Intent, values are an ArrayList of all broadcasted intents with
912     * that action (which should usually be one).  The SparseArray is keyed
913     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
914     * for stickies that are sent to all users.
915     */
916    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
917            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
918
919    final ActiveServices mServices;
920
921    final static class Association {
922        final int mSourceUid;
923        final String mSourceProcess;
924        final int mTargetUid;
925        final ComponentName mTargetComponent;
926        final String mTargetProcess;
927
928        int mCount;
929        long mTime;
930
931        int mNesting;
932        long mStartTime;
933
934        // states of the source process when the bind occurred.
935        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
936        long mLastStateUptime;
937        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
938                - ActivityManager.MIN_PROCESS_STATE+1];
939
940        Association(int sourceUid, String sourceProcess, int targetUid,
941                ComponentName targetComponent, String targetProcess) {
942            mSourceUid = sourceUid;
943            mSourceProcess = sourceProcess;
944            mTargetUid = targetUid;
945            mTargetComponent = targetComponent;
946            mTargetProcess = targetProcess;
947        }
948    }
949
950    /**
951     * When service association tracking is enabled, this is all of the associations we
952     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
953     * -> association data.
954     */
955    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
956            mAssociations = new SparseArray<>();
957    boolean mTrackingAssociations;
958
959    /**
960     * Backup/restore process management
961     */
962    String mBackupAppName = null;
963    BackupRecord mBackupTarget = null;
964
965    final ProviderMap mProviderMap;
966
967    /**
968     * List of content providers who have clients waiting for them.  The
969     * application is currently being launched and the provider will be
970     * removed from this list once it is published.
971     */
972    final ArrayList<ContentProviderRecord> mLaunchingProviders
973            = new ArrayList<ContentProviderRecord>();
974
975    /**
976     * File storing persisted {@link #mGrantedUriPermissions}.
977     */
978    private final AtomicFile mGrantFile;
979
980    /** XML constants used in {@link #mGrantFile} */
981    private static final String TAG_URI_GRANTS = "uri-grants";
982    private static final String TAG_URI_GRANT = "uri-grant";
983    private static final String ATTR_USER_HANDLE = "userHandle";
984    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
985    private static final String ATTR_TARGET_USER_ID = "targetUserId";
986    private static final String ATTR_SOURCE_PKG = "sourcePkg";
987    private static final String ATTR_TARGET_PKG = "targetPkg";
988    private static final String ATTR_URI = "uri";
989    private static final String ATTR_MODE_FLAGS = "modeFlags";
990    private static final String ATTR_CREATED_TIME = "createdTime";
991    private static final String ATTR_PREFIX = "prefix";
992
993    /**
994     * Global set of specific {@link Uri} permissions that have been granted.
995     * This optimized lookup structure maps from {@link UriPermission#targetUid}
996     * to {@link UriPermission#uri} to {@link UriPermission}.
997     */
998    @GuardedBy("this")
999    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1000            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1001
1002    public static class GrantUri {
1003        public final int sourceUserId;
1004        public final Uri uri;
1005        public boolean prefix;
1006
1007        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1008            this.sourceUserId = sourceUserId;
1009            this.uri = uri;
1010            this.prefix = prefix;
1011        }
1012
1013        @Override
1014        public int hashCode() {
1015            int hashCode = 1;
1016            hashCode = 31 * hashCode + sourceUserId;
1017            hashCode = 31 * hashCode + uri.hashCode();
1018            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1019            return hashCode;
1020        }
1021
1022        @Override
1023        public boolean equals(Object o) {
1024            if (o instanceof GrantUri) {
1025                GrantUri other = (GrantUri) o;
1026                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1027                        && prefix == other.prefix;
1028            }
1029            return false;
1030        }
1031
1032        @Override
1033        public String toString() {
1034            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1035            if (prefix) result += " [prefix]";
1036            return result;
1037        }
1038
1039        public String toSafeString() {
1040            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1041            if (prefix) result += " [prefix]";
1042            return result;
1043        }
1044
1045        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1046            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1047                    ContentProvider.getUriWithoutUserId(uri), false);
1048        }
1049    }
1050
1051    CoreSettingsObserver mCoreSettingsObserver;
1052
1053    FontScaleSettingObserver mFontScaleSettingObserver;
1054
1055    private final class FontScaleSettingObserver extends ContentObserver {
1056        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1057
1058        public FontScaleSettingObserver() {
1059            super(mHandler);
1060            ContentResolver resolver = mContext.getContentResolver();
1061            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1062        }
1063
1064        @Override
1065        public void onChange(boolean selfChange, Uri uri) {
1066            if (mFontScaleUri.equals(uri)) {
1067                updateFontScaleIfNeeded();
1068            }
1069        }
1070    }
1071
1072    /**
1073     * Thread-local storage used to carry caller permissions over through
1074     * indirect content-provider access.
1075     */
1076    private class Identity {
1077        public final IBinder token;
1078        public final int pid;
1079        public final int uid;
1080
1081        Identity(IBinder _token, int _pid, int _uid) {
1082            token = _token;
1083            pid = _pid;
1084            uid = _uid;
1085        }
1086    }
1087
1088    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1089
1090    /**
1091     * All information we have collected about the runtime performance of
1092     * any user id that can impact battery performance.
1093     */
1094    final BatteryStatsService mBatteryStatsService;
1095
1096    /**
1097     * Information about component usage
1098     */
1099    UsageStatsManagerInternal mUsageStatsService;
1100
1101    /**
1102     * Access to DeviceIdleController service.
1103     */
1104    DeviceIdleController.LocalService mLocalDeviceIdleController;
1105
1106    /**
1107     * Information about and control over application operations
1108     */
1109    final AppOpsService mAppOpsService;
1110
1111    /**
1112     * Current configuration information.  HistoryRecord objects are given
1113     * a reference to this object to indicate which configuration they are
1114     * currently running in, so this object must be kept immutable.
1115     */
1116    Configuration mConfiguration = new Configuration();
1117
1118    /**
1119     * Current sequencing integer of the configuration, for skipping old
1120     * configurations.
1121     */
1122    int mConfigurationSeq = 0;
1123
1124    boolean mSuppressResizeConfigChanges = false;
1125
1126    /**
1127     * Hardware-reported OpenGLES version.
1128     */
1129    final int GL_ES_VERSION;
1130
1131    /**
1132     * List of initialization arguments to pass to all processes when binding applications to them.
1133     * For example, references to the commonly used services.
1134     */
1135    HashMap<String, IBinder> mAppBindArgs;
1136
1137    /**
1138     * Temporary to avoid allocations.  Protected by main lock.
1139     */
1140    final StringBuilder mStringBuilder = new StringBuilder(256);
1141
1142    /**
1143     * Used to control how we initialize the service.
1144     */
1145    ComponentName mTopComponent;
1146    String mTopAction = Intent.ACTION_MAIN;
1147    String mTopData;
1148
1149    volatile boolean mProcessesReady = false;
1150    volatile boolean mSystemReady = false;
1151    volatile boolean mOnBattery = false;
1152    volatile int mFactoryTest;
1153
1154    @GuardedBy("this") boolean mBooting = false;
1155    @GuardedBy("this") boolean mCallFinishBooting = false;
1156    @GuardedBy("this") boolean mBootAnimationComplete = false;
1157    @GuardedBy("this") boolean mLaunchWarningShown = false;
1158    @GuardedBy("this") boolean mCheckedForSetup = false;
1159
1160    Context mContext;
1161
1162    /**
1163     * The time at which we will allow normal application switches again,
1164     * after a call to {@link #stopAppSwitches()}.
1165     */
1166    long mAppSwitchesAllowedTime;
1167
1168    /**
1169     * This is set to true after the first switch after mAppSwitchesAllowedTime
1170     * is set; any switches after that will clear the time.
1171     */
1172    boolean mDidAppSwitch;
1173
1174    /**
1175     * Last time (in realtime) at which we checked for power usage.
1176     */
1177    long mLastPowerCheckRealtime;
1178
1179    /**
1180     * Last time (in uptime) at which we checked for power usage.
1181     */
1182    long mLastPowerCheckUptime;
1183
1184    /**
1185     * Set while we are wanting to sleep, to prevent any
1186     * activities from being started/resumed.
1187     */
1188    private boolean mSleeping = false;
1189
1190    /**
1191     * The process state used for processes that are running the top activities.
1192     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1193     */
1194    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1195
1196    /**
1197     * Set while we are running a voice interaction.  This overrides
1198     * sleeping while it is active.
1199     */
1200    private IVoiceInteractionSession mRunningVoice;
1201
1202    /**
1203     * For some direct access we need to power manager.
1204     */
1205    PowerManagerInternal mLocalPowerManager;
1206
1207    /**
1208     * We want to hold a wake lock while running a voice interaction session, since
1209     * this may happen with the screen off and we need to keep the CPU running to
1210     * be able to continue to interact with the user.
1211     */
1212    PowerManager.WakeLock mVoiceWakeLock;
1213
1214    /**
1215     * State of external calls telling us if the device is awake or asleep.
1216     */
1217    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1218
1219    /**
1220     * A list of tokens that cause the top activity to be put to sleep.
1221     * They are used by components that may hide and block interaction with underlying
1222     * activities.
1223     */
1224    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1225
1226    static final int LOCK_SCREEN_HIDDEN = 0;
1227    static final int LOCK_SCREEN_LEAVING = 1;
1228    static final int LOCK_SCREEN_SHOWN = 2;
1229    /**
1230     * State of external call telling us if the lock screen is shown.
1231     */
1232    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1233
1234    /**
1235     * Set if we are shutting down the system, similar to sleeping.
1236     */
1237    boolean mShuttingDown = false;
1238
1239    /**
1240     * Current sequence id for oom_adj computation traversal.
1241     */
1242    int mAdjSeq = 0;
1243
1244    /**
1245     * Current sequence id for process LRU updating.
1246     */
1247    int mLruSeq = 0;
1248
1249    /**
1250     * Keep track of the non-cached/empty process we last found, to help
1251     * determine how to distribute cached/empty processes next time.
1252     */
1253    int mNumNonCachedProcs = 0;
1254
1255    /**
1256     * Keep track of the number of cached hidden procs, to balance oom adj
1257     * distribution between those and empty procs.
1258     */
1259    int mNumCachedHiddenProcs = 0;
1260
1261    /**
1262     * Keep track of the number of service processes we last found, to
1263     * determine on the next iteration which should be B services.
1264     */
1265    int mNumServiceProcs = 0;
1266    int mNewNumAServiceProcs = 0;
1267    int mNewNumServiceProcs = 0;
1268
1269    /**
1270     * Allow the current computed overall memory level of the system to go down?
1271     * This is set to false when we are killing processes for reasons other than
1272     * memory management, so that the now smaller process list will not be taken as
1273     * an indication that memory is tighter.
1274     */
1275    boolean mAllowLowerMemLevel = false;
1276
1277    /**
1278     * The last computed memory level, for holding when we are in a state that
1279     * processes are going away for other reasons.
1280     */
1281    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1282
1283    /**
1284     * The last total number of process we have, to determine if changes actually look
1285     * like a shrinking number of process due to lower RAM.
1286     */
1287    int mLastNumProcesses;
1288
1289    /**
1290     * The uptime of the last time we performed idle maintenance.
1291     */
1292    long mLastIdleTime = SystemClock.uptimeMillis();
1293
1294    /**
1295     * Total time spent with RAM that has been added in the past since the last idle time.
1296     */
1297    long mLowRamTimeSinceLastIdle = 0;
1298
1299    /**
1300     * If RAM is currently low, when that horrible situation started.
1301     */
1302    long mLowRamStartTime = 0;
1303
1304    /**
1305     * For reporting to battery stats the current top application.
1306     */
1307    private String mCurResumedPackage = null;
1308    private int mCurResumedUid = -1;
1309
1310    /**
1311     * For reporting to battery stats the apps currently running foreground
1312     * service.  The ProcessMap is package/uid tuples; each of these contain
1313     * an array of the currently foreground processes.
1314     */
1315    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1316            = new ProcessMap<ArrayList<ProcessRecord>>();
1317
1318    /**
1319     * This is set if we had to do a delayed dexopt of an app before launching
1320     * it, to increase the ANR timeouts in that case.
1321     */
1322    boolean mDidDexOpt;
1323
1324    /**
1325     * Set if the systemServer made a call to enterSafeMode.
1326     */
1327    boolean mSafeMode;
1328
1329    /**
1330     * If true, we are running under a test environment so will sample PSS from processes
1331     * much more rapidly to try to collect better data when the tests are rapidly
1332     * running through apps.
1333     */
1334    boolean mTestPssMode = false;
1335
1336    String mDebugApp = null;
1337    boolean mWaitForDebugger = false;
1338    boolean mDebugTransient = false;
1339    String mOrigDebugApp = null;
1340    boolean mOrigWaitForDebugger = false;
1341    boolean mAlwaysFinishActivities = false;
1342    boolean mLenientBackgroundCheck = false;
1343    boolean mForceResizableActivities;
1344    boolean mSupportsMultiWindow;
1345    boolean mSupportsFreeformWindowManagement;
1346    boolean mSupportsPictureInPicture;
1347    Rect mDefaultPinnedStackBounds;
1348    IActivityController mController = null;
1349    boolean mControllerIsAMonkey = false;
1350    String mProfileApp = null;
1351    ProcessRecord mProfileProc = null;
1352    String mProfileFile;
1353    ParcelFileDescriptor mProfileFd;
1354    int mSamplingInterval = 0;
1355    boolean mAutoStopProfiler = false;
1356    int mProfileType = 0;
1357    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1358    String mMemWatchDumpProcName;
1359    String mMemWatchDumpFile;
1360    int mMemWatchDumpPid;
1361    int mMemWatchDumpUid;
1362    String mTrackAllocationApp = null;
1363    String mNativeDebuggingApp = null;
1364
1365    final long[] mTmpLong = new long[2];
1366
1367    static final class ProcessChangeItem {
1368        static final int CHANGE_ACTIVITIES = 1<<0;
1369        static final int CHANGE_PROCESS_STATE = 1<<1;
1370        int changes;
1371        int uid;
1372        int pid;
1373        int processState;
1374        boolean foregroundActivities;
1375    }
1376
1377    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1378    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1379
1380    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1381    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1382
1383    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1384    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1385
1386    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1387    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1388
1389    /**
1390     * Runtime CPU use collection thread.  This object's lock is used to
1391     * perform synchronization with the thread (notifying it to run).
1392     */
1393    final Thread mProcessCpuThread;
1394
1395    /**
1396     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1397     * Must acquire this object's lock when accessing it.
1398     * NOTE: this lock will be held while doing long operations (trawling
1399     * through all processes in /proc), so it should never be acquired by
1400     * any critical paths such as when holding the main activity manager lock.
1401     */
1402    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1403            MONITOR_THREAD_CPU_USAGE);
1404    final AtomicLong mLastCpuTime = new AtomicLong(0);
1405    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1406
1407    long mLastWriteTime = 0;
1408
1409    /**
1410     * Used to retain an update lock when the foreground activity is in
1411     * immersive mode.
1412     */
1413    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1414
1415    /**
1416     * Set to true after the system has finished booting.
1417     */
1418    boolean mBooted = false;
1419
1420    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1421    int mProcessLimitOverride = -1;
1422
1423    WindowManagerService mWindowManager;
1424    final ActivityThread mSystemThread;
1425
1426    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1427        final ProcessRecord mApp;
1428        final int mPid;
1429        final IApplicationThread mAppThread;
1430
1431        AppDeathRecipient(ProcessRecord app, int pid,
1432                IApplicationThread thread) {
1433            if (DEBUG_ALL) Slog.v(
1434                TAG, "New death recipient " + this
1435                + " for thread " + thread.asBinder());
1436            mApp = app;
1437            mPid = pid;
1438            mAppThread = thread;
1439        }
1440
1441        @Override
1442        public void binderDied() {
1443            if (DEBUG_ALL) Slog.v(
1444                TAG, "Death received in " + this
1445                + " for thread " + mAppThread.asBinder());
1446            synchronized(ActivityManagerService.this) {
1447                appDiedLocked(mApp, mPid, mAppThread, true);
1448            }
1449        }
1450    }
1451
1452    static final int SHOW_ERROR_UI_MSG = 1;
1453    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1454    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1455    static final int UPDATE_CONFIGURATION_MSG = 4;
1456    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1457    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1458    static final int SERVICE_TIMEOUT_MSG = 12;
1459    static final int UPDATE_TIME_ZONE = 13;
1460    static final int SHOW_UID_ERROR_UI_MSG = 14;
1461    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1462    static final int PROC_START_TIMEOUT_MSG = 20;
1463    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1464    static final int KILL_APPLICATION_MSG = 22;
1465    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1466    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1467    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1468    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1469    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1470    static final int CLEAR_DNS_CACHE_MSG = 28;
1471    static final int UPDATE_HTTP_PROXY_MSG = 29;
1472    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1473    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1474    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1475    static final int REPORT_MEM_USAGE_MSG = 33;
1476    static final int REPORT_USER_SWITCH_MSG = 34;
1477    static final int CONTINUE_USER_SWITCH_MSG = 35;
1478    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1479    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1480    static final int PERSIST_URI_GRANTS_MSG = 38;
1481    static final int REQUEST_ALL_PSS_MSG = 39;
1482    static final int START_PROFILES_MSG = 40;
1483    static final int UPDATE_TIME = 41;
1484    static final int SYSTEM_USER_START_MSG = 42;
1485    static final int SYSTEM_USER_CURRENT_MSG = 43;
1486    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1487    static final int FINISH_BOOTING_MSG = 45;
1488    static final int START_USER_SWITCH_UI_MSG = 46;
1489    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1490    static final int DISMISS_DIALOG_UI_MSG = 48;
1491    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1492    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1493    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1494    static final int DELETE_DUMPHEAP_MSG = 52;
1495    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1496    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1497    static final int REPORT_TIME_TRACKER_MSG = 55;
1498    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1499    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1500    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1501    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1502    static final int IDLE_UIDS_MSG = 60;
1503    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1504    static final int LOG_STACK_STATE = 62;
1505    static final int VR_MODE_CHANGE_MSG = 63;
1506    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1507    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1508    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1509    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1510    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1511    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1512
1513    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1514    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1515    static final int FIRST_COMPAT_MODE_MSG = 300;
1516    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1517
1518    static ServiceThread sKillThread = null;
1519    static KillHandler sKillHandler = null;
1520
1521    CompatModeDialog mCompatModeDialog;
1522    long mLastMemUsageReportTime = 0;
1523
1524    /**
1525     * Flag whether the current user is a "monkey", i.e. whether
1526     * the UI is driven by a UI automation tool.
1527     */
1528    private boolean mUserIsMonkey;
1529
1530    /** Flag whether the device has a Recents UI */
1531    boolean mHasRecents;
1532
1533    /** The dimensions of the thumbnails in the Recents UI. */
1534    int mThumbnailWidth;
1535    int mThumbnailHeight;
1536    float mFullscreenThumbnailScale;
1537
1538    final ServiceThread mHandlerThread;
1539    final MainHandler mHandler;
1540    final UiHandler mUiHandler;
1541
1542    PackageManagerInternal mPackageManagerInt;
1543
1544    // VoiceInteraction session ID that changes for each new request except when
1545    // being called for multiwindow assist in a single session.
1546    private int mViSessionId = 1000;
1547
1548    final class KillHandler extends Handler {
1549        static final int KILL_PROCESS_GROUP_MSG = 4000;
1550
1551        public KillHandler(Looper looper) {
1552            super(looper, null, true);
1553        }
1554
1555        @Override
1556        public void handleMessage(Message msg) {
1557            switch (msg.what) {
1558                case KILL_PROCESS_GROUP_MSG:
1559                {
1560                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1561                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1562                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1563                }
1564                break;
1565
1566                default:
1567                    super.handleMessage(msg);
1568            }
1569        }
1570    }
1571
1572    final class UiHandler extends Handler {
1573        public UiHandler() {
1574            super(com.android.server.UiThread.get().getLooper(), null, true);
1575        }
1576
1577        @Override
1578        public void handleMessage(Message msg) {
1579            switch (msg.what) {
1580            case SHOW_ERROR_UI_MSG: {
1581                mAppErrors.handleShowAppErrorUi(msg);
1582                ensureBootCompleted();
1583            } break;
1584            case SHOW_NOT_RESPONDING_UI_MSG: {
1585                mAppErrors.handleShowAnrUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1589                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1590                synchronized (ActivityManagerService.this) {
1591                    ProcessRecord proc = (ProcessRecord) data.get("app");
1592                    if (proc == null) {
1593                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1594                        break;
1595                    }
1596                    if (proc.crashDialog != null) {
1597                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1598                        return;
1599                    }
1600                    AppErrorResult res = (AppErrorResult) data.get("result");
1601                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1602                        Dialog d = new StrictModeViolationDialog(mContext,
1603                                ActivityManagerService.this, res, proc);
1604                        d.show();
1605                        proc.crashDialog = d;
1606                    } else {
1607                        // The device is asleep, so just pretend that the user
1608                        // saw a crash dialog and hit "force quit".
1609                        res.set(0);
1610                    }
1611                }
1612                ensureBootCompleted();
1613            } break;
1614            case SHOW_FACTORY_ERROR_UI_MSG: {
1615                Dialog d = new FactoryErrorDialog(
1616                    mContext, msg.getData().getCharSequence("msg"));
1617                d.show();
1618                ensureBootCompleted();
1619            } break;
1620            case WAIT_FOR_DEBUGGER_UI_MSG: {
1621                synchronized (ActivityManagerService.this) {
1622                    ProcessRecord app = (ProcessRecord)msg.obj;
1623                    if (msg.arg1 != 0) {
1624                        if (!app.waitedForDebugger) {
1625                            Dialog d = new AppWaitingForDebuggerDialog(
1626                                    ActivityManagerService.this,
1627                                    mContext, app);
1628                            app.waitDialog = d;
1629                            app.waitedForDebugger = true;
1630                            d.show();
1631                        }
1632                    } else {
1633                        if (app.waitDialog != null) {
1634                            app.waitDialog.dismiss();
1635                            app.waitDialog = null;
1636                        }
1637                    }
1638                }
1639            } break;
1640            case SHOW_UID_ERROR_UI_MSG: {
1641                if (mShowDialogs) {
1642                    AlertDialog d = new BaseErrorDialog(mContext);
1643                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1644                    d.setCancelable(false);
1645                    d.setTitle(mContext.getText(R.string.android_system_label));
1646                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1647                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1648                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1649                    d.show();
1650                }
1651            } break;
1652            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1653                if (mShowDialogs) {
1654                    AlertDialog d = new BaseErrorDialog(mContext);
1655                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1656                    d.setCancelable(false);
1657                    d.setTitle(mContext.getText(R.string.android_system_label));
1658                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1659                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1660                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1661                    d.show();
1662                }
1663            } break;
1664            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1665                synchronized (ActivityManagerService.this) {
1666                    ActivityRecord ar = (ActivityRecord) msg.obj;
1667                    if (mCompatModeDialog != null) {
1668                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1669                                ar.info.applicationInfo.packageName)) {
1670                            return;
1671                        }
1672                        mCompatModeDialog.dismiss();
1673                        mCompatModeDialog = null;
1674                    }
1675                    if (ar != null && false) {
1676                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1677                                ar.packageName)) {
1678                            int mode = mCompatModePackages.computeCompatModeLocked(
1679                                    ar.info.applicationInfo);
1680                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1681                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1682                                mCompatModeDialog = new CompatModeDialog(
1683                                        ActivityManagerService.this, mContext,
1684                                        ar.info.applicationInfo);
1685                                mCompatModeDialog.show();
1686                            }
1687                        }
1688                    }
1689                }
1690                break;
1691            }
1692            case START_USER_SWITCH_UI_MSG: {
1693                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1694                break;
1695            }
1696            case DISMISS_DIALOG_UI_MSG: {
1697                final Dialog d = (Dialog) msg.obj;
1698                d.dismiss();
1699                break;
1700            }
1701            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1702                dispatchProcessesChanged();
1703                break;
1704            }
1705            case DISPATCH_PROCESS_DIED_UI_MSG: {
1706                final int pid = msg.arg1;
1707                final int uid = msg.arg2;
1708                dispatchProcessDied(pid, uid);
1709                break;
1710            }
1711            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1712                dispatchUidsChanged();
1713            } break;
1714            }
1715        }
1716    }
1717
1718    final class MainHandler extends Handler {
1719        public MainHandler(Looper looper) {
1720            super(looper, null, true);
1721        }
1722
1723        @Override
1724        public void handleMessage(Message msg) {
1725            switch (msg.what) {
1726            case UPDATE_CONFIGURATION_MSG: {
1727                final ContentResolver resolver = mContext.getContentResolver();
1728                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1729                        msg.arg1);
1730            } break;
1731            case GC_BACKGROUND_PROCESSES_MSG: {
1732                synchronized (ActivityManagerService.this) {
1733                    performAppGcsIfAppropriateLocked();
1734                }
1735            } break;
1736            case SERVICE_TIMEOUT_MSG: {
1737                if (mDidDexOpt) {
1738                    mDidDexOpt = false;
1739                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1740                    nmsg.obj = msg.obj;
1741                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1742                    return;
1743                }
1744                mServices.serviceTimeout((ProcessRecord)msg.obj);
1745            } break;
1746            case UPDATE_TIME_ZONE: {
1747                synchronized (ActivityManagerService.this) {
1748                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1749                        ProcessRecord r = mLruProcesses.get(i);
1750                        if (r.thread != null) {
1751                            try {
1752                                r.thread.updateTimeZone();
1753                            } catch (RemoteException ex) {
1754                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1755                            }
1756                        }
1757                    }
1758                }
1759            } break;
1760            case CLEAR_DNS_CACHE_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1763                        ProcessRecord r = mLruProcesses.get(i);
1764                        if (r.thread != null) {
1765                            try {
1766                                r.thread.clearDnsCache();
1767                            } catch (RemoteException ex) {
1768                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1769                            }
1770                        }
1771                    }
1772                }
1773            } break;
1774            case UPDATE_HTTP_PROXY_MSG: {
1775                ProxyInfo proxy = (ProxyInfo)msg.obj;
1776                String host = "";
1777                String port = "";
1778                String exclList = "";
1779                Uri pacFileUrl = Uri.EMPTY;
1780                if (proxy != null) {
1781                    host = proxy.getHost();
1782                    port = Integer.toString(proxy.getPort());
1783                    exclList = proxy.getExclusionListAsString();
1784                    pacFileUrl = proxy.getPacFileUrl();
1785                }
1786                synchronized (ActivityManagerService.this) {
1787                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1788                        ProcessRecord r = mLruProcesses.get(i);
1789                        if (r.thread != null) {
1790                            try {
1791                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1792                            } catch (RemoteException ex) {
1793                                Slog.w(TAG, "Failed to update http proxy for: " +
1794                                        r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799            } break;
1800            case PROC_START_TIMEOUT_MSG: {
1801                if (mDidDexOpt) {
1802                    mDidDexOpt = false;
1803                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1804                    nmsg.obj = msg.obj;
1805                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1806                    return;
1807                }
1808                ProcessRecord app = (ProcessRecord)msg.obj;
1809                synchronized (ActivityManagerService.this) {
1810                    processStartTimedOutLocked(app);
1811                }
1812            } break;
1813            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1814                ProcessRecord app = (ProcessRecord)msg.obj;
1815                synchronized (ActivityManagerService.this) {
1816                    processContentProviderPublishTimedOutLocked(app);
1817                }
1818            } break;
1819            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1822                }
1823            } break;
1824            case KILL_APPLICATION_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    int appid = msg.arg1;
1827                    boolean restart = (msg.arg2 == 1);
1828                    Bundle bundle = (Bundle)msg.obj;
1829                    String pkg = bundle.getString("pkg");
1830                    String reason = bundle.getString("reason");
1831                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1832                            false, UserHandle.USER_ALL, reason);
1833                }
1834            } break;
1835            case FINALIZE_PENDING_INTENT_MSG: {
1836                ((PendingIntentRecord)msg.obj).completeFinalize();
1837            } break;
1838            case POST_HEAVY_NOTIFICATION_MSG: {
1839                INotificationManager inm = NotificationManager.getService();
1840                if (inm == null) {
1841                    return;
1842                }
1843
1844                ActivityRecord root = (ActivityRecord)msg.obj;
1845                ProcessRecord process = root.app;
1846                if (process == null) {
1847                    return;
1848                }
1849
1850                try {
1851                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1852                    String text = mContext.getString(R.string.heavy_weight_notification,
1853                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1854                    Notification notification = new Notification.Builder(context)
1855                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1856                            .setWhen(0)
1857                            .setOngoing(true)
1858                            .setTicker(text)
1859                            .setColor(mContext.getColor(
1860                                    com.android.internal.R.color.system_notification_accent_color))
1861                            .setContentTitle(text)
1862                            .setContentText(
1863                                    mContext.getText(R.string.heavy_weight_notification_detail))
1864                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1865                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1866                                    new UserHandle(root.userId)))
1867                            .build();
1868                    try {
1869                        int[] outId = new int[1];
1870                        inm.enqueueNotificationWithTag("android", "android", null,
1871                                R.string.heavy_weight_notification,
1872                                notification, outId, root.userId);
1873                    } catch (RuntimeException e) {
1874                        Slog.w(ActivityManagerService.TAG,
1875                                "Error showing notification for heavy-weight app", e);
1876                    } catch (RemoteException e) {
1877                    }
1878                } catch (NameNotFoundException e) {
1879                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1880                }
1881            } break;
1882            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1883                INotificationManager inm = NotificationManager.getService();
1884                if (inm == null) {
1885                    return;
1886                }
1887                try {
1888                    inm.cancelNotificationWithTag("android", null,
1889                            R.string.heavy_weight_notification,  msg.arg1);
1890                } catch (RuntimeException e) {
1891                    Slog.w(ActivityManagerService.TAG,
1892                            "Error canceling notification for service", e);
1893                } catch (RemoteException e) {
1894                }
1895            } break;
1896            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1897                synchronized (ActivityManagerService.this) {
1898                    checkExcessivePowerUsageLocked(true);
1899                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1900                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1902                }
1903            } break;
1904            case REPORT_MEM_USAGE_MSG: {
1905                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1906                Thread thread = new Thread() {
1907                    @Override public void run() {
1908                        reportMemUsage(memInfos);
1909                    }
1910                };
1911                thread.start();
1912                break;
1913            }
1914            case REPORT_USER_SWITCH_MSG: {
1915                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1916                break;
1917            }
1918            case CONTINUE_USER_SWITCH_MSG: {
1919                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case USER_SWITCH_TIMEOUT_MSG: {
1923                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case IMMERSIVE_MODE_LOCK_MSG: {
1927                final boolean nextState = (msg.arg1 != 0);
1928                if (mUpdateLock.isHeld() != nextState) {
1929                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1930                            "Applying new update lock state '" + nextState
1931                            + "' for " + (ActivityRecord)msg.obj);
1932                    if (nextState) {
1933                        mUpdateLock.acquire();
1934                    } else {
1935                        mUpdateLock.release();
1936                    }
1937                }
1938                break;
1939            }
1940            case PERSIST_URI_GRANTS_MSG: {
1941                writeGrantedUriPermissions();
1942                break;
1943            }
1944            case REQUEST_ALL_PSS_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1947                }
1948                break;
1949            }
1950            case START_PROFILES_MSG: {
1951                synchronized (ActivityManagerService.this) {
1952                    mUserController.startProfilesLocked();
1953                }
1954                break;
1955            }
1956            case UPDATE_TIME: {
1957                synchronized (ActivityManagerService.this) {
1958                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1959                        ProcessRecord r = mLruProcesses.get(i);
1960                        if (r.thread != null) {
1961                            try {
1962                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1963                            } catch (RemoteException ex) {
1964                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1965                            }
1966                        }
1967                    }
1968                }
1969                break;
1970            }
1971            case SYSTEM_USER_START_MSG: {
1972                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1973                        Integer.toString(msg.arg1), msg.arg1);
1974                mSystemServiceManager.startUser(msg.arg1);
1975                break;
1976            }
1977            case SYSTEM_USER_UNLOCK_MSG: {
1978                final int userId = msg.arg1;
1979                mSystemServiceManager.unlockUser(userId);
1980                synchronized (ActivityManagerService.this) {
1981                    mRecentTasks.loadUserRecentsLocked(userId);
1982                }
1983                if (userId == UserHandle.USER_SYSTEM) {
1984                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1985                }
1986                installEncryptionUnawareProviders(userId);
1987                mUserController.finishUserUnlocked((UserState) msg.obj);
1988                break;
1989            }
1990            case SYSTEM_USER_CURRENT_MSG: {
1991                mBatteryStatsService.noteEvent(
1992                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1993                        Integer.toString(msg.arg2), msg.arg2);
1994                mBatteryStatsService.noteEvent(
1995                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1996                        Integer.toString(msg.arg1), msg.arg1);
1997                mSystemServiceManager.switchUser(msg.arg1);
1998                break;
1999            }
2000            case ENTER_ANIMATION_COMPLETE_MSG: {
2001                synchronized (ActivityManagerService.this) {
2002                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2003                    if (r != null && r.app != null && r.app.thread != null) {
2004                        try {
2005                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2006                        } catch (RemoteException e) {
2007                        }
2008                    }
2009                }
2010                break;
2011            }
2012            case FINISH_BOOTING_MSG: {
2013                if (msg.arg1 != 0) {
2014                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2015                    finishBooting();
2016                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2017                }
2018                if (msg.arg2 != 0) {
2019                    enableScreenAfterBoot();
2020                }
2021                break;
2022            }
2023            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2024                try {
2025                    Locale l = (Locale) msg.obj;
2026                    IBinder service = ServiceManager.getService("mount");
2027                    IMountService mountService = IMountService.Stub.asInterface(service);
2028                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2029                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2030                } catch (RemoteException e) {
2031                    Log.e(TAG, "Error storing locale for decryption UI", e);
2032                }
2033                break;
2034            }
2035            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                        try {
2067                            // Make a one-way callback to the listener
2068                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2069                        } catch (RemoteException e){
2070                            // Handled by the RemoteCallbackList
2071                        }
2072                    }
2073                    mTaskStackListeners.finishBroadcast();
2074                }
2075                break;
2076            }
2077            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2078                synchronized (ActivityManagerService.this) {
2079                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2080                        try {
2081                            // Make a one-way callback to the listener
2082                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2083                        } catch (RemoteException e){
2084                            // Handled by the RemoteCallbackList
2085                        }
2086                    }
2087                    mTaskStackListeners.finishBroadcast();
2088                }
2089                break;
2090            }
2091            case NOTIFY_FORCED_RESIZABLE_MSG: {
2092                synchronized (ActivityManagerService.this) {
2093                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2094                        try {
2095                            // Make a one-way callback to the listener
2096                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2097                                    (String) msg.obj, msg.arg1);
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2107                    synchronized (ActivityManagerService.this) {
2108                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                            try {
2110                                // Make a one-way callback to the listener
2111                                mTaskStackListeners.getBroadcastItem(i)
2112                                        .onActivityDismissingDockedStack();
2113                            } catch (RemoteException e){
2114                                // Handled by the RemoteCallbackList
2115                            }
2116                        }
2117                        mTaskStackListeners.finishBroadcast();
2118                    }
2119                    break;
2120                }
2121            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2122                final int uid = msg.arg1;
2123                final byte[] firstPacket = (byte[]) msg.obj;
2124
2125                synchronized (mPidsSelfLocked) {
2126                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2127                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2128                        if (p.uid == uid) {
2129                            try {
2130                                p.thread.notifyCleartextNetwork(firstPacket);
2131                            } catch (RemoteException ignored) {
2132                            }
2133                        }
2134                    }
2135                }
2136                break;
2137            }
2138            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2139                final String procName;
2140                final int uid;
2141                final long memLimit;
2142                final String reportPackage;
2143                synchronized (ActivityManagerService.this) {
2144                    procName = mMemWatchDumpProcName;
2145                    uid = mMemWatchDumpUid;
2146                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2147                    if (val == null) {
2148                        val = mMemWatchProcesses.get(procName, 0);
2149                    }
2150                    if (val != null) {
2151                        memLimit = val.first;
2152                        reportPackage = val.second;
2153                    } else {
2154                        memLimit = 0;
2155                        reportPackage = null;
2156                    }
2157                }
2158                if (procName == null) {
2159                    return;
2160                }
2161
2162                if (DEBUG_PSS) Slog.d(TAG_PSS,
2163                        "Showing dump heap notification from " + procName + "/" + uid);
2164
2165                INotificationManager inm = NotificationManager.getService();
2166                if (inm == null) {
2167                    return;
2168                }
2169
2170                String text = mContext.getString(R.string.dump_heap_notification, procName);
2171
2172
2173                Intent deleteIntent = new Intent();
2174                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2175                Intent intent = new Intent();
2176                intent.setClassName("android", DumpHeapActivity.class.getName());
2177                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2178                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2179                if (reportPackage != null) {
2180                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2181                }
2182                int userId = UserHandle.getUserId(uid);
2183                Notification notification = new Notification.Builder(mContext)
2184                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2185                        .setWhen(0)
2186                        .setOngoing(true)
2187                        .setAutoCancel(true)
2188                        .setTicker(text)
2189                        .setColor(mContext.getColor(
2190                                com.android.internal.R.color.system_notification_accent_color))
2191                        .setContentTitle(text)
2192                        .setContentText(
2193                                mContext.getText(R.string.dump_heap_notification_detail))
2194                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2195                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2196                                new UserHandle(userId)))
2197                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2198                                deleteIntent, 0, UserHandle.SYSTEM))
2199                        .build();
2200
2201                try {
2202                    int[] outId = new int[1];
2203                    inm.enqueueNotificationWithTag("android", "android", null,
2204                            R.string.dump_heap_notification,
2205                            notification, outId, userId);
2206                } catch (RuntimeException e) {
2207                    Slog.w(ActivityManagerService.TAG,
2208                            "Error showing notification for dump heap", e);
2209                } catch (RemoteException e) {
2210                }
2211            } break;
2212            case DELETE_DUMPHEAP_MSG: {
2213                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2214                        DumpHeapActivity.JAVA_URI,
2215                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2216                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2217                        UserHandle.myUserId());
2218                synchronized (ActivityManagerService.this) {
2219                    mMemWatchDumpFile = null;
2220                    mMemWatchDumpProcName = null;
2221                    mMemWatchDumpPid = -1;
2222                    mMemWatchDumpUid = -1;
2223                }
2224            } break;
2225            case FOREGROUND_PROFILE_CHANGED_MSG: {
2226                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2227            } break;
2228            case REPORT_TIME_TRACKER_MSG: {
2229                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2230                tracker.deliverResult(mContext);
2231            } break;
2232            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2233                mUserController.dispatchUserSwitchComplete(msg.arg1);
2234            } break;
2235            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2236                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2237                try {
2238                    connection.shutdown();
2239                } catch (RemoteException e) {
2240                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2241                }
2242                // Only a UiAutomation can set this flag and now that
2243                // it is finished we make sure it is reset to its default.
2244                mUserIsMonkey = false;
2245            } break;
2246            case APP_BOOST_DEACTIVATE_MSG: {
2247                synchronized(ActivityManagerService.this) {
2248                    if (mIsBoosted) {
2249                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2250                            nativeMigrateFromBoost();
2251                            mIsBoosted = false;
2252                            mBoostStartTime = 0;
2253                        } else {
2254                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2255                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2256                        }
2257                    }
2258                }
2259            } break;
2260            case IDLE_UIDS_MSG: {
2261                idleUids();
2262            } break;
2263            case LOG_STACK_STATE: {
2264                synchronized (ActivityManagerService.this) {
2265                    mStackSupervisor.logStackState();
2266                }
2267            } break;
2268            case VR_MODE_CHANGE_MSG: {
2269                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2270                final ActivityRecord r = (ActivityRecord) msg.obj;
2271                boolean vrMode;
2272                ComponentName requestedPackage;
2273                ComponentName callingPackage;
2274                int userId;
2275                synchronized (ActivityManagerService.this) {
2276                    vrMode = r.requestedVrComponent != null;
2277                    requestedPackage = r.requestedVrComponent;
2278                    userId = r.userId;
2279                    callingPackage = r.info.getComponentName();
2280                    if (mInVrMode != vrMode) {
2281                        mInVrMode = vrMode;
2282                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2283                    }
2284                }
2285                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2286            } break;
2287            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2288                final ActivityRecord r = (ActivityRecord) msg.obj;
2289                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2290                if (needsVrMode) {
2291                    VrManagerInternal vrService =
2292                            LocalServices.getService(VrManagerInternal.class);
2293                    boolean enable = msg.arg1 == 1;
2294                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2295                            r.info.getComponentName());
2296                }
2297            } break;
2298            }
2299        }
2300    };
2301
2302    static final int COLLECT_PSS_BG_MSG = 1;
2303
2304    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2305        @Override
2306        public void handleMessage(Message msg) {
2307            switch (msg.what) {
2308            case COLLECT_PSS_BG_MSG: {
2309                long start = SystemClock.uptimeMillis();
2310                MemInfoReader memInfo = null;
2311                synchronized (ActivityManagerService.this) {
2312                    if (mFullPssPending) {
2313                        mFullPssPending = false;
2314                        memInfo = new MemInfoReader();
2315                    }
2316                }
2317                if (memInfo != null) {
2318                    updateCpuStatsNow();
2319                    long nativeTotalPss = 0;
2320                    synchronized (mProcessCpuTracker) {
2321                        final int N = mProcessCpuTracker.countStats();
2322                        for (int j=0; j<N; j++) {
2323                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2324                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2325                                // This is definitely an application process; skip it.
2326                                continue;
2327                            }
2328                            synchronized (mPidsSelfLocked) {
2329                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2330                                    // This is one of our own processes; skip it.
2331                                    continue;
2332                                }
2333                            }
2334                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2335                        }
2336                    }
2337                    memInfo.readMemInfo();
2338                    synchronized (ActivityManagerService.this) {
2339                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2340                                + (SystemClock.uptimeMillis()-start) + "ms");
2341                        final long cachedKb = memInfo.getCachedSizeKb();
2342                        final long freeKb = memInfo.getFreeSizeKb();
2343                        final long zramKb = memInfo.getZramTotalSizeKb();
2344                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2345                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2346                                kernelKb*1024, nativeTotalPss*1024);
2347                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2348                                nativeTotalPss);
2349                    }
2350                }
2351
2352                int num = 0;
2353                long[] tmp = new long[2];
2354                do {
2355                    ProcessRecord proc;
2356                    int procState;
2357                    int pid;
2358                    long lastPssTime;
2359                    synchronized (ActivityManagerService.this) {
2360                        if (mPendingPssProcesses.size() <= 0) {
2361                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2362                                    "Collected PSS of " + num + " processes in "
2363                                    + (SystemClock.uptimeMillis() - start) + "ms");
2364                            mPendingPssProcesses.clear();
2365                            return;
2366                        }
2367                        proc = mPendingPssProcesses.remove(0);
2368                        procState = proc.pssProcState;
2369                        lastPssTime = proc.lastPssTime;
2370                        if (proc.thread != null && procState == proc.setProcState
2371                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2372                                        < SystemClock.uptimeMillis()) {
2373                            pid = proc.pid;
2374                        } else {
2375                            proc = null;
2376                            pid = 0;
2377                        }
2378                    }
2379                    if (proc != null) {
2380                        long pss = Debug.getPss(pid, tmp, null);
2381                        synchronized (ActivityManagerService.this) {
2382                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2383                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2384                                num++;
2385                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2386                                        SystemClock.uptimeMillis());
2387                            }
2388                        }
2389                    }
2390                } while (true);
2391            }
2392            }
2393        }
2394    };
2395
2396    public void setSystemProcess() {
2397        try {
2398            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2399            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2400            ServiceManager.addService("meminfo", new MemBinder(this));
2401            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2402            ServiceManager.addService("dbinfo", new DbBinder(this));
2403            if (MONITOR_CPU_USAGE) {
2404                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2405            }
2406            ServiceManager.addService("permission", new PermissionController(this));
2407            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2408
2409            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2410                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2411            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2412
2413            synchronized (this) {
2414                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2415                app.persistent = true;
2416                app.pid = MY_PID;
2417                app.maxAdj = ProcessList.SYSTEM_ADJ;
2418                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2419                synchronized (mPidsSelfLocked) {
2420                    mPidsSelfLocked.put(app.pid, app);
2421                }
2422                updateLruProcessLocked(app, false, null);
2423                updateOomAdjLocked();
2424            }
2425        } catch (PackageManager.NameNotFoundException e) {
2426            throw new RuntimeException(
2427                    "Unable to find android system package", e);
2428        }
2429    }
2430
2431    public void setWindowManager(WindowManagerService wm) {
2432        mWindowManager = wm;
2433        mStackSupervisor.setWindowManager(wm);
2434        mActivityStarter.setWindowManager(wm);
2435    }
2436
2437    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2438        mUsageStatsService = usageStatsManager;
2439    }
2440
2441    public void startObservingNativeCrashes() {
2442        final NativeCrashListener ncl = new NativeCrashListener(this);
2443        ncl.start();
2444    }
2445
2446    public IAppOpsService getAppOpsService() {
2447        return mAppOpsService;
2448    }
2449
2450    static class MemBinder extends Binder {
2451        ActivityManagerService mActivityManagerService;
2452        MemBinder(ActivityManagerService activityManagerService) {
2453            mActivityManagerService = activityManagerService;
2454        }
2455
2456        @Override
2457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2459                    != PackageManager.PERMISSION_GRANTED) {
2460                pw.println("Permission Denial: can't dump meminfo from from pid="
2461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2462                        + " without permission " + android.Manifest.permission.DUMP);
2463                return;
2464            }
2465
2466            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2467        }
2468    }
2469
2470    static class GraphicsBinder extends Binder {
2471        ActivityManagerService mActivityManagerService;
2472        GraphicsBinder(ActivityManagerService activityManagerService) {
2473            mActivityManagerService = activityManagerService;
2474        }
2475
2476        @Override
2477        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2478            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2479                    != PackageManager.PERMISSION_GRANTED) {
2480                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2481                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2482                        + " without permission " + android.Manifest.permission.DUMP);
2483                return;
2484            }
2485
2486            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2487        }
2488    }
2489
2490    static class DbBinder extends Binder {
2491        ActivityManagerService mActivityManagerService;
2492        DbBinder(ActivityManagerService activityManagerService) {
2493            mActivityManagerService = activityManagerService;
2494        }
2495
2496        @Override
2497        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2498            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2499                    != PackageManager.PERMISSION_GRANTED) {
2500                pw.println("Permission Denial: can't dump dbinfo from from pid="
2501                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2502                        + " without permission " + android.Manifest.permission.DUMP);
2503                return;
2504            }
2505
2506            mActivityManagerService.dumpDbInfo(fd, pw, args);
2507        }
2508    }
2509
2510    static class CpuBinder extends Binder {
2511        ActivityManagerService mActivityManagerService;
2512        CpuBinder(ActivityManagerService activityManagerService) {
2513            mActivityManagerService = activityManagerService;
2514        }
2515
2516        @Override
2517        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2518            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2519                    != PackageManager.PERMISSION_GRANTED) {
2520                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2521                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2522                        + " without permission " + android.Manifest.permission.DUMP);
2523                return;
2524            }
2525
2526            synchronized (mActivityManagerService.mProcessCpuTracker) {
2527                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2529                        SystemClock.uptimeMillis()));
2530            }
2531        }
2532    }
2533
2534    public static final class Lifecycle extends SystemService {
2535        private final ActivityManagerService mService;
2536
2537        public Lifecycle(Context context) {
2538            super(context);
2539            mService = new ActivityManagerService(context);
2540        }
2541
2542        @Override
2543        public void onStart() {
2544            mService.start();
2545        }
2546
2547        public ActivityManagerService getService() {
2548            return mService;
2549        }
2550    }
2551
2552    // Note: This method is invoked on the main thread but may need to attach various
2553    // handlers to other threads.  So take care to be explicit about the looper.
2554    public ActivityManagerService(Context systemContext) {
2555        mContext = systemContext;
2556        mFactoryTest = FactoryTest.getMode();
2557        mSystemThread = ActivityThread.currentActivityThread();
2558
2559        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2560
2561        mHandlerThread = new ServiceThread(TAG,
2562                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2563        mHandlerThread.start();
2564        mHandler = new MainHandler(mHandlerThread.getLooper());
2565        mUiHandler = new UiHandler();
2566
2567        /* static; one-time init here */
2568        if (sKillHandler == null) {
2569            sKillThread = new ServiceThread(TAG + ":kill",
2570                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2571            sKillThread.start();
2572            sKillHandler = new KillHandler(sKillThread.getLooper());
2573        }
2574
2575        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2576                "foreground", BROADCAST_FG_TIMEOUT, false);
2577        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2578                "background", BROADCAST_BG_TIMEOUT, true);
2579        mBroadcastQueues[0] = mFgBroadcastQueue;
2580        mBroadcastQueues[1] = mBgBroadcastQueue;
2581
2582        mServices = new ActiveServices(this);
2583        mProviderMap = new ProviderMap(this);
2584        mAppErrors = new AppErrors(mContext, this);
2585
2586        // TODO: Move creation of battery stats service outside of activity manager service.
2587        File dataDir = Environment.getDataDirectory();
2588        File systemDir = new File(dataDir, "system");
2589        systemDir.mkdirs();
2590        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2591        mBatteryStatsService.getActiveStatistics().readLocked();
2592        mBatteryStatsService.scheduleWriteToDisk();
2593        mOnBattery = DEBUG_POWER ? true
2594                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2595        mBatteryStatsService.getActiveStatistics().setCallback(this);
2596
2597        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2598
2599        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2600        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2601                new IAppOpsCallback.Stub() {
2602                    @Override public void opChanged(int op, int uid, String packageName) {
2603                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2604                            if (mAppOpsService.checkOperation(op, uid, packageName)
2605                                    != AppOpsManager.MODE_ALLOWED) {
2606                                runInBackgroundDisabled(uid);
2607                            }
2608                        }
2609                    }
2610                });
2611
2612        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2613
2614        mUserController = new UserController(this);
2615
2616        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2617            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2618
2619        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2620
2621        mConfiguration.setToDefaults();
2622        mConfiguration.setLocales(LocaleList.getDefault());
2623
2624        mConfigurationSeq = mConfiguration.seq = 1;
2625        mProcessCpuTracker.init();
2626
2627        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2628        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2629        mStackSupervisor = new ActivityStackSupervisor(this);
2630        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2631        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2632
2633        mProcessCpuThread = new Thread("CpuTracker") {
2634            @Override
2635            public void run() {
2636                while (true) {
2637                    try {
2638                        try {
2639                            synchronized(this) {
2640                                final long now = SystemClock.uptimeMillis();
2641                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2642                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2643                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2644                                //        + ", write delay=" + nextWriteDelay);
2645                                if (nextWriteDelay < nextCpuDelay) {
2646                                    nextCpuDelay = nextWriteDelay;
2647                                }
2648                                if (nextCpuDelay > 0) {
2649                                    mProcessCpuMutexFree.set(true);
2650                                    this.wait(nextCpuDelay);
2651                                }
2652                            }
2653                        } catch (InterruptedException e) {
2654                        }
2655                        updateCpuStatsNow();
2656                    } catch (Exception e) {
2657                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2658                    }
2659                }
2660            }
2661        };
2662
2663        Watchdog.getInstance().addMonitor(this);
2664        Watchdog.getInstance().addThread(mHandler);
2665    }
2666
2667    public void setSystemServiceManager(SystemServiceManager mgr) {
2668        mSystemServiceManager = mgr;
2669    }
2670
2671    public void setInstaller(Installer installer) {
2672        mInstaller = installer;
2673    }
2674
2675    private void start() {
2676        Process.removeAllProcessGroups();
2677        mProcessCpuThread.start();
2678
2679        mBatteryStatsService.publish(mContext);
2680        mAppOpsService.publish(mContext);
2681        Slog.d("AppOps", "AppOpsService published");
2682        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2683    }
2684
2685    void onUserStoppedLocked(int userId) {
2686        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2687    }
2688
2689    public void initPowerManagement() {
2690        mStackSupervisor.initPowerManagement();
2691        mBatteryStatsService.initPowerManagement();
2692        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2693        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2694        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2695        mVoiceWakeLock.setReferenceCounted(false);
2696    }
2697
2698    @Override
2699    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2700            throws RemoteException {
2701        if (code == SYSPROPS_TRANSACTION) {
2702            // We need to tell all apps about the system property change.
2703            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2704            synchronized(this) {
2705                final int NP = mProcessNames.getMap().size();
2706                for (int ip=0; ip<NP; ip++) {
2707                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2708                    final int NA = apps.size();
2709                    for (int ia=0; ia<NA; ia++) {
2710                        ProcessRecord app = apps.valueAt(ia);
2711                        if (app.thread != null) {
2712                            procs.add(app.thread.asBinder());
2713                        }
2714                    }
2715                }
2716            }
2717
2718            int N = procs.size();
2719            for (int i=0; i<N; i++) {
2720                Parcel data2 = Parcel.obtain();
2721                try {
2722                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2723                } catch (RemoteException e) {
2724                }
2725                data2.recycle();
2726            }
2727        }
2728        try {
2729            return super.onTransact(code, data, reply, flags);
2730        } catch (RuntimeException e) {
2731            // The activity manager only throws security exceptions, so let's
2732            // log all others.
2733            if (!(e instanceof SecurityException)) {
2734                Slog.wtf(TAG, "Activity Manager Crash", e);
2735            }
2736            throw e;
2737        }
2738    }
2739
2740    void updateCpuStats() {
2741        final long now = SystemClock.uptimeMillis();
2742        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2743            return;
2744        }
2745        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2746            synchronized (mProcessCpuThread) {
2747                mProcessCpuThread.notify();
2748            }
2749        }
2750    }
2751
2752    void updateCpuStatsNow() {
2753        synchronized (mProcessCpuTracker) {
2754            mProcessCpuMutexFree.set(false);
2755            final long now = SystemClock.uptimeMillis();
2756            boolean haveNewCpuStats = false;
2757
2758            if (MONITOR_CPU_USAGE &&
2759                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2760                mLastCpuTime.set(now);
2761                mProcessCpuTracker.update();
2762                if (mProcessCpuTracker.hasGoodLastStats()) {
2763                    haveNewCpuStats = true;
2764                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2765                    //Slog.i(TAG, "Total CPU usage: "
2766                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2767
2768                    // Slog the cpu usage if the property is set.
2769                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2770                        int user = mProcessCpuTracker.getLastUserTime();
2771                        int system = mProcessCpuTracker.getLastSystemTime();
2772                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2773                        int irq = mProcessCpuTracker.getLastIrqTime();
2774                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2775                        int idle = mProcessCpuTracker.getLastIdleTime();
2776
2777                        int total = user + system + iowait + irq + softIrq + idle;
2778                        if (total == 0) total = 1;
2779
2780                        EventLog.writeEvent(EventLogTags.CPU,
2781                                ((user+system+iowait+irq+softIrq) * 100) / total,
2782                                (user * 100) / total,
2783                                (system * 100) / total,
2784                                (iowait * 100) / total,
2785                                (irq * 100) / total,
2786                                (softIrq * 100) / total);
2787                    }
2788                }
2789            }
2790
2791            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2792            synchronized(bstats) {
2793                synchronized(mPidsSelfLocked) {
2794                    if (haveNewCpuStats) {
2795                        if (bstats.startAddingCpuLocked()) {
2796                            int totalUTime = 0;
2797                            int totalSTime = 0;
2798                            final int N = mProcessCpuTracker.countStats();
2799                            for (int i=0; i<N; i++) {
2800                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2801                                if (!st.working) {
2802                                    continue;
2803                                }
2804                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2805                                totalUTime += st.rel_utime;
2806                                totalSTime += st.rel_stime;
2807                                if (pr != null) {
2808                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2809                                    if (ps == null || !ps.isActive()) {
2810                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2811                                                pr.info.uid, pr.processName);
2812                                    }
2813                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2814                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2815                                } else {
2816                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2817                                    if (ps == null || !ps.isActive()) {
2818                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2819                                                bstats.mapUid(st.uid), st.name);
2820                                    }
2821                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2822                                }
2823                            }
2824                            final int userTime = mProcessCpuTracker.getLastUserTime();
2825                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2826                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2827                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2828                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2829                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2830                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2831                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2832                        }
2833                    }
2834                }
2835
2836                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2837                    mLastWriteTime = now;
2838                    mBatteryStatsService.scheduleWriteToDisk();
2839                }
2840            }
2841        }
2842    }
2843
2844    @Override
2845    public void batteryNeedsCpuUpdate() {
2846        updateCpuStatsNow();
2847    }
2848
2849    @Override
2850    public void batteryPowerChanged(boolean onBattery) {
2851        // When plugging in, update the CPU stats first before changing
2852        // the plug state.
2853        updateCpuStatsNow();
2854        synchronized (this) {
2855            synchronized(mPidsSelfLocked) {
2856                mOnBattery = DEBUG_POWER ? true : onBattery;
2857            }
2858        }
2859    }
2860
2861    @Override
2862    public void batterySendBroadcast(Intent intent) {
2863        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2864                AppOpsManager.OP_NONE, null, false, false,
2865                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2866    }
2867
2868    /**
2869     * Initialize the application bind args. These are passed to each
2870     * process when the bindApplication() IPC is sent to the process. They're
2871     * lazily setup to make sure the services are running when they're asked for.
2872     */
2873    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2874        if (mAppBindArgs == null) {
2875            mAppBindArgs = new HashMap<>();
2876
2877            // Isolated processes won't get this optimization, so that we don't
2878            // violate the rules about which services they have access to.
2879            if (!isolated) {
2880                // Setup the application init args
2881                mAppBindArgs.put("package", ServiceManager.getService("package"));
2882                mAppBindArgs.put("window", ServiceManager.getService("window"));
2883                mAppBindArgs.put(Context.ALARM_SERVICE,
2884                        ServiceManager.getService(Context.ALARM_SERVICE));
2885            }
2886        }
2887        return mAppBindArgs;
2888    }
2889
2890    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2891        if (r == null || mFocusedActivity == r) {
2892            return false;
2893        }
2894
2895        if (!r.isFocusable()) {
2896            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2897            return false;
2898        }
2899
2900        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2901
2902        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2903        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2904                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2905        mDoingSetFocusedActivity = true;
2906
2907        final ActivityRecord last = mFocusedActivity;
2908        mFocusedActivity = r;
2909        if (r.task.isApplicationTask()) {
2910            if (mCurAppTimeTracker != r.appTimeTracker) {
2911                // We are switching app tracking.  Complete the current one.
2912                if (mCurAppTimeTracker != null) {
2913                    mCurAppTimeTracker.stop();
2914                    mHandler.obtainMessage(
2915                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2916                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2917                    mCurAppTimeTracker = null;
2918                }
2919                if (r.appTimeTracker != null) {
2920                    mCurAppTimeTracker = r.appTimeTracker;
2921                    startTimeTrackingFocusedActivityLocked();
2922                }
2923            } else {
2924                startTimeTrackingFocusedActivityLocked();
2925            }
2926        } else {
2927            r.appTimeTracker = null;
2928        }
2929        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2930        // TODO: Probably not, because we don't want to resume voice on switching
2931        // back to this activity
2932        if (r.task.voiceInteractor != null) {
2933            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2934        } else {
2935            finishRunningVoiceLocked();
2936            IVoiceInteractionSession session;
2937            if (last != null && ((session = last.task.voiceSession) != null
2938                    || (session = last.voiceSession) != null)) {
2939                // We had been in a voice interaction session, but now focused has
2940                // move to something different.  Just finish the session, we can't
2941                // return to it and retain the proper state and synchronization with
2942                // the voice interaction service.
2943                finishVoiceTask(session);
2944            }
2945        }
2946        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2947            mWindowManager.setFocusedApp(r.appToken, true);
2948        }
2949        applyUpdateLockStateLocked(r);
2950        applyUpdateVrModeLocked(r);
2951        if (mFocusedActivity.userId != mLastFocusedUserId) {
2952            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2953            mHandler.obtainMessage(
2954                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2955            mLastFocusedUserId = mFocusedActivity.userId;
2956        }
2957
2958        // Log a warning if the focused app is changed during the process. This could
2959        // indicate a problem of the focus setting logic!
2960        if (mFocusedActivity != r) Slog.w(TAG,
2961                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2962        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2963
2964        EventLogTags.writeAmFocusedActivity(
2965                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2966                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2967                reason);
2968        return true;
2969    }
2970
2971    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2972        if (mFocusedActivity != goingAway) {
2973            return;
2974        }
2975
2976        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2977        if (focusedStack != null) {
2978            final ActivityRecord top = focusedStack.topActivity();
2979            if (top != null && top.userId != mLastFocusedUserId) {
2980                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2981                mHandler.sendMessage(
2982                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2983                mLastFocusedUserId = top.userId;
2984            }
2985        }
2986
2987        // Try to move focus to another activity if possible.
2988        if (setFocusedActivityLocked(
2989                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2990            return;
2991        }
2992
2993        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2994                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2995        mFocusedActivity = null;
2996        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2997    }
2998
2999    @Override
3000    public void setFocusedStack(int stackId) {
3001        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3002        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3003        final long callingId = Binder.clearCallingIdentity();
3004        try {
3005            synchronized (this) {
3006                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3007                if (stack == null) {
3008                    return;
3009                }
3010                final ActivityRecord r = stack.topRunningActivityLocked();
3011                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3012                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3013                }
3014            }
3015        } finally {
3016            Binder.restoreCallingIdentity(callingId);
3017        }
3018    }
3019
3020    @Override
3021    public void setFocusedTask(int taskId) {
3022        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3023        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3024        final long callingId = Binder.clearCallingIdentity();
3025        try {
3026            synchronized (this) {
3027                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3028                if (task == null) {
3029                    return;
3030                }
3031                final ActivityRecord r = task.topRunningActivityLocked();
3032                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3033                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3034                }
3035            }
3036        } finally {
3037            Binder.restoreCallingIdentity(callingId);
3038        }
3039    }
3040
3041    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3042    @Override
3043    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3045        synchronized (this) {
3046            if (listener != null) {
3047                mTaskStackListeners.register(listener);
3048            }
3049        }
3050    }
3051
3052    @Override
3053    public void notifyActivityDrawn(IBinder token) {
3054        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3055        synchronized (this) {
3056            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3057            if (r != null) {
3058                r.task.stack.notifyActivityDrawnLocked(r);
3059            }
3060        }
3061    }
3062
3063    final void applyUpdateLockStateLocked(ActivityRecord r) {
3064        // Modifications to the UpdateLock state are done on our handler, outside
3065        // the activity manager's locks.  The new state is determined based on the
3066        // state *now* of the relevant activity record.  The object is passed to
3067        // the handler solely for logging detail, not to be consulted/modified.
3068        final boolean nextState = r != null && r.immersive;
3069        mHandler.sendMessage(
3070                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3071    }
3072
3073    final void applyUpdateVrModeLocked(ActivityRecord r) {
3074        mHandler.sendMessage(
3075                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3076    }
3077
3078    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3079        mHandler.sendMessage(
3080                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3081    }
3082
3083    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3084        Message msg = Message.obtain();
3085        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3086        msg.obj = r.task.askedCompatMode ? null : r;
3087        mUiHandler.sendMessage(msg);
3088    }
3089
3090    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3091            String what, Object obj, ProcessRecord srcApp) {
3092        app.lastActivityTime = now;
3093
3094        if (app.activities.size() > 0) {
3095            // Don't want to touch dependent processes that are hosting activities.
3096            return index;
3097        }
3098
3099        int lrui = mLruProcesses.lastIndexOf(app);
3100        if (lrui < 0) {
3101            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3102                    + what + " " + obj + " from " + srcApp);
3103            return index;
3104        }
3105
3106        if (lrui >= index) {
3107            // Don't want to cause this to move dependent processes *back* in the
3108            // list as if they were less frequently used.
3109            return index;
3110        }
3111
3112        if (lrui >= mLruProcessActivityStart) {
3113            // Don't want to touch dependent processes that are hosting activities.
3114            return index;
3115        }
3116
3117        mLruProcesses.remove(lrui);
3118        if (index > 0) {
3119            index--;
3120        }
3121        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3122                + " in LRU list: " + app);
3123        mLruProcesses.add(index, app);
3124        return index;
3125    }
3126
3127    static void killProcessGroup(int uid, int pid) {
3128        if (sKillHandler != null) {
3129            sKillHandler.sendMessage(
3130                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3131        } else {
3132            Slog.w(TAG, "Asked to kill process group before system bringup!");
3133            Process.killProcessGroup(uid, pid);
3134        }
3135    }
3136
3137    final void removeLruProcessLocked(ProcessRecord app) {
3138        int lrui = mLruProcesses.lastIndexOf(app);
3139        if (lrui >= 0) {
3140            if (!app.killed) {
3141                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3142                Process.killProcessQuiet(app.pid);
3143                killProcessGroup(app.uid, app.pid);
3144            }
3145            if (lrui <= mLruProcessActivityStart) {
3146                mLruProcessActivityStart--;
3147            }
3148            if (lrui <= mLruProcessServiceStart) {
3149                mLruProcessServiceStart--;
3150            }
3151            mLruProcesses.remove(lrui);
3152        }
3153    }
3154
3155    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3156            ProcessRecord client) {
3157        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3158                || app.treatLikeActivity;
3159        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3160        if (!activityChange && hasActivity) {
3161            // The process has activities, so we are only allowing activity-based adjustments
3162            // to move it.  It should be kept in the front of the list with other
3163            // processes that have activities, and we don't want those to change their
3164            // order except due to activity operations.
3165            return;
3166        }
3167
3168        mLruSeq++;
3169        final long now = SystemClock.uptimeMillis();
3170        app.lastActivityTime = now;
3171
3172        // First a quick reject: if the app is already at the position we will
3173        // put it, then there is nothing to do.
3174        if (hasActivity) {
3175            final int N = mLruProcesses.size();
3176            if (N > 0 && mLruProcesses.get(N-1) == app) {
3177                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3178                return;
3179            }
3180        } else {
3181            if (mLruProcessServiceStart > 0
3182                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3183                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3184                return;
3185            }
3186        }
3187
3188        int lrui = mLruProcesses.lastIndexOf(app);
3189
3190        if (app.persistent && lrui >= 0) {
3191            // We don't care about the position of persistent processes, as long as
3192            // they are in the list.
3193            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3194            return;
3195        }
3196
3197        /* In progress: compute new position first, so we can avoid doing work
3198           if the process is not actually going to move.  Not yet working.
3199        int addIndex;
3200        int nextIndex;
3201        boolean inActivity = false, inService = false;
3202        if (hasActivity) {
3203            // Process has activities, put it at the very tipsy-top.
3204            addIndex = mLruProcesses.size();
3205            nextIndex = mLruProcessServiceStart;
3206            inActivity = true;
3207        } else if (hasService) {
3208            // Process has services, put it at the top of the service list.
3209            addIndex = mLruProcessActivityStart;
3210            nextIndex = mLruProcessServiceStart;
3211            inActivity = true;
3212            inService = true;
3213        } else  {
3214            // Process not otherwise of interest, it goes to the top of the non-service area.
3215            addIndex = mLruProcessServiceStart;
3216            if (client != null) {
3217                int clientIndex = mLruProcesses.lastIndexOf(client);
3218                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3219                        + app);
3220                if (clientIndex >= 0 && addIndex > clientIndex) {
3221                    addIndex = clientIndex;
3222                }
3223            }
3224            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3225        }
3226
3227        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3228                + mLruProcessActivityStart + "): " + app);
3229        */
3230
3231        if (lrui >= 0) {
3232            if (lrui < mLruProcessActivityStart) {
3233                mLruProcessActivityStart--;
3234            }
3235            if (lrui < mLruProcessServiceStart) {
3236                mLruProcessServiceStart--;
3237            }
3238            /*
3239            if (addIndex > lrui) {
3240                addIndex--;
3241            }
3242            if (nextIndex > lrui) {
3243                nextIndex--;
3244            }
3245            */
3246            mLruProcesses.remove(lrui);
3247        }
3248
3249        /*
3250        mLruProcesses.add(addIndex, app);
3251        if (inActivity) {
3252            mLruProcessActivityStart++;
3253        }
3254        if (inService) {
3255            mLruProcessActivityStart++;
3256        }
3257        */
3258
3259        int nextIndex;
3260        if (hasActivity) {
3261            final int N = mLruProcesses.size();
3262            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3263                // Process doesn't have activities, but has clients with
3264                // activities...  move it up, but one below the top (the top
3265                // should always have a real activity).
3266                if (DEBUG_LRU) Slog.d(TAG_LRU,
3267                        "Adding to second-top of LRU activity list: " + app);
3268                mLruProcesses.add(N - 1, app);
3269                // To keep it from spamming the LRU list (by making a bunch of clients),
3270                // we will push down any other entries owned by the app.
3271                final int uid = app.info.uid;
3272                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3273                    ProcessRecord subProc = mLruProcesses.get(i);
3274                    if (subProc.info.uid == uid) {
3275                        // We want to push this one down the list.  If the process after
3276                        // it is for the same uid, however, don't do so, because we don't
3277                        // want them internally to be re-ordered.
3278                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3279                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3280                                    "Pushing uid " + uid + " swapping at " + i + ": "
3281                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3282                            ProcessRecord tmp = mLruProcesses.get(i);
3283                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3284                            mLruProcesses.set(i - 1, tmp);
3285                            i--;
3286                        }
3287                    } else {
3288                        // A gap, we can stop here.
3289                        break;
3290                    }
3291                }
3292            } else {
3293                // Process has activities, put it at the very tipsy-top.
3294                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3295                mLruProcesses.add(app);
3296            }
3297            nextIndex = mLruProcessServiceStart;
3298        } else if (hasService) {
3299            // Process has services, put it at the top of the service list.
3300            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3301            mLruProcesses.add(mLruProcessActivityStart, app);
3302            nextIndex = mLruProcessServiceStart;
3303            mLruProcessActivityStart++;
3304        } else  {
3305            // Process not otherwise of interest, it goes to the top of the non-service area.
3306            int index = mLruProcessServiceStart;
3307            if (client != null) {
3308                // If there is a client, don't allow the process to be moved up higher
3309                // in the list than that client.
3310                int clientIndex = mLruProcesses.lastIndexOf(client);
3311                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3312                        + " when updating " + app);
3313                if (clientIndex <= lrui) {
3314                    // Don't allow the client index restriction to push it down farther in the
3315                    // list than it already is.
3316                    clientIndex = lrui;
3317                }
3318                if (clientIndex >= 0 && index > clientIndex) {
3319                    index = clientIndex;
3320                }
3321            }
3322            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3323            mLruProcesses.add(index, app);
3324            nextIndex = index-1;
3325            mLruProcessActivityStart++;
3326            mLruProcessServiceStart++;
3327        }
3328
3329        // If the app is currently using a content provider or service,
3330        // bump those processes as well.
3331        for (int j=app.connections.size()-1; j>=0; j--) {
3332            ConnectionRecord cr = app.connections.valueAt(j);
3333            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3334                    && cr.binding.service.app != null
3335                    && cr.binding.service.app.lruSeq != mLruSeq
3336                    && !cr.binding.service.app.persistent) {
3337                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3338                        "service connection", cr, app);
3339            }
3340        }
3341        for (int j=app.conProviders.size()-1; j>=0; j--) {
3342            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3343            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3344                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3345                        "provider reference", cpr, app);
3346            }
3347        }
3348    }
3349
3350    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3351        if (uid == Process.SYSTEM_UID) {
3352            // The system gets to run in any process.  If there are multiple
3353            // processes with the same uid, just pick the first (this
3354            // should never happen).
3355            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3356            if (procs == null) return null;
3357            final int procCount = procs.size();
3358            for (int i = 0; i < procCount; i++) {
3359                final int procUid = procs.keyAt(i);
3360                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3361                    // Don't use an app process or different user process for system component.
3362                    continue;
3363                }
3364                return procs.valueAt(i);
3365            }
3366        }
3367        ProcessRecord proc = mProcessNames.get(processName, uid);
3368        if (false && proc != null && !keepIfLarge
3369                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3370                && proc.lastCachedPss >= 4000) {
3371            // Turn this condition on to cause killing to happen regularly, for testing.
3372            if (proc.baseProcessTracker != null) {
3373                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3374            }
3375            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3376        } else if (proc != null && !keepIfLarge
3377                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3378                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3379            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3380            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3381                if (proc.baseProcessTracker != null) {
3382                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3383                }
3384                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3385            }
3386        }
3387        return proc;
3388    }
3389
3390    void notifyPackageUse(String packageName, int reason) {
3391        IPackageManager pm = AppGlobals.getPackageManager();
3392        try {
3393            pm.notifyPackageUse(packageName, reason);
3394        } catch (RemoteException e) {
3395        }
3396    }
3397
3398    boolean isNextTransitionForward() {
3399        int transit = mWindowManager.getPendingAppTransition();
3400        return transit == TRANSIT_ACTIVITY_OPEN
3401                || transit == TRANSIT_TASK_OPEN
3402                || transit == TRANSIT_TASK_TO_FRONT;
3403    }
3404
3405    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3406            String processName, String abiOverride, int uid, Runnable crashHandler) {
3407        synchronized(this) {
3408            ApplicationInfo info = new ApplicationInfo();
3409            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3410            // For isolated processes, the former contains the parent's uid and the latter the
3411            // actual uid of the isolated process.
3412            // In the special case introduced by this method (which is, starting an isolated
3413            // process directly from the SystemServer without an actual parent app process) the
3414            // closest thing to a parent's uid is SYSTEM_UID.
3415            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3416            // the |isolated| logic in the ProcessRecord constructor.
3417            info.uid = Process.SYSTEM_UID;
3418            info.processName = processName;
3419            info.className = entryPoint;
3420            info.packageName = "android";
3421            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3422                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3423                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3424                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3425                    crashHandler);
3426            return proc != null ? proc.pid : 0;
3427        }
3428    }
3429
3430    final ProcessRecord startProcessLocked(String processName,
3431            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3432            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3433            boolean isolated, boolean keepIfLarge) {
3434        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3435                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3436                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3437                null /* crashHandler */);
3438    }
3439
3440    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3441            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3442            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3443            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3444        long startTime = SystemClock.elapsedRealtime();
3445        ProcessRecord app;
3446        if (!isolated) {
3447            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3448            checkTime(startTime, "startProcess: after getProcessRecord");
3449
3450            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3451                // If we are in the background, then check to see if this process
3452                // is bad.  If so, we will just silently fail.
3453                if (mAppErrors.isBadProcessLocked(info)) {
3454                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3455                            + "/" + info.processName);
3456                    return null;
3457                }
3458            } else {
3459                // When the user is explicitly starting a process, then clear its
3460                // crash count so that we won't make it bad until they see at
3461                // least one crash dialog again, and make the process good again
3462                // if it had been bad.
3463                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3464                        + "/" + info.processName);
3465                mAppErrors.resetProcessCrashTimeLocked(info);
3466                if (mAppErrors.isBadProcessLocked(info)) {
3467                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3468                            UserHandle.getUserId(info.uid), info.uid,
3469                            info.processName);
3470                    mAppErrors.clearBadProcessLocked(info);
3471                    if (app != null) {
3472                        app.bad = false;
3473                    }
3474                }
3475            }
3476        } else {
3477            // If this is an isolated process, it can't re-use an existing process.
3478            app = null;
3479        }
3480
3481        // app launch boost for big.little configurations
3482        // use cpusets to migrate freshly launched tasks to big cores
3483        synchronized(ActivityManagerService.this) {
3484            nativeMigrateToBoost();
3485            mIsBoosted = true;
3486            mBoostStartTime = SystemClock.uptimeMillis();
3487            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3488            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3489        }
3490
3491        // We don't have to do anything more if:
3492        // (1) There is an existing application record; and
3493        // (2) The caller doesn't think it is dead, OR there is no thread
3494        //     object attached to it so we know it couldn't have crashed; and
3495        // (3) There is a pid assigned to it, so it is either starting or
3496        //     already running.
3497        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3498                + " app=" + app + " knownToBeDead=" + knownToBeDead
3499                + " thread=" + (app != null ? app.thread : null)
3500                + " pid=" + (app != null ? app.pid : -1));
3501        if (app != null && app.pid > 0) {
3502            if (!knownToBeDead || app.thread == null) {
3503                // We already have the app running, or are waiting for it to
3504                // come up (we have a pid but not yet its thread), so keep it.
3505                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3506                // If this is a new package in the process, add the package to the list
3507                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3508                checkTime(startTime, "startProcess: done, added package to proc");
3509                return app;
3510            }
3511
3512            // An application record is attached to a previous process,
3513            // clean it up now.
3514            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3515            checkTime(startTime, "startProcess: bad proc running, killing");
3516            killProcessGroup(app.uid, app.pid);
3517            handleAppDiedLocked(app, true, true);
3518            checkTime(startTime, "startProcess: done killing old proc");
3519        }
3520
3521        String hostingNameStr = hostingName != null
3522                ? hostingName.flattenToShortString() : null;
3523
3524        if (app == null) {
3525            checkTime(startTime, "startProcess: creating new process record");
3526            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3527            if (app == null) {
3528                Slog.w(TAG, "Failed making new process record for "
3529                        + processName + "/" + info.uid + " isolated=" + isolated);
3530                return null;
3531            }
3532            app.crashHandler = crashHandler;
3533            checkTime(startTime, "startProcess: done creating new process record");
3534        } else {
3535            // If this is a new package in the process, add the package to the list
3536            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3537            checkTime(startTime, "startProcess: added package to existing proc");
3538        }
3539
3540        // If the system is not ready yet, then hold off on starting this
3541        // process until it is.
3542        if (!mProcessesReady
3543                && !isAllowedWhileBooting(info)
3544                && !allowWhileBooting) {
3545            if (!mProcessesOnHold.contains(app)) {
3546                mProcessesOnHold.add(app);
3547            }
3548            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3549                    "System not ready, putting on hold: " + app);
3550            checkTime(startTime, "startProcess: returning with proc on hold");
3551            return app;
3552        }
3553
3554        checkTime(startTime, "startProcess: stepping in to startProcess");
3555        startProcessLocked(
3556                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3557        checkTime(startTime, "startProcess: done starting proc!");
3558        return (app.pid != 0) ? app : null;
3559    }
3560
3561    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3562        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3563    }
3564
3565    private final void startProcessLocked(ProcessRecord app,
3566            String hostingType, String hostingNameStr) {
3567        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3568                null /* entryPoint */, null /* entryPointArgs */);
3569    }
3570
3571    private final void startProcessLocked(ProcessRecord app, String hostingType,
3572            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3573        long startTime = SystemClock.elapsedRealtime();
3574        if (app.pid > 0 && app.pid != MY_PID) {
3575            checkTime(startTime, "startProcess: removing from pids map");
3576            synchronized (mPidsSelfLocked) {
3577                mPidsSelfLocked.remove(app.pid);
3578                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3579            }
3580            checkTime(startTime, "startProcess: done removing from pids map");
3581            app.setPid(0);
3582        }
3583
3584        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3585                "startProcessLocked removing on hold: " + app);
3586        mProcessesOnHold.remove(app);
3587
3588        checkTime(startTime, "startProcess: starting to update cpu stats");
3589        updateCpuStats();
3590        checkTime(startTime, "startProcess: done updating cpu stats");
3591
3592        try {
3593            try {
3594                final int userId = UserHandle.getUserId(app.uid);
3595                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3596            } catch (RemoteException e) {
3597                throw e.rethrowAsRuntimeException();
3598            }
3599
3600            int uid = app.uid;
3601            int[] gids = null;
3602            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3603            if (!app.isolated) {
3604                int[] permGids = null;
3605                try {
3606                    checkTime(startTime, "startProcess: getting gids from package manager");
3607                    final IPackageManager pm = AppGlobals.getPackageManager();
3608                    permGids = pm.getPackageGids(app.info.packageName,
3609                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3610                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3611                            MountServiceInternal.class);
3612                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3613                            app.info.packageName);
3614                } catch (RemoteException e) {
3615                    throw e.rethrowAsRuntimeException();
3616                }
3617
3618                /*
3619                 * Add shared application and profile GIDs so applications can share some
3620                 * resources like shared libraries and access user-wide resources
3621                 */
3622                if (ArrayUtils.isEmpty(permGids)) {
3623                    gids = new int[2];
3624                } else {
3625                    gids = new int[permGids.length + 2];
3626                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3627                }
3628                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3629                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3630            }
3631            checkTime(startTime, "startProcess: building args");
3632            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3633                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3634                        && mTopComponent != null
3635                        && app.processName.equals(mTopComponent.getPackageName())) {
3636                    uid = 0;
3637                }
3638                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3639                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3640                    uid = 0;
3641                }
3642            }
3643            int debugFlags = 0;
3644            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3645                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3646                // Also turn on CheckJNI for debuggable apps. It's quite
3647                // awkward to turn on otherwise.
3648                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3649            }
3650            // Run the app in safe mode if its manifest requests so or the
3651            // system is booted in safe mode.
3652            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3653                mSafeMode == true) {
3654                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3655            }
3656            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3658            }
3659            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3660            if ("true".equals(genDebugInfoProperty)) {
3661                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3662            }
3663            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3664                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3665            }
3666            if ("1".equals(SystemProperties.get("debug.assert"))) {
3667                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3668            }
3669            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3670                // Enable all debug flags required by the native debugger.
3671                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3672                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3673                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3674                mNativeDebuggingApp = null;
3675            }
3676
3677            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3678            if (requiredAbi == null) {
3679                requiredAbi = Build.SUPPORTED_ABIS[0];
3680            }
3681
3682            String instructionSet = null;
3683            if (app.info.primaryCpuAbi != null) {
3684                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3685            }
3686
3687            app.gids = gids;
3688            app.requiredAbi = requiredAbi;
3689            app.instructionSet = instructionSet;
3690
3691            // Start the process.  It will either succeed and return a result containing
3692            // the PID of the new process, or else throw a RuntimeException.
3693            boolean isActivityProcess = (entryPoint == null);
3694            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3695            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3696                    app.processName);
3697            checkTime(startTime, "startProcess: asking zygote to start proc");
3698            Process.ProcessStartResult startResult = Process.start(entryPoint,
3699                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3700                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3701                    app.info.dataDir, entryPointArgs);
3702            checkTime(startTime, "startProcess: returned from zygote!");
3703            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3704
3705            if (app.isolated) {
3706                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3707            }
3708            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3709            checkTime(startTime, "startProcess: done updating battery stats");
3710
3711            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3712                    UserHandle.getUserId(uid), startResult.pid, uid,
3713                    app.processName, hostingType,
3714                    hostingNameStr != null ? hostingNameStr : "");
3715
3716            try {
3717                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3718                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3719            } catch (RemoteException ex) {
3720                // Ignore
3721            }
3722
3723            if (app.persistent) {
3724                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3725            }
3726
3727            checkTime(startTime, "startProcess: building log message");
3728            StringBuilder buf = mStringBuilder;
3729            buf.setLength(0);
3730            buf.append("Start proc ");
3731            buf.append(startResult.pid);
3732            buf.append(':');
3733            buf.append(app.processName);
3734            buf.append('/');
3735            UserHandle.formatUid(buf, uid);
3736            if (!isActivityProcess) {
3737                buf.append(" [");
3738                buf.append(entryPoint);
3739                buf.append("]");
3740            }
3741            buf.append(" for ");
3742            buf.append(hostingType);
3743            if (hostingNameStr != null) {
3744                buf.append(" ");
3745                buf.append(hostingNameStr);
3746            }
3747            Slog.i(TAG, buf.toString());
3748            app.setPid(startResult.pid);
3749            app.usingWrapper = startResult.usingWrapper;
3750            app.removed = false;
3751            app.killed = false;
3752            app.killedByAm = false;
3753            checkTime(startTime, "startProcess: starting to update pids map");
3754            synchronized (mPidsSelfLocked) {
3755                this.mPidsSelfLocked.put(startResult.pid, app);
3756                if (isActivityProcess) {
3757                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3758                    msg.obj = app;
3759                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3760                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3761                }
3762            }
3763            checkTime(startTime, "startProcess: done updating pids map");
3764        } catch (RuntimeException e) {
3765            Slog.e(TAG, "Failure starting process " + app.processName, e);
3766
3767            // Something went very wrong while trying to start this process; one
3768            // common case is when the package is frozen due to an active
3769            // upgrade. To recover, clean up any active bookkeeping related to
3770            // starting this process. (We already invoked this method once when
3771            // the package was initially frozen through KILL_APPLICATION_MSG, so
3772            // it doesn't hurt to use it again.)
3773            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3774                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3775        }
3776    }
3777
3778    void updateUsageStats(ActivityRecord component, boolean resumed) {
3779        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3780                "updateUsageStats: comp=" + component + "res=" + resumed);
3781        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3782        if (resumed) {
3783            if (mUsageStatsService != null) {
3784                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3785                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3786            }
3787            synchronized (stats) {
3788                stats.noteActivityResumedLocked(component.app.uid);
3789            }
3790        } else {
3791            if (mUsageStatsService != null) {
3792                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3793                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3794            }
3795            synchronized (stats) {
3796                stats.noteActivityPausedLocked(component.app.uid);
3797            }
3798        }
3799    }
3800
3801    Intent getHomeIntent() {
3802        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3803        intent.setComponent(mTopComponent);
3804        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3805        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3806            intent.addCategory(Intent.CATEGORY_HOME);
3807        }
3808        return intent;
3809    }
3810
3811    boolean startHomeActivityLocked(int userId, String reason) {
3812        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3813                && mTopAction == null) {
3814            // We are running in factory test mode, but unable to find
3815            // the factory test app, so just sit around displaying the
3816            // error message and don't try to start anything.
3817            return false;
3818        }
3819        Intent intent = getHomeIntent();
3820        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3821        if (aInfo != null) {
3822            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3823            // Don't do this if the home app is currently being
3824            // instrumented.
3825            aInfo = new ActivityInfo(aInfo);
3826            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3827            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3828                    aInfo.applicationInfo.uid, true);
3829            if (app == null || app.instrumentationClass == null) {
3830                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3831                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3832            }
3833        } else {
3834            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3835        }
3836
3837        return true;
3838    }
3839
3840    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3841        ActivityInfo ai = null;
3842        ComponentName comp = intent.getComponent();
3843        try {
3844            if (comp != null) {
3845                // Factory test.
3846                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3847            } else {
3848                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3849                        intent,
3850                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3851                        flags, userId);
3852
3853                if (info != null) {
3854                    ai = info.activityInfo;
3855                }
3856            }
3857        } catch (RemoteException e) {
3858            // ignore
3859        }
3860
3861        return ai;
3862    }
3863
3864    /**
3865     * Starts the "new version setup screen" if appropriate.
3866     */
3867    void startSetupActivityLocked() {
3868        // Only do this once per boot.
3869        if (mCheckedForSetup) {
3870            return;
3871        }
3872
3873        // We will show this screen if the current one is a different
3874        // version than the last one shown, and we are not running in
3875        // low-level factory test mode.
3876        final ContentResolver resolver = mContext.getContentResolver();
3877        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3878                Settings.Global.getInt(resolver,
3879                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3880            mCheckedForSetup = true;
3881
3882            // See if we should be showing the platform update setup UI.
3883            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3884            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3885                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3886            if (!ris.isEmpty()) {
3887                final ResolveInfo ri = ris.get(0);
3888                String vers = ri.activityInfo.metaData != null
3889                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3890                        : null;
3891                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3892                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3893                            Intent.METADATA_SETUP_VERSION);
3894                }
3895                String lastVers = Settings.Secure.getString(
3896                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3897                if (vers != null && !vers.equals(lastVers)) {
3898                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3899                    intent.setComponent(new ComponentName(
3900                            ri.activityInfo.packageName, ri.activityInfo.name));
3901                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3902                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3903                            null, 0, 0, 0, null, false, false, null, null, null);
3904                }
3905            }
3906        }
3907    }
3908
3909    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3910        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3911    }
3912
3913    void enforceNotIsolatedCaller(String caller) {
3914        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3915            throw new SecurityException("Isolated process not allowed to call " + caller);
3916        }
3917    }
3918
3919    void enforceShellRestriction(String restriction, int userHandle) {
3920        if (Binder.getCallingUid() == Process.SHELL_UID) {
3921            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3922                throw new SecurityException("Shell does not have permission to access user "
3923                        + userHandle);
3924            }
3925        }
3926    }
3927
3928    @Override
3929    public int getFrontActivityScreenCompatMode() {
3930        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3931        synchronized (this) {
3932            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3933        }
3934    }
3935
3936    @Override
3937    public void setFrontActivityScreenCompatMode(int mode) {
3938        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3939                "setFrontActivityScreenCompatMode");
3940        synchronized (this) {
3941            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3942        }
3943    }
3944
3945    @Override
3946    public int getPackageScreenCompatMode(String packageName) {
3947        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3948        synchronized (this) {
3949            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3950        }
3951    }
3952
3953    @Override
3954    public void setPackageScreenCompatMode(String packageName, int mode) {
3955        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3956                "setPackageScreenCompatMode");
3957        synchronized (this) {
3958            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3959        }
3960    }
3961
3962    @Override
3963    public boolean getPackageAskScreenCompat(String packageName) {
3964        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3965        synchronized (this) {
3966            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3967        }
3968    }
3969
3970    @Override
3971    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3973                "setPackageAskScreenCompat");
3974        synchronized (this) {
3975            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3976        }
3977    }
3978
3979    private boolean hasUsageStatsPermission(String callingPackage) {
3980        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3981                Binder.getCallingUid(), callingPackage);
3982        if (mode == AppOpsManager.MODE_DEFAULT) {
3983            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3984                    == PackageManager.PERMISSION_GRANTED;
3985        }
3986        return mode == AppOpsManager.MODE_ALLOWED;
3987    }
3988
3989    @Override
3990    public int getPackageProcessState(String packageName, String callingPackage) {
3991        if (!hasUsageStatsPermission(callingPackage)) {
3992            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3993                    "getPackageProcessState");
3994        }
3995
3996        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3997        synchronized (this) {
3998            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3999                final ProcessRecord proc = mLruProcesses.get(i);
4000                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4001                        || procState > proc.setProcState) {
4002                    boolean found = false;
4003                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4004                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4005                            procState = proc.setProcState;
4006                            found = true;
4007                        }
4008                    }
4009                    if (proc.pkgDeps != null && !found) {
4010                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4011                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4012                                procState = proc.setProcState;
4013                                break;
4014                            }
4015                        }
4016                    }
4017                }
4018            }
4019        }
4020        return procState;
4021    }
4022
4023    @Override
4024    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4025        synchronized (this) {
4026            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4027            if (app == null) {
4028                return false;
4029            }
4030            if (app.trimMemoryLevel < level && app.thread != null &&
4031                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4032                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4033                try {
4034                    app.thread.scheduleTrimMemory(level);
4035                    app.trimMemoryLevel = level;
4036                    return true;
4037                } catch (RemoteException e) {
4038                    // Fallthrough to failure case.
4039                }
4040            }
4041        }
4042        return false;
4043    }
4044
4045    private void dispatchProcessesChanged() {
4046        int N;
4047        synchronized (this) {
4048            N = mPendingProcessChanges.size();
4049            if (mActiveProcessChanges.length < N) {
4050                mActiveProcessChanges = new ProcessChangeItem[N];
4051            }
4052            mPendingProcessChanges.toArray(mActiveProcessChanges);
4053            mPendingProcessChanges.clear();
4054            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4055                    "*** Delivering " + N + " process changes");
4056        }
4057
4058        int i = mProcessObservers.beginBroadcast();
4059        while (i > 0) {
4060            i--;
4061            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4062            if (observer != null) {
4063                try {
4064                    for (int j=0; j<N; j++) {
4065                        ProcessChangeItem item = mActiveProcessChanges[j];
4066                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4067                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4068                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4069                                    + item.uid + ": " + item.foregroundActivities);
4070                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4071                                    item.foregroundActivities);
4072                        }
4073                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4074                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4075                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4076                                    + ": " + item.processState);
4077                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4078                        }
4079                    }
4080                } catch (RemoteException e) {
4081                }
4082            }
4083        }
4084        mProcessObservers.finishBroadcast();
4085
4086        synchronized (this) {
4087            for (int j=0; j<N; j++) {
4088                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4089            }
4090        }
4091    }
4092
4093    private void dispatchProcessDied(int pid, int uid) {
4094        int i = mProcessObservers.beginBroadcast();
4095        while (i > 0) {
4096            i--;
4097            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4098            if (observer != null) {
4099                try {
4100                    observer.onProcessDied(pid, uid);
4101                } catch (RemoteException e) {
4102                }
4103            }
4104        }
4105        mProcessObservers.finishBroadcast();
4106    }
4107
4108    private void dispatchUidsChanged() {
4109        int N;
4110        synchronized (this) {
4111            N = mPendingUidChanges.size();
4112            if (mActiveUidChanges.length < N) {
4113                mActiveUidChanges = new UidRecord.ChangeItem[N];
4114            }
4115            for (int i=0; i<N; i++) {
4116                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4117                mActiveUidChanges[i] = change;
4118                if (change.uidRecord != null) {
4119                    change.uidRecord.pendingChange = null;
4120                    change.uidRecord = null;
4121                }
4122            }
4123            mPendingUidChanges.clear();
4124            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4125                    "*** Delivering " + N + " uid changes");
4126        }
4127
4128        if (mLocalPowerManager != null) {
4129            for (int j=0; j<N; j++) {
4130                UidRecord.ChangeItem item = mActiveUidChanges[j];
4131                if (item.change == UidRecord.CHANGE_GONE
4132                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4133                    mLocalPowerManager.uidGone(item.uid);
4134                } else {
4135                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4136                }
4137            }
4138        }
4139
4140        int i = mUidObservers.beginBroadcast();
4141        while (i > 0) {
4142            i--;
4143            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4144            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4145            if (observer != null) {
4146                try {
4147                    for (int j=0; j<N; j++) {
4148                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4149                        final int change = item.change;
4150                        UidRecord validateUid = null;
4151                        if (VALIDATE_UID_STATES && i == 0) {
4152                            validateUid = mValidateUids.get(item.uid);
4153                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4154                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4155                                validateUid = new UidRecord(item.uid);
4156                                mValidateUids.put(item.uid, validateUid);
4157                            }
4158                        }
4159                        if (change == UidRecord.CHANGE_IDLE
4160                                || change == UidRecord.CHANGE_GONE_IDLE) {
4161                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4162                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4163                                        "UID idle uid=" + item.uid);
4164                                observer.onUidIdle(item.uid);
4165                            }
4166                            if (VALIDATE_UID_STATES && i == 0) {
4167                                if (validateUid != null) {
4168                                    validateUid.idle = true;
4169                                }
4170                            }
4171                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4172                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4173                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4174                                        "UID active uid=" + item.uid);
4175                                observer.onUidActive(item.uid);
4176                            }
4177                            if (VALIDATE_UID_STATES && i == 0) {
4178                                validateUid.idle = false;
4179                            }
4180                        }
4181                        if (change == UidRecord.CHANGE_GONE
4182                                || change == UidRecord.CHANGE_GONE_IDLE) {
4183                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4184                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4185                                        "UID gone uid=" + item.uid);
4186                                observer.onUidGone(item.uid);
4187                            }
4188                            if (VALIDATE_UID_STATES && i == 0) {
4189                                if (validateUid != null) {
4190                                    mValidateUids.remove(item.uid);
4191                                }
4192                            }
4193                        } else {
4194                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4195                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4196                                        "UID CHANGED uid=" + item.uid
4197                                                + ": " + item.processState);
4198                                observer.onUidStateChanged(item.uid, item.processState);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                validateUid.curProcState = validateUid.setProcState
4202                                        = item.processState;
4203                            }
4204                        }
4205                    }
4206                } catch (RemoteException e) {
4207                }
4208            }
4209        }
4210        mUidObservers.finishBroadcast();
4211
4212        synchronized (this) {
4213            for (int j=0; j<N; j++) {
4214                mAvailUidChanges.add(mActiveUidChanges[j]);
4215            }
4216        }
4217    }
4218
4219    @Override
4220    public final int startActivity(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4223        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4224                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4225                UserHandle.getCallingUserId());
4226    }
4227
4228    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4229        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4230        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4231                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4232                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4233
4234        // TODO: Switch to user app stacks here.
4235        String mimeType = intent.getType();
4236        final Uri data = intent.getData();
4237        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4238            mimeType = getProviderMimeType(data, userId);
4239        }
4240        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4241
4242        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4243        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4244                null, 0, 0, null, null, null, null, false, userId, container, null);
4245    }
4246
4247    @Override
4248    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4249            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4250            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4251        enforceNotIsolatedCaller("startActivity");
4252        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4253                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4254        // TODO: Switch to user app stacks here.
4255        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4256                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4257                profilerInfo, null, null, bOptions, false, userId, null, null);
4258    }
4259
4260    @Override
4261    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4262            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4263            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4264            int userId) {
4265
4266        // This is very dangerous -- it allows you to perform a start activity (including
4267        // permission grants) as any app that may launch one of your own activities.  So
4268        // we will only allow this to be done from activities that are part of the core framework,
4269        // and then only when they are running as the system.
4270        final ActivityRecord sourceRecord;
4271        final int targetUid;
4272        final String targetPackage;
4273        synchronized (this) {
4274            if (resultTo == null) {
4275                throw new SecurityException("Must be called from an activity");
4276            }
4277            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4278            if (sourceRecord == null) {
4279                throw new SecurityException("Called with bad activity token: " + resultTo);
4280            }
4281            if (!sourceRecord.info.packageName.equals("android")) {
4282                throw new SecurityException(
4283                        "Must be called from an activity that is declared in the android package");
4284            }
4285            if (sourceRecord.app == null) {
4286                throw new SecurityException("Called without a process attached to activity");
4287            }
4288            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4289                // This is still okay, as long as this activity is running under the
4290                // uid of the original calling activity.
4291                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4292                    throw new SecurityException(
4293                            "Calling activity in uid " + sourceRecord.app.uid
4294                                    + " must be system uid or original calling uid "
4295                                    + sourceRecord.launchedFromUid);
4296                }
4297            }
4298            if (ignoreTargetSecurity) {
4299                if (intent.getComponent() == null) {
4300                    throw new SecurityException(
4301                            "Component must be specified with ignoreTargetSecurity");
4302                }
4303                if (intent.getSelector() != null) {
4304                    throw new SecurityException(
4305                            "Selector not allowed with ignoreTargetSecurity");
4306                }
4307            }
4308            targetUid = sourceRecord.launchedFromUid;
4309            targetPackage = sourceRecord.launchedFromPackage;
4310        }
4311
4312        if (userId == UserHandle.USER_NULL) {
4313            userId = UserHandle.getUserId(sourceRecord.app.uid);
4314        }
4315
4316        // TODO: Switch to user app stacks here.
4317        try {
4318            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4319                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4320                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4321            return ret;
4322        } catch (SecurityException e) {
4323            // XXX need to figure out how to propagate to original app.
4324            // A SecurityException here is generally actually a fault of the original
4325            // calling activity (such as a fairly granting permissions), so propagate it
4326            // back to them.
4327            /*
4328            StringBuilder msg = new StringBuilder();
4329            msg.append("While launching");
4330            msg.append(intent.toString());
4331            msg.append(": ");
4332            msg.append(e.getMessage());
4333            */
4334            throw e;
4335        }
4336    }
4337
4338    @Override
4339    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4341            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4342        enforceNotIsolatedCaller("startActivityAndWait");
4343        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4344                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4345        WaitResult res = new WaitResult();
4346        // TODO: Switch to user app stacks here.
4347        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4348                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4349                bOptions, false, userId, null, null);
4350        return res;
4351    }
4352
4353    @Override
4354    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4356            int startFlags, Configuration config, Bundle bOptions, int userId) {
4357        enforceNotIsolatedCaller("startActivityWithConfig");
4358        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4359                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4360        // TODO: Switch to user app stacks here.
4361        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4362                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4363                null, null, config, bOptions, false, userId, null, null);
4364        return ret;
4365    }
4366
4367    @Override
4368    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4369            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4370            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4371            throws TransactionTooLargeException {
4372        enforceNotIsolatedCaller("startActivityIntentSender");
4373        // Refuse possible leaked file descriptors
4374        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4375            throw new IllegalArgumentException("File descriptors passed in Intent");
4376        }
4377
4378        IIntentSender sender = intent.getTarget();
4379        if (!(sender instanceof PendingIntentRecord)) {
4380            throw new IllegalArgumentException("Bad PendingIntent object");
4381        }
4382
4383        PendingIntentRecord pir = (PendingIntentRecord)sender;
4384
4385        synchronized (this) {
4386            // If this is coming from the currently resumed activity, it is
4387            // effectively saying that app switches are allowed at this point.
4388            final ActivityStack stack = getFocusedStack();
4389            if (stack.mResumedActivity != null &&
4390                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4391                mAppSwitchesAllowedTime = 0;
4392            }
4393        }
4394        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4395                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4396        return ret;
4397    }
4398
4399    @Override
4400    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4401            Intent intent, String resolvedType, IVoiceInteractionSession session,
4402            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4403            Bundle bOptions, int userId) {
4404        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4405                != PackageManager.PERMISSION_GRANTED) {
4406            String msg = "Permission Denial: startVoiceActivity() from pid="
4407                    + Binder.getCallingPid()
4408                    + ", uid=" + Binder.getCallingUid()
4409                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4410            Slog.w(TAG, msg);
4411            throw new SecurityException(msg);
4412        }
4413        if (session == null || interactor == null) {
4414            throw new NullPointerException("null session or interactor");
4415        }
4416        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4417                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4418        // TODO: Switch to user app stacks here.
4419        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4420                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4421                null, bOptions, false, userId, null, null);
4422    }
4423
4424    @Override
4425    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4426            throws RemoteException {
4427        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4428        synchronized (this) {
4429            ActivityRecord activity = getFocusedStack().topActivity();
4430            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4431                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4432            }
4433            if (mRunningVoice != null || activity.task.voiceSession != null
4434                    || activity.voiceSession != null) {
4435                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4436                return;
4437            }
4438            if (activity.pendingVoiceInteractionStart) {
4439                Slog.w(TAG, "Pending start of voice interaction already.");
4440                return;
4441            }
4442            activity.pendingVoiceInteractionStart = true;
4443        }
4444        LocalServices.getService(VoiceInteractionManagerInternal.class)
4445                .startLocalVoiceInteraction(callingActivity, options);
4446    }
4447
4448    @Override
4449    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4450        LocalServices.getService(VoiceInteractionManagerInternal.class)
4451                .stopLocalVoiceInteraction(callingActivity);
4452    }
4453
4454    @Override
4455    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4456        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4457                .supportsLocalVoiceInteraction();
4458    }
4459
4460    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4461            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4462        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4463        if (activityToCallback == null) return;
4464        activityToCallback.setVoiceSessionLocked(voiceSession);
4465
4466        // Inform the activity
4467        try {
4468            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4469                    voiceInteractor);
4470            long token = Binder.clearCallingIdentity();
4471            try {
4472                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4473            } finally {
4474                Binder.restoreCallingIdentity(token);
4475            }
4476            // TODO: VI Should we cache the activity so that it's easier to find later
4477            // rather than scan through all the stacks and activities?
4478        } catch (RemoteException re) {
4479            activityToCallback.clearVoiceSessionLocked();
4480            // TODO: VI Should this terminate the voice session?
4481        }
4482    }
4483
4484    @Override
4485    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4486        synchronized (this) {
4487            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4488                if (keepAwake) {
4489                    mVoiceWakeLock.acquire();
4490                } else {
4491                    mVoiceWakeLock.release();
4492                }
4493            }
4494        }
4495    }
4496
4497    @Override
4498    public boolean startNextMatchingActivity(IBinder callingActivity,
4499            Intent intent, Bundle bOptions) {
4500        // Refuse possible leaked file descriptors
4501        if (intent != null && intent.hasFileDescriptors() == true) {
4502            throw new IllegalArgumentException("File descriptors passed in Intent");
4503        }
4504        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4505
4506        synchronized (this) {
4507            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4508            if (r == null) {
4509                ActivityOptions.abort(options);
4510                return false;
4511            }
4512            if (r.app == null || r.app.thread == null) {
4513                // The caller is not running...  d'oh!
4514                ActivityOptions.abort(options);
4515                return false;
4516            }
4517            intent = new Intent(intent);
4518            // The caller is not allowed to change the data.
4519            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4520            // And we are resetting to find the next component...
4521            intent.setComponent(null);
4522
4523            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4524
4525            ActivityInfo aInfo = null;
4526            try {
4527                List<ResolveInfo> resolves =
4528                    AppGlobals.getPackageManager().queryIntentActivities(
4529                            intent, r.resolvedType,
4530                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4531                            UserHandle.getCallingUserId()).getList();
4532
4533                // Look for the original activity in the list...
4534                final int N = resolves != null ? resolves.size() : 0;
4535                for (int i=0; i<N; i++) {
4536                    ResolveInfo rInfo = resolves.get(i);
4537                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4538                            && rInfo.activityInfo.name.equals(r.info.name)) {
4539                        // We found the current one...  the next matching is
4540                        // after it.
4541                        i++;
4542                        if (i<N) {
4543                            aInfo = resolves.get(i).activityInfo;
4544                        }
4545                        if (debug) {
4546                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4547                                    + "/" + r.info.name);
4548                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4549                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4550                        }
4551                        break;
4552                    }
4553                }
4554            } catch (RemoteException e) {
4555            }
4556
4557            if (aInfo == null) {
4558                // Nobody who is next!
4559                ActivityOptions.abort(options);
4560                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4561                return false;
4562            }
4563
4564            intent.setComponent(new ComponentName(
4565                    aInfo.applicationInfo.packageName, aInfo.name));
4566            intent.setFlags(intent.getFlags()&~(
4567                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4568                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4569                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4570                    Intent.FLAG_ACTIVITY_NEW_TASK));
4571
4572            // Okay now we need to start the new activity, replacing the
4573            // currently running activity.  This is a little tricky because
4574            // we want to start the new one as if the current one is finished,
4575            // but not finish the current one first so that there is no flicker.
4576            // And thus...
4577            final boolean wasFinishing = r.finishing;
4578            r.finishing = true;
4579
4580            // Propagate reply information over to the new activity.
4581            final ActivityRecord resultTo = r.resultTo;
4582            final String resultWho = r.resultWho;
4583            final int requestCode = r.requestCode;
4584            r.resultTo = null;
4585            if (resultTo != null) {
4586                resultTo.removeResultsLocked(r, resultWho, requestCode);
4587            }
4588
4589            final long origId = Binder.clearCallingIdentity();
4590            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4591                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4592                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4593                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4594                    false, false, null, null, null);
4595            Binder.restoreCallingIdentity(origId);
4596
4597            r.finishing = wasFinishing;
4598            if (res != ActivityManager.START_SUCCESS) {
4599                return false;
4600            }
4601            return true;
4602        }
4603    }
4604
4605    @Override
4606    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4607        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4608            String msg = "Permission Denial: startActivityFromRecents called without " +
4609                    START_TASKS_FROM_RECENTS;
4610            Slog.w(TAG, msg);
4611            throw new SecurityException(msg);
4612        }
4613        final long origId = Binder.clearCallingIdentity();
4614        try {
4615            synchronized (this) {
4616                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4617            }
4618        } finally {
4619            Binder.restoreCallingIdentity(origId);
4620        }
4621    }
4622
4623    final int startActivityInPackage(int uid, String callingPackage,
4624            Intent intent, String resolvedType, IBinder resultTo,
4625            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4626            IActivityContainer container, TaskRecord inTask) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630
4631        // TODO: Switch to user app stacks here.
4632        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4633                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4634                null, null, null, bOptions, false, userId, container, inTask);
4635        return ret;
4636    }
4637
4638    @Override
4639    public final int startActivities(IApplicationThread caller, String callingPackage,
4640            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4641            int userId) {
4642        enforceNotIsolatedCaller("startActivities");
4643        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4644                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4645        // TODO: Switch to user app stacks here.
4646        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4647                resolvedTypes, resultTo, bOptions, userId);
4648        return ret;
4649    }
4650
4651    final int startActivitiesInPackage(int uid, String callingPackage,
4652            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4653            Bundle bOptions, int userId) {
4654
4655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4656                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4657        // TODO: Switch to user app stacks here.
4658        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4659                resultTo, bOptions, userId);
4660        return ret;
4661    }
4662
4663    @Override
4664    public void reportActivityFullyDrawn(IBinder token) {
4665        synchronized (this) {
4666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4667            if (r == null) {
4668                return;
4669            }
4670            r.reportFullyDrawnLocked();
4671        }
4672    }
4673
4674    @Override
4675    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return;
4680            }
4681            TaskRecord task = r.task;
4682            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4683                // Fixed screen orientation isn't supported when activities aren't in full screen
4684                // mode.
4685                return;
4686            }
4687            final long origId = Binder.clearCallingIdentity();
4688            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4689            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4690                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4691            if (config != null) {
4692                r.frozenBeforeDestroy = true;
4693                if (!updateConfigurationLocked(config, r, false)) {
4694                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4695                }
4696            }
4697            Binder.restoreCallingIdentity(origId);
4698        }
4699    }
4700
4701    @Override
4702    public int getRequestedOrientation(IBinder token) {
4703        synchronized (this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4707            }
4708            return mWindowManager.getAppOrientation(r.appToken);
4709        }
4710    }
4711
4712    /**
4713     * This is the internal entry point for handling Activity.finish().
4714     *
4715     * @param token The Binder token referencing the Activity we want to finish.
4716     * @param resultCode Result code, if any, from this Activity.
4717     * @param resultData Result data (Intent), if any, from this Activity.
4718     * @param finishTask Whether to finish the task associated with this Activity.
4719     *
4720     * @return Returns true if the activity successfully finished, or false if it is still running.
4721     */
4722    @Override
4723    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4724            int finishTask) {
4725        // Refuse possible leaked file descriptors
4726        if (resultData != null && resultData.hasFileDescriptors() == true) {
4727            throw new IllegalArgumentException("File descriptors passed in Intent");
4728        }
4729
4730        synchronized(this) {
4731            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4732            if (r == null) {
4733                return true;
4734            }
4735            // Keep track of the root activity of the task before we finish it
4736            TaskRecord tr = r.task;
4737            ActivityRecord rootR = tr.getRootActivity();
4738            if (rootR == null) {
4739                Slog.w(TAG, "Finishing task with all activities already finished");
4740            }
4741            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4742            // finish.
4743            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4744                    mStackSupervisor.isLastLockedTask(tr)) {
4745                Slog.i(TAG, "Not finishing task in lock task mode");
4746                mStackSupervisor.showLockTaskToast();
4747                return false;
4748            }
4749            if (mController != null) {
4750                // Find the first activity that is not finishing.
4751                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4752                if (next != null) {
4753                    // ask watcher if this is allowed
4754                    boolean resumeOK = true;
4755                    try {
4756                        resumeOK = mController.activityResuming(next.packageName);
4757                    } catch (RemoteException e) {
4758                        mController = null;
4759                        Watchdog.getInstance().setActivityController(null);
4760                    }
4761
4762                    if (!resumeOK) {
4763                        Slog.i(TAG, "Not finishing activity because controller resumed");
4764                        return false;
4765                    }
4766                }
4767            }
4768            final long origId = Binder.clearCallingIdentity();
4769            try {
4770                boolean res;
4771                final boolean finishWithRootActivity =
4772                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4773                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4774                        || (finishWithRootActivity && r == rootR)) {
4775                    // If requested, remove the task that is associated to this activity only if it
4776                    // was the root activity in the task. The result code and data is ignored
4777                    // because we don't support returning them across task boundaries. Also, to
4778                    // keep backwards compatibility we remove the task from recents when finishing
4779                    // task with root activity.
4780                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4781                    if (!res) {
4782                        Slog.i(TAG, "Removing task failed to finish activity");
4783                    }
4784                } else {
4785                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4786                            resultData, "app-request", true);
4787                    if (!res) {
4788                        Slog.i(TAG, "Failed to finish by app-request");
4789                    }
4790                }
4791                return res;
4792            } finally {
4793                Binder.restoreCallingIdentity(origId);
4794            }
4795        }
4796    }
4797
4798    @Override
4799    public final void finishHeavyWeightApp() {
4800        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4801                != PackageManager.PERMISSION_GRANTED) {
4802            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4803                    + Binder.getCallingPid()
4804                    + ", uid=" + Binder.getCallingUid()
4805                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4806            Slog.w(TAG, msg);
4807            throw new SecurityException(msg);
4808        }
4809
4810        synchronized(this) {
4811            if (mHeavyWeightProcess == null) {
4812                return;
4813            }
4814
4815            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4816            for (int i = 0; i < activities.size(); i++) {
4817                ActivityRecord r = activities.get(i);
4818                if (!r.finishing && r.isInStackLocked()) {
4819                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4820                            null, "finish-heavy", true);
4821                }
4822            }
4823
4824            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4825                    mHeavyWeightProcess.userId, 0));
4826            mHeavyWeightProcess = null;
4827        }
4828    }
4829
4830    @Override
4831    public void crashApplication(int uid, int initialPid, String packageName,
4832            String message) {
4833        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4834                != PackageManager.PERMISSION_GRANTED) {
4835            String msg = "Permission Denial: crashApplication() from pid="
4836                    + Binder.getCallingPid()
4837                    + ", uid=" + Binder.getCallingUid()
4838                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4839            Slog.w(TAG, msg);
4840            throw new SecurityException(msg);
4841        }
4842
4843        synchronized(this) {
4844            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4845        }
4846    }
4847
4848    @Override
4849    public final void finishSubActivity(IBinder token, String resultWho,
4850            int requestCode) {
4851        synchronized(this) {
4852            final long origId = Binder.clearCallingIdentity();
4853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4854            if (r != null) {
4855                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4856            }
4857            Binder.restoreCallingIdentity(origId);
4858        }
4859    }
4860
4861    @Override
4862    public boolean finishActivityAffinity(IBinder token) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            try {
4866                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4867                if (r == null) {
4868                    return false;
4869                }
4870
4871                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4872                // can finish.
4873                final TaskRecord task = r.task;
4874                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4875                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4876                    mStackSupervisor.showLockTaskToast();
4877                    return false;
4878                }
4879                return task.stack.finishActivityAffinityLocked(r);
4880            } finally {
4881                Binder.restoreCallingIdentity(origId);
4882            }
4883        }
4884    }
4885
4886    @Override
4887    public void finishVoiceTask(IVoiceInteractionSession session) {
4888        synchronized (this) {
4889            final long origId = Binder.clearCallingIdentity();
4890            try {
4891                // TODO: VI Consider treating local voice interactions and voice tasks
4892                // differently here
4893                mStackSupervisor.finishVoiceTask(session);
4894            } finally {
4895                Binder.restoreCallingIdentity(origId);
4896            }
4897        }
4898
4899    }
4900
4901    @Override
4902    public boolean releaseActivityInstance(IBinder token) {
4903        synchronized(this) {
4904            final long origId = Binder.clearCallingIdentity();
4905            try {
4906                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4907                if (r == null) {
4908                    return false;
4909                }
4910                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4911            } finally {
4912                Binder.restoreCallingIdentity(origId);
4913            }
4914        }
4915    }
4916
4917    @Override
4918    public void releaseSomeActivities(IApplicationThread appInt) {
4919        synchronized(this) {
4920            final long origId = Binder.clearCallingIdentity();
4921            try {
4922                ProcessRecord app = getRecordForAppLocked(appInt);
4923                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4924            } finally {
4925                Binder.restoreCallingIdentity(origId);
4926            }
4927        }
4928    }
4929
4930    @Override
4931    public boolean willActivityBeVisible(IBinder token) {
4932        synchronized(this) {
4933            ActivityStack stack = ActivityRecord.getStackLocked(token);
4934            if (stack != null) {
4935                return stack.willActivityBeVisibleLocked(token);
4936            }
4937            return false;
4938        }
4939    }
4940
4941    @Override
4942    public void overridePendingTransition(IBinder token, String packageName,
4943            int enterAnim, int exitAnim) {
4944        synchronized(this) {
4945            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4946            if (self == null) {
4947                return;
4948            }
4949
4950            final long origId = Binder.clearCallingIdentity();
4951
4952            if (self.state == ActivityState.RESUMED
4953                    || self.state == ActivityState.PAUSING) {
4954                mWindowManager.overridePendingAppTransition(packageName,
4955                        enterAnim, exitAnim, null);
4956            }
4957
4958            Binder.restoreCallingIdentity(origId);
4959        }
4960    }
4961
4962    /**
4963     * Main function for removing an existing process from the activity manager
4964     * as a result of that process going away.  Clears out all connections
4965     * to the process.
4966     */
4967    private final void handleAppDiedLocked(ProcessRecord app,
4968            boolean restarting, boolean allowRestart) {
4969        int pid = app.pid;
4970        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4971        if (!kept && !restarting) {
4972            removeLruProcessLocked(app);
4973            if (pid > 0) {
4974                ProcessList.remove(pid);
4975            }
4976        }
4977
4978        if (mProfileProc == app) {
4979            clearProfilerLocked();
4980        }
4981
4982        // Remove this application's activities from active lists.
4983        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4984
4985        app.activities.clear();
4986
4987        if (app.instrumentationClass != null) {
4988            Slog.w(TAG, "Crash of app " + app.processName
4989                  + " running instrumentation " + app.instrumentationClass);
4990            Bundle info = new Bundle();
4991            info.putString("shortMsg", "Process crashed.");
4992            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4993        }
4994
4995        if (!restarting && hasVisibleActivities
4996                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4997            // If there was nothing to resume, and we are not already restarting this process, but
4998            // there is a visible activity that is hosted by the process...  then make sure all
4999            // visible activities are running, taking care of restarting this process.
5000            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5001        }
5002    }
5003
5004    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5005        IBinder threadBinder = thread.asBinder();
5006        // Find the application record.
5007        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5008            ProcessRecord rec = mLruProcesses.get(i);
5009            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5010                return i;
5011            }
5012        }
5013        return -1;
5014    }
5015
5016    final ProcessRecord getRecordForAppLocked(
5017            IApplicationThread thread) {
5018        if (thread == null) {
5019            return null;
5020        }
5021
5022        int appIndex = getLRURecordIndexForAppLocked(thread);
5023        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5024    }
5025
5026    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5027        // If there are no longer any background processes running,
5028        // and the app that died was not running instrumentation,
5029        // then tell everyone we are now low on memory.
5030        boolean haveBg = false;
5031        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5032            ProcessRecord rec = mLruProcesses.get(i);
5033            if (rec.thread != null
5034                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5035                haveBg = true;
5036                break;
5037            }
5038        }
5039
5040        if (!haveBg) {
5041            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5042            if (doReport) {
5043                long now = SystemClock.uptimeMillis();
5044                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5045                    doReport = false;
5046                } else {
5047                    mLastMemUsageReportTime = now;
5048                }
5049            }
5050            final ArrayList<ProcessMemInfo> memInfos
5051                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5052            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5053            long now = SystemClock.uptimeMillis();
5054            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5055                ProcessRecord rec = mLruProcesses.get(i);
5056                if (rec == dyingProc || rec.thread == null) {
5057                    continue;
5058                }
5059                if (doReport) {
5060                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5061                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5062                }
5063                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5064                    // The low memory report is overriding any current
5065                    // state for a GC request.  Make sure to do
5066                    // heavy/important/visible/foreground processes first.
5067                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5068                        rec.lastRequestedGc = 0;
5069                    } else {
5070                        rec.lastRequestedGc = rec.lastLowMemory;
5071                    }
5072                    rec.reportLowMemory = true;
5073                    rec.lastLowMemory = now;
5074                    mProcessesToGc.remove(rec);
5075                    addProcessToGcListLocked(rec);
5076                }
5077            }
5078            if (doReport) {
5079                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5080                mHandler.sendMessage(msg);
5081            }
5082            scheduleAppGcsLocked();
5083        }
5084    }
5085
5086    final void appDiedLocked(ProcessRecord app) {
5087       appDiedLocked(app, app.pid, app.thread, false);
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5091            boolean fromBinderDied) {
5092        // First check if this ProcessRecord is actually active for the pid.
5093        synchronized (mPidsSelfLocked) {
5094            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5095            if (curProc != app) {
5096                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5097                return;
5098            }
5099        }
5100
5101        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5102        synchronized (stats) {
5103            stats.noteProcessDiedLocked(app.info.uid, pid);
5104        }
5105
5106        if (!app.killed) {
5107            if (!fromBinderDied) {
5108                Process.killProcessQuiet(pid);
5109            }
5110            killProcessGroup(app.uid, pid);
5111            app.killed = true;
5112        }
5113
5114        // Clean up already done if the process has been re-started.
5115        if (app.pid == pid && app.thread != null &&
5116                app.thread.asBinder() == thread.asBinder()) {
5117            boolean doLowMem = app.instrumentationClass == null;
5118            boolean doOomAdj = doLowMem;
5119            if (!app.killedByAm) {
5120                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5121                        + ") has died");
5122                mAllowLowerMemLevel = true;
5123            } else {
5124                // Note that we always want to do oom adj to update our state with the
5125                // new number of procs.
5126                mAllowLowerMemLevel = false;
5127                doLowMem = false;
5128            }
5129            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5130            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5131                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5132            handleAppDiedLocked(app, false, true);
5133
5134            if (doOomAdj) {
5135                updateOomAdjLocked();
5136            }
5137            if (doLowMem) {
5138                doLowMemReportIfNeededLocked(app);
5139            }
5140        } else if (app.pid != pid) {
5141            // A new process has already been started.
5142            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5143                    + ") has died and restarted (pid " + app.pid + ").");
5144            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5145        } else if (DEBUG_PROCESSES) {
5146            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5147                    + thread.asBinder());
5148        }
5149    }
5150
5151    /**
5152     * If a stack trace dump file is configured, dump process stack traces.
5153     * @param clearTraces causes the dump file to be erased prior to the new
5154     *    traces being written, if true; when false, the new traces will be
5155     *    appended to any existing file content.
5156     * @param firstPids of dalvik VM processes to dump stack traces for first
5157     * @param lastPids of dalvik VM processes to dump stack traces for last
5158     * @param nativeProcs optional list of native process names to dump stack crawls
5159     * @return file containing stack traces, or null if no dump file is configured
5160     */
5161    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5162            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5163        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5164        if (tracesPath == null || tracesPath.length() == 0) {
5165            return null;
5166        }
5167
5168        File tracesFile = new File(tracesPath);
5169        try {
5170            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5171            tracesFile.createNewFile();
5172            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5173        } catch (IOException e) {
5174            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5175            return null;
5176        }
5177
5178        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5179        return tracesFile;
5180    }
5181
5182    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5183            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5184        // Use a FileObserver to detect when traces finish writing.
5185        // The order of traces is considered important to maintain for legibility.
5186        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5187            @Override
5188            public synchronized void onEvent(int event, String path) { notify(); }
5189        };
5190
5191        try {
5192            observer.startWatching();
5193
5194            // First collect all of the stacks of the most important pids.
5195            if (firstPids != null) {
5196                try {
5197                    int num = firstPids.size();
5198                    for (int i = 0; i < num; i++) {
5199                        synchronized (observer) {
5200                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5201                                    + firstPids.get(i));
5202                            final long sime = SystemClock.elapsedRealtime();
5203                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5204                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5205                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5206                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5207                        }
5208                    }
5209                } catch (InterruptedException e) {
5210                    Slog.wtf(TAG, e);
5211                }
5212            }
5213
5214            // Next collect the stacks of the native pids
5215            if (nativeProcs != null) {
5216                int[] pids = Process.getPidsForCommands(nativeProcs);
5217                if (pids != null) {
5218                    for (int pid : pids) {
5219                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5220                        final long sime = SystemClock.elapsedRealtime();
5221                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5222                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5223                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5224                    }
5225                }
5226            }
5227
5228            // Lastly, measure CPU usage.
5229            if (processCpuTracker != null) {
5230                processCpuTracker.init();
5231                System.gc();
5232                processCpuTracker.update();
5233                try {
5234                    synchronized (processCpuTracker) {
5235                        processCpuTracker.wait(500); // measure over 1/2 second.
5236                    }
5237                } catch (InterruptedException e) {
5238                }
5239                processCpuTracker.update();
5240
5241                // We'll take the stack crawls of just the top apps using CPU.
5242                final int N = processCpuTracker.countWorkingStats();
5243                int numProcs = 0;
5244                for (int i=0; i<N && numProcs<5; i++) {
5245                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5246                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5247                        numProcs++;
5248                        try {
5249                            synchronized (observer) {
5250                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5251                                        + stats.pid);
5252                                final long stime = SystemClock.elapsedRealtime();
5253                                Process.sendSignal(stats.pid, 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 extra pid " + stats.pid
5256                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5257                            }
5258                        } catch (InterruptedException e) {
5259                            Slog.wtf(TAG, e);
5260                        }
5261                    } else if (DEBUG_ANR) {
5262                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5263                                + stats.pid);
5264                    }
5265                }
5266            }
5267        } finally {
5268            observer.stopWatching();
5269        }
5270    }
5271
5272    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5273        if (true || IS_USER_BUILD) {
5274            return;
5275        }
5276        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5277        if (tracesPath == null || tracesPath.length() == 0) {
5278            return;
5279        }
5280
5281        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5282        StrictMode.allowThreadDiskWrites();
5283        try {
5284            final File tracesFile = new File(tracesPath);
5285            final File tracesDir = tracesFile.getParentFile();
5286            final File tracesTmp = new File(tracesDir, "__tmp__");
5287            try {
5288                if (tracesFile.exists()) {
5289                    tracesTmp.delete();
5290                    tracesFile.renameTo(tracesTmp);
5291                }
5292                StringBuilder sb = new StringBuilder();
5293                Time tobj = new Time();
5294                tobj.set(System.currentTimeMillis());
5295                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5296                sb.append(": ");
5297                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5298                sb.append(" since ");
5299                sb.append(msg);
5300                FileOutputStream fos = new FileOutputStream(tracesFile);
5301                fos.write(sb.toString().getBytes());
5302                if (app == null) {
5303                    fos.write("\n*** No application process!".getBytes());
5304                }
5305                fos.close();
5306                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5307            } catch (IOException e) {
5308                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5309                return;
5310            }
5311
5312            if (app != null) {
5313                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5314                firstPids.add(app.pid);
5315                dumpStackTraces(tracesPath, firstPids, null, null, null);
5316            }
5317
5318            File lastTracesFile = null;
5319            File curTracesFile = null;
5320            for (int i=9; i>=0; i--) {
5321                String name = String.format(Locale.US, "slow%02d.txt", i);
5322                curTracesFile = new File(tracesDir, name);
5323                if (curTracesFile.exists()) {
5324                    if (lastTracesFile != null) {
5325                        curTracesFile.renameTo(lastTracesFile);
5326                    } else {
5327                        curTracesFile.delete();
5328                    }
5329                }
5330                lastTracesFile = curTracesFile;
5331            }
5332            tracesFile.renameTo(curTracesFile);
5333            if (tracesTmp.exists()) {
5334                tracesTmp.renameTo(tracesFile);
5335            }
5336        } finally {
5337            StrictMode.setThreadPolicy(oldPolicy);
5338        }
5339    }
5340
5341    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5342        if (!mLaunchWarningShown) {
5343            mLaunchWarningShown = true;
5344            mUiHandler.post(new Runnable() {
5345                @Override
5346                public void run() {
5347                    synchronized (ActivityManagerService.this) {
5348                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5349                        d.show();
5350                        mUiHandler.postDelayed(new Runnable() {
5351                            @Override
5352                            public void run() {
5353                                synchronized (ActivityManagerService.this) {
5354                                    d.dismiss();
5355                                    mLaunchWarningShown = false;
5356                                }
5357                            }
5358                        }, 4000);
5359                    }
5360                }
5361            });
5362        }
5363    }
5364
5365    @Override
5366    public boolean clearApplicationUserData(final String packageName,
5367            final IPackageDataObserver observer, int userId) {
5368        enforceNotIsolatedCaller("clearApplicationUserData");
5369        int uid = Binder.getCallingUid();
5370        int pid = Binder.getCallingPid();
5371        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5372                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5373
5374        final DevicePolicyManagerInternal dpmi = LocalServices
5375                .getService(DevicePolicyManagerInternal.class);
5376        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5377            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5378        }
5379
5380        long callingId = Binder.clearCallingIdentity();
5381        try {
5382            IPackageManager pm = AppGlobals.getPackageManager();
5383            int pkgUid = -1;
5384            synchronized(this) {
5385                try {
5386                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5387                } catch (RemoteException e) {
5388                }
5389                if (pkgUid == -1) {
5390                    Slog.w(TAG, "Invalid packageName: " + packageName);
5391                    if (observer != null) {
5392                        try {
5393                            observer.onRemoveCompleted(packageName, false);
5394                        } catch (RemoteException e) {
5395                            Slog.i(TAG, "Observer no longer exists.");
5396                        }
5397                    }
5398                    return false;
5399                }
5400                if (uid == pkgUid || checkComponentPermission(
5401                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5402                        pid, uid, -1, true)
5403                        == PackageManager.PERMISSION_GRANTED) {
5404                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5405                } else {
5406                    throw new SecurityException("PID " + pid + " does not have permission "
5407                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5408                                    + " of package " + packageName);
5409                }
5410
5411                // Remove all tasks match the cleared application package and user
5412                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5413                    final TaskRecord tr = mRecentTasks.get(i);
5414                    final String taskPackageName =
5415                            tr.getBaseIntent().getComponent().getPackageName();
5416                    if (tr.userId != userId) continue;
5417                    if (!taskPackageName.equals(packageName)) continue;
5418                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5419                }
5420            }
5421
5422            try {
5423                // Clear application user data
5424                pm.clearApplicationUserData(packageName, observer, userId);
5425
5426                synchronized(this) {
5427                    // Remove all permissions granted from/to this package
5428                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5429                }
5430
5431                // Remove all zen rules created by this package; revoke it's zen access.
5432                INotificationManager inm = NotificationManager.getService();
5433                inm.removeAutomaticZenRules(packageName);
5434                inm.setNotificationPolicyAccessGranted(packageName, false);
5435
5436                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437                        Uri.fromParts("package", packageName, null));
5438                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5439                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5440                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441                        null, null, 0, null, null, null, null, false, false, userId);
5442            } catch (RemoteException e) {
5443            }
5444        } finally {
5445            Binder.restoreCallingIdentity(callingId);
5446        }
5447        return true;
5448    }
5449
5450    @Override
5451    public void killBackgroundProcesses(final String packageName, int userId) {
5452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5453                != PackageManager.PERMISSION_GRANTED &&
5454                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5455                        != PackageManager.PERMISSION_GRANTED) {
5456            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5457                    + Binder.getCallingPid()
5458                    + ", uid=" + Binder.getCallingUid()
5459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5460            Slog.w(TAG, msg);
5461            throw new SecurityException(msg);
5462        }
5463
5464        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5465                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5466        long callingId = Binder.clearCallingIdentity();
5467        try {
5468            IPackageManager pm = AppGlobals.getPackageManager();
5469            synchronized(this) {
5470                int appId = -1;
5471                try {
5472                    appId = UserHandle.getAppId(
5473                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5474                } catch (RemoteException e) {
5475                }
5476                if (appId == -1) {
5477                    Slog.w(TAG, "Invalid packageName: " + packageName);
5478                    return;
5479                }
5480                killPackageProcessesLocked(packageName, appId, userId,
5481                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5482            }
5483        } finally {
5484            Binder.restoreCallingIdentity(callingId);
5485        }
5486    }
5487
5488    @Override
5489    public void killAllBackgroundProcesses() {
5490        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5491                != PackageManager.PERMISSION_GRANTED) {
5492            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5493                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5494                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5495            Slog.w(TAG, msg);
5496            throw new SecurityException(msg);
5497        }
5498
5499        final long callingId = Binder.clearCallingIdentity();
5500        try {
5501            synchronized (this) {
5502                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5503                final int NP = mProcessNames.getMap().size();
5504                for (int ip = 0; ip < NP; ip++) {
5505                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5506                    final int NA = apps.size();
5507                    for (int ia = 0; ia < NA; ia++) {
5508                        final ProcessRecord app = apps.valueAt(ia);
5509                        if (app.persistent) {
5510                            // We don't kill persistent processes.
5511                            continue;
5512                        }
5513                        if (app.removed) {
5514                            procs.add(app);
5515                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5516                            app.removed = true;
5517                            procs.add(app);
5518                        }
5519                    }
5520                }
5521
5522                final int N = procs.size();
5523                for (int i = 0; i < N; i++) {
5524                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5525                }
5526
5527                mAllowLowerMemLevel = true;
5528
5529                updateOomAdjLocked();
5530                doLowMemReportIfNeededLocked(null);
5531            }
5532        } finally {
5533            Binder.restoreCallingIdentity(callingId);
5534        }
5535    }
5536
5537    /**
5538     * Kills all background processes, except those matching any of the
5539     * specified properties.
5540     *
5541     * @param minTargetSdk the target SDK version at or above which to preserve
5542     *                     processes, or {@code -1} to ignore the target SDK
5543     * @param maxProcState the process state at or below which to preserve
5544     *                     processes, or {@code -1} to ignore the process state
5545     */
5546    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5547        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5548                != PackageManager.PERMISSION_GRANTED) {
5549            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5550                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5551                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5552            Slog.w(TAG, msg);
5553            throw new SecurityException(msg);
5554        }
5555
5556        final long callingId = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5560                final int NP = mProcessNames.getMap().size();
5561                for (int ip = 0; ip < NP; ip++) {
5562                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5563                    final int NA = apps.size();
5564                    for (int ia = 0; ia < NA; ia++) {
5565                        final ProcessRecord app = apps.valueAt(ia);
5566                        if (app.removed) {
5567                            procs.add(app);
5568                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5569                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5570                            app.removed = true;
5571                            procs.add(app);
5572                        }
5573                    }
5574                }
5575
5576                final int N = procs.size();
5577                for (int i = 0; i < N; i++) {
5578                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5579                }
5580            }
5581        } finally {
5582            Binder.restoreCallingIdentity(callingId);
5583        }
5584    }
5585
5586    @Override
5587    public void forceStopPackage(final String packageName, int userId) {
5588        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5589                != PackageManager.PERMISSION_GRANTED) {
5590            String msg = "Permission Denial: forceStopPackage() from pid="
5591                    + Binder.getCallingPid()
5592                    + ", uid=" + Binder.getCallingUid()
5593                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5594            Slog.w(TAG, msg);
5595            throw new SecurityException(msg);
5596        }
5597        final int callingPid = Binder.getCallingPid();
5598        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5599                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5600        long callingId = Binder.clearCallingIdentity();
5601        try {
5602            IPackageManager pm = AppGlobals.getPackageManager();
5603            synchronized(this) {
5604                int[] users = userId == UserHandle.USER_ALL
5605                        ? mUserController.getUsers() : new int[] { userId };
5606                for (int user : users) {
5607                    int pkgUid = -1;
5608                    try {
5609                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5610                                user);
5611                    } catch (RemoteException e) {
5612                    }
5613                    if (pkgUid == -1) {
5614                        Slog.w(TAG, "Invalid packageName: " + packageName);
5615                        continue;
5616                    }
5617                    try {
5618                        pm.setPackageStoppedState(packageName, true, user);
5619                    } catch (RemoteException e) {
5620                    } catch (IllegalArgumentException e) {
5621                        Slog.w(TAG, "Failed trying to unstop package "
5622                                + packageName + ": " + e);
5623                    }
5624                    if (mUserController.isUserRunningLocked(user, 0)) {
5625                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5626                    }
5627                }
5628            }
5629        } finally {
5630            Binder.restoreCallingIdentity(callingId);
5631        }
5632    }
5633
5634    @Override
5635    public void addPackageDependency(String packageName) {
5636        synchronized (this) {
5637            int callingPid = Binder.getCallingPid();
5638            if (callingPid == Process.myPid()) {
5639                //  Yeah, um, no.
5640                return;
5641            }
5642            ProcessRecord proc;
5643            synchronized (mPidsSelfLocked) {
5644                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5645            }
5646            if (proc != null) {
5647                if (proc.pkgDeps == null) {
5648                    proc.pkgDeps = new ArraySet<String>(1);
5649                }
5650                proc.pkgDeps.add(packageName);
5651            }
5652        }
5653    }
5654
5655    /*
5656     * The pkg name and app id have to be specified.
5657     */
5658    @Override
5659    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5660        if (pkg == null) {
5661            return;
5662        }
5663        // Make sure the uid is valid.
5664        if (appid < 0) {
5665            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5666            return;
5667        }
5668        int callerUid = Binder.getCallingUid();
5669        // Only the system server can kill an application
5670        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5671            // Post an aysnc message to kill the application
5672            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5673            msg.arg1 = appid;
5674            msg.arg2 = 0;
5675            Bundle bundle = new Bundle();
5676            bundle.putString("pkg", pkg);
5677            bundle.putString("reason", reason);
5678            msg.obj = bundle;
5679            mHandler.sendMessage(msg);
5680        } else {
5681            throw new SecurityException(callerUid + " cannot kill pkg: " +
5682                    pkg);
5683        }
5684    }
5685
5686    @Override
5687    public void closeSystemDialogs(String reason) {
5688        enforceNotIsolatedCaller("closeSystemDialogs");
5689
5690        final int pid = Binder.getCallingPid();
5691        final int uid = Binder.getCallingUid();
5692        final long origId = Binder.clearCallingIdentity();
5693        try {
5694            synchronized (this) {
5695                // Only allow this from foreground processes, so that background
5696                // applications can't abuse it to prevent system UI from being shown.
5697                if (uid >= Process.FIRST_APPLICATION_UID) {
5698                    ProcessRecord proc;
5699                    synchronized (mPidsSelfLocked) {
5700                        proc = mPidsSelfLocked.get(pid);
5701                    }
5702                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5703                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5704                                + " from background process " + proc);
5705                        return;
5706                    }
5707                }
5708                closeSystemDialogsLocked(reason);
5709            }
5710        } finally {
5711            Binder.restoreCallingIdentity(origId);
5712        }
5713    }
5714
5715    void closeSystemDialogsLocked(String reason) {
5716        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5717        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5718                | Intent.FLAG_RECEIVER_FOREGROUND);
5719        if (reason != null) {
5720            intent.putExtra("reason", reason);
5721        }
5722        mWindowManager.closeSystemDialogs(reason);
5723
5724        mStackSupervisor.closeSystemDialogsLocked();
5725
5726        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5727                AppOpsManager.OP_NONE, null, false, false,
5728                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5729    }
5730
5731    @Override
5732    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5733        enforceNotIsolatedCaller("getProcessMemoryInfo");
5734        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5735        for (int i=pids.length-1; i>=0; i--) {
5736            ProcessRecord proc;
5737            int oomAdj;
5738            synchronized (this) {
5739                synchronized (mPidsSelfLocked) {
5740                    proc = mPidsSelfLocked.get(pids[i]);
5741                    oomAdj = proc != null ? proc.setAdj : 0;
5742                }
5743            }
5744            infos[i] = new Debug.MemoryInfo();
5745            Debug.getMemoryInfo(pids[i], infos[i]);
5746            if (proc != null) {
5747                synchronized (this) {
5748                    if (proc.thread != null && proc.setAdj == oomAdj) {
5749                        // Record this for posterity if the process has been stable.
5750                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5751                                infos[i].getTotalUss(), false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return infos;
5757    }
5758
5759    @Override
5760    public long[] getProcessPss(int[] pids) {
5761        enforceNotIsolatedCaller("getProcessPss");
5762        long[] pss = new long[pids.length];
5763        for (int i=pids.length-1; i>=0; i--) {
5764            ProcessRecord proc;
5765            int oomAdj;
5766            synchronized (this) {
5767                synchronized (mPidsSelfLocked) {
5768                    proc = mPidsSelfLocked.get(pids[i]);
5769                    oomAdj = proc != null ? proc.setAdj : 0;
5770                }
5771            }
5772            long[] tmpUss = new long[1];
5773            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5774            if (proc != null) {
5775                synchronized (this) {
5776                    if (proc.thread != null && proc.setAdj == oomAdj) {
5777                        // Record this for posterity if the process has been stable.
5778                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5779                    }
5780                }
5781            }
5782        }
5783        return pss;
5784    }
5785
5786    @Override
5787    public void killApplicationProcess(String processName, int uid) {
5788        if (processName == null) {
5789            return;
5790        }
5791
5792        int callerUid = Binder.getCallingUid();
5793        // Only the system server can kill an application
5794        if (callerUid == Process.SYSTEM_UID) {
5795            synchronized (this) {
5796                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5797                if (app != null && app.thread != null) {
5798                    try {
5799                        app.thread.scheduleSuicide();
5800                    } catch (RemoteException e) {
5801                        // If the other end already died, then our work here is done.
5802                    }
5803                } else {
5804                    Slog.w(TAG, "Process/uid not found attempting kill of "
5805                            + processName + " / " + uid);
5806                }
5807            }
5808        } else {
5809            throw new SecurityException(callerUid + " cannot kill app process: " +
5810                    processName);
5811        }
5812    }
5813
5814    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5815        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5816                false, true, false, false, UserHandle.getUserId(uid), reason);
5817        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5818                Uri.fromParts("package", packageName, null));
5819        if (!mProcessesReady) {
5820            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5821                    | Intent.FLAG_RECEIVER_FOREGROUND);
5822        }
5823        intent.putExtra(Intent.EXTRA_UID, uid);
5824        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5825        broadcastIntentLocked(null, null, intent,
5826                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5827                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5828    }
5829
5830
5831    private final boolean killPackageProcessesLocked(String packageName, int appId,
5832            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5833            boolean doit, boolean evenPersistent, String reason) {
5834        ArrayList<ProcessRecord> procs = new ArrayList<>();
5835
5836        // Remove all processes this package may have touched: all with the
5837        // same UID (except for the system or root user), and all whose name
5838        // matches the package name.
5839        final int NP = mProcessNames.getMap().size();
5840        for (int ip=0; ip<NP; ip++) {
5841            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5842            final int NA = apps.size();
5843            for (int ia=0; ia<NA; ia++) {
5844                ProcessRecord app = apps.valueAt(ia);
5845                if (app.persistent && !evenPersistent) {
5846                    // we don't kill persistent processes
5847                    continue;
5848                }
5849                if (app.removed) {
5850                    if (doit) {
5851                        procs.add(app);
5852                    }
5853                    continue;
5854                }
5855
5856                // Skip process if it doesn't meet our oom adj requirement.
5857                if (app.setAdj < minOomAdj) {
5858                    continue;
5859                }
5860
5861                // If no package is specified, we call all processes under the
5862                // give user id.
5863                if (packageName == null) {
5864                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5865                        continue;
5866                    }
5867                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5868                        continue;
5869                    }
5870                // Package has been specified, we want to hit all processes
5871                // that match it.  We need to qualify this by the processes
5872                // that are running under the specified app and user ID.
5873                } else {
5874                    final boolean isDep = app.pkgDeps != null
5875                            && app.pkgDeps.contains(packageName);
5876                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5877                        continue;
5878                    }
5879                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5880                        continue;
5881                    }
5882                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5883                        continue;
5884                    }
5885                }
5886
5887                // Process has passed all conditions, kill it!
5888                if (!doit) {
5889                    return true;
5890                }
5891                app.removed = true;
5892                procs.add(app);
5893            }
5894        }
5895
5896        int N = procs.size();
5897        for (int i=0; i<N; i++) {
5898            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5899        }
5900        updateOomAdjLocked();
5901        return N > 0;
5902    }
5903
5904    private void cleanupDisabledPackageComponentsLocked(
5905            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5906
5907        Set<String> disabledClasses = null;
5908        boolean packageDisabled = false;
5909        IPackageManager pm = AppGlobals.getPackageManager();
5910
5911        if (changedClasses == null) {
5912            // Nothing changed...
5913            return;
5914        }
5915
5916        // Determine enable/disable state of the package and its components.
5917        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5918        for (int i = changedClasses.length - 1; i >= 0; i--) {
5919            final String changedClass = changedClasses[i];
5920
5921            if (changedClass.equals(packageName)) {
5922                try {
5923                    // Entire package setting changed
5924                    enabled = pm.getApplicationEnabledSetting(packageName,
5925                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5926                } catch (Exception e) {
5927                    // No such package/component; probably racing with uninstall.  In any
5928                    // event it means we have nothing further to do here.
5929                    return;
5930                }
5931                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5932                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5933                if (packageDisabled) {
5934                    // Entire package is disabled.
5935                    // No need to continue to check component states.
5936                    disabledClasses = null;
5937                    break;
5938                }
5939            } else {
5940                try {
5941                    enabled = pm.getComponentEnabledSetting(
5942                            new ComponentName(packageName, changedClass),
5943                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5944                } catch (Exception e) {
5945                    // As above, probably racing with uninstall.
5946                    return;
5947                }
5948                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5949                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5950                    if (disabledClasses == null) {
5951                        disabledClasses = new ArraySet<>(changedClasses.length);
5952                    }
5953                    disabledClasses.add(changedClass);
5954                }
5955            }
5956        }
5957
5958        if (!packageDisabled && disabledClasses == null) {
5959            // Nothing to do here...
5960            return;
5961        }
5962
5963        // Clean-up disabled activities.
5964        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5965                packageName, disabledClasses, true, false, userId) && mBooted) {
5966            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5967            mStackSupervisor.scheduleIdleLocked();
5968        }
5969
5970        // Clean-up disabled tasks
5971        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5972
5973        // Clean-up disabled services.
5974        mServices.bringDownDisabledPackageServicesLocked(
5975                packageName, disabledClasses, userId, false, killProcess, true);
5976
5977        // Clean-up disabled providers.
5978        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5979        mProviderMap.collectPackageProvidersLocked(
5980                packageName, disabledClasses, true, false, userId, providers);
5981        for (int i = providers.size() - 1; i >= 0; i--) {
5982            removeDyingProviderLocked(null, providers.get(i), true);
5983        }
5984
5985        // Clean-up disabled broadcast receivers.
5986        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5987            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5988                    packageName, disabledClasses, userId, true);
5989        }
5990
5991    }
5992
5993    final boolean clearBroadcastQueueForUserLocked(int userId) {
5994        boolean didSomething = false;
5995        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5996            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5997                    null, null, userId, true);
5998        }
5999        return didSomething;
6000    }
6001
6002    final boolean forceStopPackageLocked(String packageName, int appId,
6003            boolean callerWillRestart, boolean purgeCache, boolean doit,
6004            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6005        int i;
6006
6007        if (userId == UserHandle.USER_ALL && packageName == null) {
6008            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6009        }
6010
6011        if (appId < 0 && packageName != null) {
6012            try {
6013                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6014                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6015            } catch (RemoteException e) {
6016            }
6017        }
6018
6019        if (doit) {
6020            if (packageName != null) {
6021                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6022                        + " user=" + userId + ": " + reason);
6023            } else {
6024                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6025            }
6026
6027            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6028        }
6029
6030        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6031                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6032                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6033
6034        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6035                packageName, null, doit, evenPersistent, userId)) {
6036            if (!doit) {
6037                return true;
6038            }
6039            didSomething = true;
6040        }
6041
6042        if (mServices.bringDownDisabledPackageServicesLocked(
6043                packageName, null, userId, evenPersistent, true, doit)) {
6044            if (!doit) {
6045                return true;
6046            }
6047            didSomething = true;
6048        }
6049
6050        if (packageName == null) {
6051            // Remove all sticky broadcasts from this user.
6052            mStickyBroadcasts.remove(userId);
6053        }
6054
6055        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6056        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6057                userId, providers)) {
6058            if (!doit) {
6059                return true;
6060            }
6061            didSomething = true;
6062        }
6063        for (i = providers.size() - 1; i >= 0; i--) {
6064            removeDyingProviderLocked(null, providers.get(i), true);
6065        }
6066
6067        // Remove transient permissions granted from/to this package/user
6068        removeUriPermissionsForPackageLocked(packageName, userId, false);
6069
6070        if (doit) {
6071            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6072                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6073                        packageName, null, userId, doit);
6074            }
6075        }
6076
6077        if (packageName == null || uninstalling) {
6078            // Remove pending intents.  For now we only do this when force
6079            // stopping users, because we have some problems when doing this
6080            // for packages -- app widgets are not currently cleaned up for
6081            // such packages, so they can be left with bad pending intents.
6082            if (mIntentSenderRecords.size() > 0) {
6083                Iterator<WeakReference<PendingIntentRecord>> it
6084                        = mIntentSenderRecords.values().iterator();
6085                while (it.hasNext()) {
6086                    WeakReference<PendingIntentRecord> wpir = it.next();
6087                    if (wpir == null) {
6088                        it.remove();
6089                        continue;
6090                    }
6091                    PendingIntentRecord pir = wpir.get();
6092                    if (pir == null) {
6093                        it.remove();
6094                        continue;
6095                    }
6096                    if (packageName == null) {
6097                        // Stopping user, remove all objects for the user.
6098                        if (pir.key.userId != userId) {
6099                            // Not the same user, skip it.
6100                            continue;
6101                        }
6102                    } else {
6103                        if (UserHandle.getAppId(pir.uid) != appId) {
6104                            // Different app id, skip it.
6105                            continue;
6106                        }
6107                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6108                            // Different user, skip it.
6109                            continue;
6110                        }
6111                        if (!pir.key.packageName.equals(packageName)) {
6112                            // Different package, skip it.
6113                            continue;
6114                        }
6115                    }
6116                    if (!doit) {
6117                        return true;
6118                    }
6119                    didSomething = true;
6120                    it.remove();
6121                    pir.canceled = true;
6122                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6123                        pir.key.activity.pendingResults.remove(pir.ref);
6124                    }
6125                }
6126            }
6127        }
6128
6129        if (doit) {
6130            if (purgeCache && packageName != null) {
6131                AttributeCache ac = AttributeCache.instance();
6132                if (ac != null) {
6133                    ac.removePackage(packageName);
6134                }
6135            }
6136            if (mBooted) {
6137                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6138                mStackSupervisor.scheduleIdleLocked();
6139            }
6140        }
6141
6142        return didSomething;
6143    }
6144
6145    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6146        ProcessRecord old = mProcessNames.remove(name, uid);
6147        if (old != null) {
6148            old.uidRecord.numProcs--;
6149            if (old.uidRecord.numProcs == 0) {
6150                // No more processes using this uid, tell clients it is gone.
6151                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6152                        "No more processes in " + old.uidRecord);
6153                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6154                mActiveUids.remove(uid);
6155                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6156            }
6157            old.uidRecord = null;
6158        }
6159        mIsolatedProcesses.remove(uid);
6160        return old;
6161    }
6162
6163    private final void addProcessNameLocked(ProcessRecord proc) {
6164        // We shouldn't already have a process under this name, but just in case we
6165        // need to clean up whatever may be there now.
6166        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6167        if (old == proc && proc.persistent) {
6168            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6169            Slog.w(TAG, "Re-adding persistent process " + proc);
6170        } else if (old != null) {
6171            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6172        }
6173        UidRecord uidRec = mActiveUids.get(proc.uid);
6174        if (uidRec == null) {
6175            uidRec = new UidRecord(proc.uid);
6176            // This is the first appearance of the uid, report it now!
6177            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6178                    "Creating new process uid: " + uidRec);
6179            mActiveUids.put(proc.uid, uidRec);
6180            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6181            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6182        }
6183        proc.uidRecord = uidRec;
6184        uidRec.numProcs++;
6185        mProcessNames.put(proc.processName, proc.uid, proc);
6186        if (proc.isolated) {
6187            mIsolatedProcesses.put(proc.uid, proc);
6188        }
6189    }
6190
6191    boolean removeProcessLocked(ProcessRecord app,
6192            boolean callerWillRestart, boolean allowRestart, String reason) {
6193        final String name = app.processName;
6194        final int uid = app.uid;
6195        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6196            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6197
6198        ProcessRecord old = mProcessNames.get(name, uid);
6199        if (old != app) {
6200            // This process is no longer active, so nothing to do.
6201            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6202            return false;
6203        }
6204        removeProcessNameLocked(name, uid);
6205        if (mHeavyWeightProcess == app) {
6206            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6207                    mHeavyWeightProcess.userId, 0));
6208            mHeavyWeightProcess = null;
6209        }
6210        boolean needRestart = false;
6211        if (app.pid > 0 && app.pid != MY_PID) {
6212            int pid = app.pid;
6213            synchronized (mPidsSelfLocked) {
6214                mPidsSelfLocked.remove(pid);
6215                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6216            }
6217            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6218            if (app.isolated) {
6219                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6220            }
6221            boolean willRestart = false;
6222            if (app.persistent && !app.isolated) {
6223                if (!callerWillRestart) {
6224                    willRestart = true;
6225                } else {
6226                    needRestart = true;
6227                }
6228            }
6229            app.kill(reason, true);
6230            handleAppDiedLocked(app, willRestart, allowRestart);
6231            if (willRestart) {
6232                removeLruProcessLocked(app);
6233                addAppLocked(app.info, false, null /* ABI override */);
6234            }
6235        } else {
6236            mRemovedProcesses.add(app);
6237        }
6238
6239        return needRestart;
6240    }
6241
6242    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6243        cleanupAppInLaunchingProvidersLocked(app, true);
6244        removeProcessLocked(app, false, true, "timeout publishing content providers");
6245    }
6246
6247    private final void processStartTimedOutLocked(ProcessRecord app) {
6248        final int pid = app.pid;
6249        boolean gone = false;
6250        synchronized (mPidsSelfLocked) {
6251            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6252            if (knownApp != null && knownApp.thread == null) {
6253                mPidsSelfLocked.remove(pid);
6254                gone = true;
6255            }
6256        }
6257
6258        if (gone) {
6259            Slog.w(TAG, "Process " + app + " failed to attach");
6260            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6261                    pid, app.uid, app.processName);
6262            removeProcessNameLocked(app.processName, app.uid);
6263            if (mHeavyWeightProcess == app) {
6264                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6265                        mHeavyWeightProcess.userId, 0));
6266                mHeavyWeightProcess = null;
6267            }
6268            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6269            if (app.isolated) {
6270                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6271            }
6272            // Take care of any launching providers waiting for this process.
6273            cleanupAppInLaunchingProvidersLocked(app, true);
6274            // Take care of any services that are waiting for the process.
6275            mServices.processStartTimedOutLocked(app);
6276            app.kill("start timeout", true);
6277            removeLruProcessLocked(app);
6278            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6279                Slog.w(TAG, "Unattached app died before backup, skipping");
6280                try {
6281                    IBackupManager bm = IBackupManager.Stub.asInterface(
6282                            ServiceManager.getService(Context.BACKUP_SERVICE));
6283                    bm.agentDisconnected(app.info.packageName);
6284                } catch (RemoteException e) {
6285                    // Can't happen; the backup manager is local
6286                }
6287            }
6288            if (isPendingBroadcastProcessLocked(pid)) {
6289                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6290                skipPendingBroadcastLocked(pid);
6291            }
6292        } else {
6293            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6294        }
6295    }
6296
6297    private final boolean attachApplicationLocked(IApplicationThread thread,
6298            int pid) {
6299
6300        // Find the application record that is being attached...  either via
6301        // the pid if we are running in multiple processes, or just pull the
6302        // next app record if we are emulating process with anonymous threads.
6303        ProcessRecord app;
6304        if (pid != MY_PID && pid >= 0) {
6305            synchronized (mPidsSelfLocked) {
6306                app = mPidsSelfLocked.get(pid);
6307            }
6308        } else {
6309            app = null;
6310        }
6311
6312        if (app == null) {
6313            Slog.w(TAG, "No pending application record for pid " + pid
6314                    + " (IApplicationThread " + thread + "); dropping process");
6315            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6316            if (pid > 0 && pid != MY_PID) {
6317                Process.killProcessQuiet(pid);
6318                //TODO: killProcessGroup(app.info.uid, pid);
6319            } else {
6320                try {
6321                    thread.scheduleExit();
6322                } catch (Exception e) {
6323                    // Ignore exceptions.
6324                }
6325            }
6326            return false;
6327        }
6328
6329        // If this application record is still attached to a previous
6330        // process, clean it up now.
6331        if (app.thread != null) {
6332            handleAppDiedLocked(app, true, true);
6333        }
6334
6335        // Tell the process all about itself.
6336
6337        if (DEBUG_ALL) Slog.v(
6338                TAG, "Binding process pid " + pid + " to record " + app);
6339
6340        final String processName = app.processName;
6341        try {
6342            AppDeathRecipient adr = new AppDeathRecipient(
6343                    app, pid, thread);
6344            thread.asBinder().linkToDeath(adr, 0);
6345            app.deathRecipient = adr;
6346        } catch (RemoteException e) {
6347            app.resetPackageList(mProcessStats);
6348            startProcessLocked(app, "link fail", processName);
6349            return false;
6350        }
6351
6352        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6353
6354        app.makeActive(thread, mProcessStats);
6355        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6356        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6357        app.forcingToForeground = null;
6358        updateProcessForegroundLocked(app, false, false);
6359        app.hasShownUi = false;
6360        app.debugging = false;
6361        app.cached = false;
6362        app.killedByAm = false;
6363
6364        // We carefully use the same state that PackageManager uses for
6365        // filtering, since we use this flag to decide if we need to install
6366        // providers when user is unlocked later
6367        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6368
6369        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6370
6371        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6372        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6373
6374        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6375            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6376            msg.obj = app;
6377            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6378        }
6379
6380        if (!normalMode) {
6381            Slog.i(TAG, "Launching preboot mode app: " + app);
6382        }
6383
6384        if (DEBUG_ALL) Slog.v(
6385            TAG, "New app record " + app
6386            + " thread=" + thread.asBinder() + " pid=" + pid);
6387        try {
6388            int testMode = IApplicationThread.DEBUG_OFF;
6389            if (mDebugApp != null && mDebugApp.equals(processName)) {
6390                testMode = mWaitForDebugger
6391                    ? IApplicationThread.DEBUG_WAIT
6392                    : IApplicationThread.DEBUG_ON;
6393                app.debugging = true;
6394                if (mDebugTransient) {
6395                    mDebugApp = mOrigDebugApp;
6396                    mWaitForDebugger = mOrigWaitForDebugger;
6397                }
6398            }
6399            String profileFile = app.instrumentationProfileFile;
6400            ParcelFileDescriptor profileFd = null;
6401            int samplingInterval = 0;
6402            boolean profileAutoStop = false;
6403            if (mProfileApp != null && mProfileApp.equals(processName)) {
6404                mProfileProc = app;
6405                profileFile = mProfileFile;
6406                profileFd = mProfileFd;
6407                samplingInterval = mSamplingInterval;
6408                profileAutoStop = mAutoStopProfiler;
6409            }
6410            boolean enableTrackAllocation = false;
6411            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6412                enableTrackAllocation = true;
6413                mTrackAllocationApp = null;
6414            }
6415
6416            // If the app is being launched for restore or full backup, set it up specially
6417            boolean isRestrictedBackupMode = false;
6418            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6419                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6420                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6421                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6422                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6423            }
6424
6425            if (app.instrumentationClass != null) {
6426                notifyPackageUse(app.instrumentationClass.getPackageName(),
6427                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6428            }
6429            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6430                    + processName + " with config " + mConfiguration);
6431            ApplicationInfo appInfo = app.instrumentationInfo != null
6432                    ? app.instrumentationInfo : app.info;
6433            app.compat = compatibilityInfoForPackageLocked(appInfo);
6434            if (profileFd != null) {
6435                profileFd = profileFd.dup();
6436            }
6437            ProfilerInfo profilerInfo = profileFile == null ? null
6438                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6439            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6440                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6441                    app.instrumentationUiAutomationConnection, testMode,
6442                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6443                    isRestrictedBackupMode || !normalMode, app.persistent,
6444                    new Configuration(mConfiguration), app.compat,
6445                    getCommonServicesLocked(app.isolated),
6446                    mCoreSettingsObserver.getCoreSettingsLocked());
6447            updateLruProcessLocked(app, false, null);
6448            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6449        } catch (Exception e) {
6450            // todo: Yikes!  What should we do?  For now we will try to
6451            // start another process, but that could easily get us in
6452            // an infinite loop of restarting processes...
6453            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6454
6455            app.resetPackageList(mProcessStats);
6456            app.unlinkDeathRecipient();
6457            startProcessLocked(app, "bind fail", processName);
6458            return false;
6459        }
6460
6461        // Remove this record from the list of starting applications.
6462        mPersistentStartingProcesses.remove(app);
6463        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6464                "Attach application locked removing on hold: " + app);
6465        mProcessesOnHold.remove(app);
6466
6467        boolean badApp = false;
6468        boolean didSomething = false;
6469
6470        // See if the top visible activity is waiting to run in this process...
6471        if (normalMode) {
6472            try {
6473                if (mStackSupervisor.attachApplicationLocked(app)) {
6474                    didSomething = true;
6475                }
6476            } catch (Exception e) {
6477                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6478                badApp = true;
6479            }
6480        }
6481
6482        // Find any services that should be running in this process...
6483        if (!badApp) {
6484            try {
6485                didSomething |= mServices.attachApplicationLocked(app, processName);
6486            } catch (Exception e) {
6487                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6488                badApp = true;
6489            }
6490        }
6491
6492        // Check if a next-broadcast receiver is in this process...
6493        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6494            try {
6495                didSomething |= sendPendingBroadcastsLocked(app);
6496            } catch (Exception e) {
6497                // If the app died trying to launch the receiver we declare it 'bad'
6498                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6499                badApp = true;
6500            }
6501        }
6502
6503        // Check whether the next backup agent is in this process...
6504        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6505            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6506                    "New app is backup target, launching agent for " + app);
6507            notifyPackageUse(mBackupTarget.appInfo.packageName,
6508                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6509            try {
6510                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6511                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6512                        mBackupTarget.backupMode);
6513            } catch (Exception e) {
6514                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6515                badApp = true;
6516            }
6517        }
6518
6519        if (badApp) {
6520            app.kill("error during init", true);
6521            handleAppDiedLocked(app, false, true);
6522            return false;
6523        }
6524
6525        if (!didSomething) {
6526            updateOomAdjLocked();
6527        }
6528
6529        return true;
6530    }
6531
6532    @Override
6533    public final void attachApplication(IApplicationThread thread) {
6534        synchronized (this) {
6535            int callingPid = Binder.getCallingPid();
6536            final long origId = Binder.clearCallingIdentity();
6537            attachApplicationLocked(thread, callingPid);
6538            Binder.restoreCallingIdentity(origId);
6539        }
6540    }
6541
6542    @Override
6543    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6544        final long origId = Binder.clearCallingIdentity();
6545        synchronized (this) {
6546            ActivityStack stack = ActivityRecord.getStackLocked(token);
6547            if (stack != null) {
6548                ActivityRecord r =
6549                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6550                if (stopProfiling) {
6551                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6552                        try {
6553                            mProfileFd.close();
6554                        } catch (IOException e) {
6555                        }
6556                        clearProfilerLocked();
6557                    }
6558                }
6559            }
6560        }
6561        Binder.restoreCallingIdentity(origId);
6562    }
6563
6564    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6565        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6566                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6567    }
6568
6569    void enableScreenAfterBoot() {
6570        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6571                SystemClock.uptimeMillis());
6572        mWindowManager.enableScreenAfterBoot();
6573
6574        synchronized (this) {
6575            updateEventDispatchingLocked();
6576        }
6577    }
6578
6579    @Override
6580    public void showBootMessage(final CharSequence msg, final boolean always) {
6581        if (Binder.getCallingUid() != Process.myUid()) {
6582            // These days only the core system can call this, so apps can't get in
6583            // the way of what we show about running them.
6584        }
6585        mWindowManager.showBootMessage(msg, always);
6586    }
6587
6588    @Override
6589    public void keyguardWaitingForActivityDrawn() {
6590        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6591        final long token = Binder.clearCallingIdentity();
6592        try {
6593            synchronized (this) {
6594                if (DEBUG_LOCKSCREEN) logLockScreen("");
6595                mWindowManager.keyguardWaitingForActivityDrawn();
6596                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6597                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6598                    updateSleepIfNeededLocked();
6599                }
6600            }
6601        } finally {
6602            Binder.restoreCallingIdentity(token);
6603        }
6604    }
6605
6606    @Override
6607    public void keyguardGoingAway(int flags) {
6608        enforceNotIsolatedCaller("keyguardGoingAway");
6609        final long token = Binder.clearCallingIdentity();
6610        try {
6611            synchronized (this) {
6612                if (DEBUG_LOCKSCREEN) logLockScreen("");
6613                mWindowManager.keyguardGoingAway(flags);
6614                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6615                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6616                    updateSleepIfNeededLocked();
6617
6618                    // Some stack visibility might change (e.g. docked stack)
6619                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6620                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6621                }
6622            }
6623        } finally {
6624            Binder.restoreCallingIdentity(token);
6625        }
6626    }
6627
6628    final void finishBooting() {
6629        synchronized (this) {
6630            if (!mBootAnimationComplete) {
6631                mCallFinishBooting = true;
6632                return;
6633            }
6634            mCallFinishBooting = false;
6635        }
6636
6637        ArraySet<String> completedIsas = new ArraySet<String>();
6638        for (String abi : Build.SUPPORTED_ABIS) {
6639            Process.establishZygoteConnectionForAbi(abi);
6640            final String instructionSet = VMRuntime.getInstructionSet(abi);
6641            if (!completedIsas.contains(instructionSet)) {
6642                try {
6643                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6644                } catch (InstallerException e) {
6645                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6646                            e.getMessage() +")");
6647                }
6648                completedIsas.add(instructionSet);
6649            }
6650        }
6651
6652        IntentFilter pkgFilter = new IntentFilter();
6653        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6654        pkgFilter.addDataScheme("package");
6655        mContext.registerReceiver(new BroadcastReceiver() {
6656            @Override
6657            public void onReceive(Context context, Intent intent) {
6658                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6659                if (pkgs != null) {
6660                    for (String pkg : pkgs) {
6661                        synchronized (ActivityManagerService.this) {
6662                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6663                                    0, "query restart")) {
6664                                setResultCode(Activity.RESULT_OK);
6665                                return;
6666                            }
6667                        }
6668                    }
6669                }
6670            }
6671        }, pkgFilter);
6672
6673        IntentFilter dumpheapFilter = new IntentFilter();
6674        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6675        mContext.registerReceiver(new BroadcastReceiver() {
6676            @Override
6677            public void onReceive(Context context, Intent intent) {
6678                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6679                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6680                } else {
6681                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6682                }
6683            }
6684        }, dumpheapFilter);
6685
6686        // Let system services know.
6687        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6688
6689        synchronized (this) {
6690            // Ensure that any processes we had put on hold are now started
6691            // up.
6692            final int NP = mProcessesOnHold.size();
6693            if (NP > 0) {
6694                ArrayList<ProcessRecord> procs =
6695                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6696                for (int ip=0; ip<NP; ip++) {
6697                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6698                            + procs.get(ip));
6699                    startProcessLocked(procs.get(ip), "on-hold", null);
6700                }
6701            }
6702
6703            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6704                // Start looking for apps that are abusing wake locks.
6705                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6706                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6707                // Tell anyone interested that we are done booting!
6708                SystemProperties.set("sys.boot_completed", "1");
6709
6710                // And trigger dev.bootcomplete if we are not showing encryption progress
6711                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6712                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6713                    SystemProperties.set("dev.bootcomplete", "1");
6714                }
6715                mUserController.sendBootCompletedLocked(
6716                        new IIntentReceiver.Stub() {
6717                            @Override
6718                            public void performReceive(Intent intent, int resultCode,
6719                                    String data, Bundle extras, boolean ordered,
6720                                    boolean sticky, int sendingUser) {
6721                                synchronized (ActivityManagerService.this) {
6722                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6723                                            true, false);
6724                                }
6725                            }
6726                        });
6727                scheduleStartProfilesLocked();
6728            }
6729        }
6730    }
6731
6732    @Override
6733    public void bootAnimationComplete() {
6734        final boolean callFinishBooting;
6735        synchronized (this) {
6736            callFinishBooting = mCallFinishBooting;
6737            mBootAnimationComplete = true;
6738        }
6739        if (callFinishBooting) {
6740            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6741            finishBooting();
6742            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6743        }
6744    }
6745
6746    final void ensureBootCompleted() {
6747        boolean booting;
6748        boolean enableScreen;
6749        synchronized (this) {
6750            booting = mBooting;
6751            mBooting = false;
6752            enableScreen = !mBooted;
6753            mBooted = true;
6754        }
6755
6756        if (booting) {
6757            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6758            finishBooting();
6759            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6760        }
6761
6762        if (enableScreen) {
6763            enableScreenAfterBoot();
6764        }
6765    }
6766
6767    @Override
6768    public final void activityResumed(IBinder token) {
6769        final long origId = Binder.clearCallingIdentity();
6770        synchronized(this) {
6771            ActivityStack stack = ActivityRecord.getStackLocked(token);
6772            if (stack != null) {
6773                stack.activityResumedLocked(token);
6774            }
6775        }
6776        Binder.restoreCallingIdentity(origId);
6777    }
6778
6779    @Override
6780    public final void activityPaused(IBinder token) {
6781        final long origId = Binder.clearCallingIdentity();
6782        synchronized(this) {
6783            ActivityStack stack = ActivityRecord.getStackLocked(token);
6784            if (stack != null) {
6785                stack.activityPausedLocked(token, false);
6786            }
6787        }
6788        Binder.restoreCallingIdentity(origId);
6789    }
6790
6791    @Override
6792    public final void activityStopped(IBinder token, Bundle icicle,
6793            PersistableBundle persistentState, CharSequence description) {
6794        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6795
6796        // Refuse possible leaked file descriptors
6797        if (icicle != null && icicle.hasFileDescriptors()) {
6798            throw new IllegalArgumentException("File descriptors passed in Bundle");
6799        }
6800
6801        final long origId = Binder.clearCallingIdentity();
6802
6803        synchronized (this) {
6804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6805            if (r != null) {
6806                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6807            }
6808        }
6809
6810        trimApplications();
6811
6812        Binder.restoreCallingIdentity(origId);
6813    }
6814
6815    @Override
6816    public final void activityDestroyed(IBinder token) {
6817        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6818        synchronized (this) {
6819            ActivityStack stack = ActivityRecord.getStackLocked(token);
6820            if (stack != null) {
6821                stack.activityDestroyedLocked(token, "activityDestroyed");
6822            }
6823        }
6824    }
6825
6826    @Override
6827    public final void activityRelaunched(IBinder token) {
6828        final long origId = Binder.clearCallingIdentity();
6829        synchronized (this) {
6830            mStackSupervisor.activityRelaunchedLocked(token);
6831        }
6832        Binder.restoreCallingIdentity(origId);
6833    }
6834
6835    @Override
6836    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6837            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6838        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6839                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6840        synchronized (this) {
6841            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6842            if (record == null) {
6843                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6844                        + "found for: " + token);
6845            }
6846            record.setSizeConfigurations(horizontalSizeConfiguration,
6847                    verticalSizeConfigurations, smallestSizeConfigurations);
6848        }
6849    }
6850
6851    @Override
6852    public final void backgroundResourcesReleased(IBinder token) {
6853        final long origId = Binder.clearCallingIdentity();
6854        try {
6855            synchronized (this) {
6856                ActivityStack stack = ActivityRecord.getStackLocked(token);
6857                if (stack != null) {
6858                    stack.backgroundResourcesReleased();
6859                }
6860            }
6861        } finally {
6862            Binder.restoreCallingIdentity(origId);
6863        }
6864    }
6865
6866    @Override
6867    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6868        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6869    }
6870
6871    @Override
6872    public final void notifyEnterAnimationComplete(IBinder token) {
6873        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6874    }
6875
6876    @Override
6877    public String getCallingPackage(IBinder token) {
6878        synchronized (this) {
6879            ActivityRecord r = getCallingRecordLocked(token);
6880            return r != null ? r.info.packageName : null;
6881        }
6882    }
6883
6884    @Override
6885    public ComponentName getCallingActivity(IBinder token) {
6886        synchronized (this) {
6887            ActivityRecord r = getCallingRecordLocked(token);
6888            return r != null ? r.intent.getComponent() : null;
6889        }
6890    }
6891
6892    private ActivityRecord getCallingRecordLocked(IBinder token) {
6893        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6894        if (r == null) {
6895            return null;
6896        }
6897        return r.resultTo;
6898    }
6899
6900    @Override
6901    public ComponentName getActivityClassForToken(IBinder token) {
6902        synchronized(this) {
6903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6904            if (r == null) {
6905                return null;
6906            }
6907            return r.intent.getComponent();
6908        }
6909    }
6910
6911    @Override
6912    public String getPackageForToken(IBinder token) {
6913        synchronized(this) {
6914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6915            if (r == null) {
6916                return null;
6917            }
6918            return r.packageName;
6919        }
6920    }
6921
6922    @Override
6923    public boolean isRootVoiceInteraction(IBinder token) {
6924        synchronized(this) {
6925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926            if (r == null) {
6927                return false;
6928            }
6929            return r.rootVoiceInteraction;
6930        }
6931    }
6932
6933    @Override
6934    public IIntentSender getIntentSender(int type,
6935            String packageName, IBinder token, String resultWho,
6936            int requestCode, Intent[] intents, String[] resolvedTypes,
6937            int flags, Bundle bOptions, int userId) {
6938        enforceNotIsolatedCaller("getIntentSender");
6939        // Refuse possible leaked file descriptors
6940        if (intents != null) {
6941            if (intents.length < 1) {
6942                throw new IllegalArgumentException("Intents array length must be >= 1");
6943            }
6944            for (int i=0; i<intents.length; i++) {
6945                Intent intent = intents[i];
6946                if (intent != null) {
6947                    if (intent.hasFileDescriptors()) {
6948                        throw new IllegalArgumentException("File descriptors passed in Intent");
6949                    }
6950                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6951                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6952                        throw new IllegalArgumentException(
6953                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6954                    }
6955                    intents[i] = new Intent(intent);
6956                }
6957            }
6958            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6959                throw new IllegalArgumentException(
6960                        "Intent array length does not match resolvedTypes length");
6961            }
6962        }
6963        if (bOptions != null) {
6964            if (bOptions.hasFileDescriptors()) {
6965                throw new IllegalArgumentException("File descriptors passed in options");
6966            }
6967        }
6968
6969        synchronized(this) {
6970            int callingUid = Binder.getCallingUid();
6971            int origUserId = userId;
6972            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6973                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6974                    ALLOW_NON_FULL, "getIntentSender", null);
6975            if (origUserId == UserHandle.USER_CURRENT) {
6976                // We don't want to evaluate this until the pending intent is
6977                // actually executed.  However, we do want to always do the
6978                // security checking for it above.
6979                userId = UserHandle.USER_CURRENT;
6980            }
6981            try {
6982                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6983                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6984                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6985                    if (!UserHandle.isSameApp(callingUid, uid)) {
6986                        String msg = "Permission Denial: getIntentSender() from pid="
6987                            + Binder.getCallingPid()
6988                            + ", uid=" + Binder.getCallingUid()
6989                            + ", (need uid=" + uid + ")"
6990                            + " is not allowed to send as package " + packageName;
6991                        Slog.w(TAG, msg);
6992                        throw new SecurityException(msg);
6993                    }
6994                }
6995
6996                return getIntentSenderLocked(type, packageName, callingUid, userId,
6997                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6998
6999            } catch (RemoteException e) {
7000                throw new SecurityException(e);
7001            }
7002        }
7003    }
7004
7005    IIntentSender getIntentSenderLocked(int type, String packageName,
7006            int callingUid, int userId, IBinder token, String resultWho,
7007            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7008            Bundle bOptions) {
7009        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7010        ActivityRecord activity = null;
7011        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7012            activity = ActivityRecord.isInStackLocked(token);
7013            if (activity == null) {
7014                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7015                return null;
7016            }
7017            if (activity.finishing) {
7018                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7019                return null;
7020            }
7021        }
7022
7023        // We're going to be splicing together extras before sending, so we're
7024        // okay poking into any contained extras.
7025        if (intents != null) {
7026            for (int i = 0; i < intents.length; i++) {
7027                intents[i].setDefusable(true);
7028            }
7029        }
7030        Bundle.setDefusable(bOptions, true);
7031
7032        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7033        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7034        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7035        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7036                |PendingIntent.FLAG_UPDATE_CURRENT);
7037
7038        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7039                type, packageName, activity, resultWho,
7040                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7041        WeakReference<PendingIntentRecord> ref;
7042        ref = mIntentSenderRecords.get(key);
7043        PendingIntentRecord rec = ref != null ? ref.get() : null;
7044        if (rec != null) {
7045            if (!cancelCurrent) {
7046                if (updateCurrent) {
7047                    if (rec.key.requestIntent != null) {
7048                        rec.key.requestIntent.replaceExtras(intents != null ?
7049                                intents[intents.length - 1] : null);
7050                    }
7051                    if (intents != null) {
7052                        intents[intents.length-1] = rec.key.requestIntent;
7053                        rec.key.allIntents = intents;
7054                        rec.key.allResolvedTypes = resolvedTypes;
7055                    } else {
7056                        rec.key.allIntents = null;
7057                        rec.key.allResolvedTypes = null;
7058                    }
7059                }
7060                return rec;
7061            }
7062            rec.canceled = true;
7063            mIntentSenderRecords.remove(key);
7064        }
7065        if (noCreate) {
7066            return rec;
7067        }
7068        rec = new PendingIntentRecord(this, key, callingUid);
7069        mIntentSenderRecords.put(key, rec.ref);
7070        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7071            if (activity.pendingResults == null) {
7072                activity.pendingResults
7073                        = new HashSet<WeakReference<PendingIntentRecord>>();
7074            }
7075            activity.pendingResults.add(rec.ref);
7076        }
7077        return rec;
7078    }
7079
7080    @Override
7081    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7082            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7083        if (target instanceof PendingIntentRecord) {
7084            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7085                    finishedReceiver, requiredPermission, options);
7086        } else {
7087            if (intent == null) {
7088                // Weird case: someone has given us their own custom IIntentSender, and now
7089                // they have someone else trying to send to it but of course this isn't
7090                // really a PendingIntent, so there is no base Intent, and the caller isn't
7091                // supplying an Intent... but we never want to dispatch a null Intent to
7092                // a receiver, so um...  let's make something up.
7093                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7094                intent = new Intent(Intent.ACTION_MAIN);
7095            }
7096            try {
7097                target.send(code, intent, resolvedType, null, requiredPermission, options);
7098            } catch (RemoteException e) {
7099            }
7100            // Platform code can rely on getting a result back when the send is done, but if
7101            // this intent sender is from outside of the system we can't rely on it doing that.
7102            // So instead we don't give it the result receiver, and instead just directly
7103            // report the finish immediately.
7104            if (finishedReceiver != null) {
7105                try {
7106                    finishedReceiver.performReceive(intent, 0,
7107                            null, null, false, false, UserHandle.getCallingUserId());
7108                } catch (RemoteException e) {
7109                }
7110            }
7111            return 0;
7112        }
7113    }
7114
7115    @Override
7116    public void cancelIntentSender(IIntentSender sender) {
7117        if (!(sender instanceof PendingIntentRecord)) {
7118            return;
7119        }
7120        synchronized(this) {
7121            PendingIntentRecord rec = (PendingIntentRecord)sender;
7122            try {
7123                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7124                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7125                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7126                    String msg = "Permission Denial: cancelIntentSender() from pid="
7127                        + Binder.getCallingPid()
7128                        + ", uid=" + Binder.getCallingUid()
7129                        + " is not allowed to cancel packges "
7130                        + rec.key.packageName;
7131                    Slog.w(TAG, msg);
7132                    throw new SecurityException(msg);
7133                }
7134            } catch (RemoteException e) {
7135                throw new SecurityException(e);
7136            }
7137            cancelIntentSenderLocked(rec, true);
7138        }
7139    }
7140
7141    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7142        rec.canceled = true;
7143        mIntentSenderRecords.remove(rec.key);
7144        if (cleanActivity && rec.key.activity != null) {
7145            rec.key.activity.pendingResults.remove(rec.ref);
7146        }
7147    }
7148
7149    @Override
7150    public String getPackageForIntentSender(IIntentSender pendingResult) {
7151        if (!(pendingResult instanceof PendingIntentRecord)) {
7152            return null;
7153        }
7154        try {
7155            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7156            return res.key.packageName;
7157        } catch (ClassCastException e) {
7158        }
7159        return null;
7160    }
7161
7162    @Override
7163    public int getUidForIntentSender(IIntentSender sender) {
7164        if (sender instanceof PendingIntentRecord) {
7165            try {
7166                PendingIntentRecord res = (PendingIntentRecord)sender;
7167                return res.uid;
7168            } catch (ClassCastException e) {
7169            }
7170        }
7171        return -1;
7172    }
7173
7174    @Override
7175    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7176        if (!(pendingResult instanceof PendingIntentRecord)) {
7177            return false;
7178        }
7179        try {
7180            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7181            if (res.key.allIntents == null) {
7182                return false;
7183            }
7184            for (int i=0; i<res.key.allIntents.length; i++) {
7185                Intent intent = res.key.allIntents[i];
7186                if (intent.getPackage() != null && intent.getComponent() != null) {
7187                    return false;
7188                }
7189            }
7190            return true;
7191        } catch (ClassCastException e) {
7192        }
7193        return false;
7194    }
7195
7196    @Override
7197    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7198        if (!(pendingResult instanceof PendingIntentRecord)) {
7199            return false;
7200        }
7201        try {
7202            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7203            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7204                return true;
7205            }
7206            return false;
7207        } catch (ClassCastException e) {
7208        }
7209        return false;
7210    }
7211
7212    @Override
7213    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7214        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7215                "getIntentForIntentSender()");
7216        if (!(pendingResult instanceof PendingIntentRecord)) {
7217            return null;
7218        }
7219        try {
7220            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7221            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7222        } catch (ClassCastException e) {
7223        }
7224        return null;
7225    }
7226
7227    @Override
7228    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7229        if (!(pendingResult instanceof PendingIntentRecord)) {
7230            return null;
7231        }
7232        try {
7233            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7234            synchronized (this) {
7235                return getTagForIntentSenderLocked(res, prefix);
7236            }
7237        } catch (ClassCastException e) {
7238        }
7239        return null;
7240    }
7241
7242    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7243        final Intent intent = res.key.requestIntent;
7244        if (intent != null) {
7245            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7246                    || res.lastTagPrefix.equals(prefix))) {
7247                return res.lastTag;
7248            }
7249            res.lastTagPrefix = prefix;
7250            final StringBuilder sb = new StringBuilder(128);
7251            if (prefix != null) {
7252                sb.append(prefix);
7253            }
7254            if (intent.getAction() != null) {
7255                sb.append(intent.getAction());
7256            } else if (intent.getComponent() != null) {
7257                intent.getComponent().appendShortString(sb);
7258            } else {
7259                sb.append("?");
7260            }
7261            return res.lastTag = sb.toString();
7262        }
7263        return null;
7264    }
7265
7266    @Override
7267    public void setProcessLimit(int max) {
7268        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7269                "setProcessLimit()");
7270        synchronized (this) {
7271            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7272            mProcessLimitOverride = max;
7273        }
7274        trimApplications();
7275    }
7276
7277    @Override
7278    public int getProcessLimit() {
7279        synchronized (this) {
7280            return mProcessLimitOverride;
7281        }
7282    }
7283
7284    void foregroundTokenDied(ForegroundToken token) {
7285        synchronized (ActivityManagerService.this) {
7286            synchronized (mPidsSelfLocked) {
7287                ForegroundToken cur
7288                    = mForegroundProcesses.get(token.pid);
7289                if (cur != token) {
7290                    return;
7291                }
7292                mForegroundProcesses.remove(token.pid);
7293                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7294                if (pr == null) {
7295                    return;
7296                }
7297                pr.forcingToForeground = null;
7298                updateProcessForegroundLocked(pr, false, false);
7299            }
7300            updateOomAdjLocked();
7301        }
7302    }
7303
7304    @Override
7305    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7306        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7307                "setProcessForeground()");
7308        synchronized(this) {
7309            boolean changed = false;
7310
7311            synchronized (mPidsSelfLocked) {
7312                ProcessRecord pr = mPidsSelfLocked.get(pid);
7313                if (pr == null && isForeground) {
7314                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7315                    return;
7316                }
7317                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7318                if (oldToken != null) {
7319                    oldToken.token.unlinkToDeath(oldToken, 0);
7320                    mForegroundProcesses.remove(pid);
7321                    if (pr != null) {
7322                        pr.forcingToForeground = null;
7323                    }
7324                    changed = true;
7325                }
7326                if (isForeground && token != null) {
7327                    ForegroundToken newToken = new ForegroundToken() {
7328                        @Override
7329                        public void binderDied() {
7330                            foregroundTokenDied(this);
7331                        }
7332                    };
7333                    newToken.pid = pid;
7334                    newToken.token = token;
7335                    try {
7336                        token.linkToDeath(newToken, 0);
7337                        mForegroundProcesses.put(pid, newToken);
7338                        pr.forcingToForeground = token;
7339                        changed = true;
7340                    } catch (RemoteException e) {
7341                        // If the process died while doing this, we will later
7342                        // do the cleanup with the process death link.
7343                    }
7344                }
7345            }
7346
7347            if (changed) {
7348                updateOomAdjLocked();
7349            }
7350        }
7351    }
7352
7353    @Override
7354    public boolean isAppForeground(int uid) throws RemoteException {
7355        synchronized (this) {
7356            UidRecord uidRec = mActiveUids.get(uid);
7357            if (uidRec == null || uidRec.idle) {
7358                return false;
7359            }
7360            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7361        }
7362    }
7363
7364    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7365    // be guarded by permission checking.
7366    int getUidState(int uid) {
7367        synchronized (this) {
7368            UidRecord uidRec = mActiveUids.get(uid);
7369            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7370        }
7371    }
7372
7373    @Override
7374    public boolean isInMultiWindowMode(IBinder token) {
7375        final long origId = Binder.clearCallingIdentity();
7376        try {
7377            synchronized(this) {
7378                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7379                if (r == null) {
7380                    return false;
7381                }
7382                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7383                return !r.task.mFullscreen;
7384            }
7385        } finally {
7386            Binder.restoreCallingIdentity(origId);
7387        }
7388    }
7389
7390    @Override
7391    public boolean isInPictureInPictureMode(IBinder token) {
7392        final long origId = Binder.clearCallingIdentity();
7393        try {
7394            synchronized(this) {
7395                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7396                if (stack == null) {
7397                    return false;
7398                }
7399                return stack.mStackId == PINNED_STACK_ID;
7400            }
7401        } finally {
7402            Binder.restoreCallingIdentity(origId);
7403        }
7404    }
7405
7406    @Override
7407    public void enterPictureInPictureMode(IBinder token) {
7408        final long origId = Binder.clearCallingIdentity();
7409        try {
7410            synchronized(this) {
7411                if (!mSupportsPictureInPicture) {
7412                    throw new IllegalStateException("enterPictureInPictureMode: "
7413                            + "Device doesn't support picture-in-picture mode.");
7414                }
7415
7416                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7417
7418                if (r == null) {
7419                    throw new IllegalStateException("enterPictureInPictureMode: "
7420                            + "Can't find activity for token=" + token);
7421                }
7422
7423                if (!r.supportsPictureInPicture()) {
7424                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7425                            + "Picture-In-Picture not supported for r=" + r);
7426                }
7427
7428                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7429                // current bounds.
7430                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7431                final Rect bounds = (pinnedStack != null)
7432                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7433
7434                mStackSupervisor.moveActivityToPinnedStackLocked(
7435                        r, "enterPictureInPictureMode", bounds);
7436            }
7437        } finally {
7438            Binder.restoreCallingIdentity(origId);
7439        }
7440    }
7441
7442    // =========================================================
7443    // PROCESS INFO
7444    // =========================================================
7445
7446    static class ProcessInfoService extends IProcessInfoService.Stub {
7447        final ActivityManagerService mActivityManagerService;
7448        ProcessInfoService(ActivityManagerService activityManagerService) {
7449            mActivityManagerService = activityManagerService;
7450        }
7451
7452        @Override
7453        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7454            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7455                    /*in*/ pids, /*out*/ states, null);
7456        }
7457
7458        @Override
7459        public void getProcessStatesAndOomScoresFromPids(
7460                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7461            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7462                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7463        }
7464    }
7465
7466    /**
7467     * For each PID in the given input array, write the current process state
7468     * for that process into the states array, or -1 to indicate that no
7469     * process with the given PID exists. If scores array is provided, write
7470     * the oom score for the process into the scores array, with INVALID_ADJ
7471     * indicating the PID doesn't exist.
7472     */
7473    public void getProcessStatesAndOomScoresForPIDs(
7474            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7475        if (scores != null) {
7476            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7477                    "getProcessStatesAndOomScoresForPIDs()");
7478        }
7479
7480        if (pids == null) {
7481            throw new NullPointerException("pids");
7482        } else if (states == null) {
7483            throw new NullPointerException("states");
7484        } else if (pids.length != states.length) {
7485            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7486        } else if (scores != null && pids.length != scores.length) {
7487            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7488        }
7489
7490        synchronized (mPidsSelfLocked) {
7491            for (int i = 0; i < pids.length; i++) {
7492                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7493                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7494                        pr.curProcState;
7495                if (scores != null) {
7496                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7497                }
7498            }
7499        }
7500    }
7501
7502    // =========================================================
7503    // PERMISSIONS
7504    // =========================================================
7505
7506    static class PermissionController extends IPermissionController.Stub {
7507        ActivityManagerService mActivityManagerService;
7508        PermissionController(ActivityManagerService activityManagerService) {
7509            mActivityManagerService = activityManagerService;
7510        }
7511
7512        @Override
7513        public boolean checkPermission(String permission, int pid, int uid) {
7514            return mActivityManagerService.checkPermission(permission, pid,
7515                    uid) == PackageManager.PERMISSION_GRANTED;
7516        }
7517
7518        @Override
7519        public String[] getPackagesForUid(int uid) {
7520            return mActivityManagerService.mContext.getPackageManager()
7521                    .getPackagesForUid(uid);
7522        }
7523
7524        @Override
7525        public boolean isRuntimePermission(String permission) {
7526            try {
7527                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7528                        .getPermissionInfo(permission, 0);
7529                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7530            } catch (NameNotFoundException nnfe) {
7531                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7532            }
7533            return false;
7534        }
7535    }
7536
7537    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7538        @Override
7539        public int checkComponentPermission(String permission, int pid, int uid,
7540                int owningUid, boolean exported) {
7541            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7542                    owningUid, exported);
7543        }
7544
7545        @Override
7546        public Object getAMSLock() {
7547            return ActivityManagerService.this;
7548        }
7549    }
7550
7551    /**
7552     * This can be called with or without the global lock held.
7553     */
7554    int checkComponentPermission(String permission, int pid, int uid,
7555            int owningUid, boolean exported) {
7556        if (pid == MY_PID) {
7557            return PackageManager.PERMISSION_GRANTED;
7558        }
7559        return ActivityManager.checkComponentPermission(permission, uid,
7560                owningUid, exported);
7561    }
7562
7563    /**
7564     * As the only public entry point for permissions checking, this method
7565     * can enforce the semantic that requesting a check on a null global
7566     * permission is automatically denied.  (Internally a null permission
7567     * string is used when calling {@link #checkComponentPermission} in cases
7568     * when only uid-based security is needed.)
7569     *
7570     * This can be called with or without the global lock held.
7571     */
7572    @Override
7573    public int checkPermission(String permission, int pid, int uid) {
7574        if (permission == null) {
7575            return PackageManager.PERMISSION_DENIED;
7576        }
7577        return checkComponentPermission(permission, pid, uid, -1, true);
7578    }
7579
7580    @Override
7581    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7582        if (permission == null) {
7583            return PackageManager.PERMISSION_DENIED;
7584        }
7585
7586        // We might be performing an operation on behalf of an indirect binder
7587        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7588        // client identity accordingly before proceeding.
7589        Identity tlsIdentity = sCallerIdentity.get();
7590        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7591            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7592                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7593            uid = tlsIdentity.uid;
7594            pid = tlsIdentity.pid;
7595        }
7596
7597        return checkComponentPermission(permission, pid, uid, -1, true);
7598    }
7599
7600    /**
7601     * Binder IPC calls go through the public entry point.
7602     * This can be called with or without the global lock held.
7603     */
7604    int checkCallingPermission(String permission) {
7605        return checkPermission(permission,
7606                Binder.getCallingPid(),
7607                UserHandle.getAppId(Binder.getCallingUid()));
7608    }
7609
7610    /**
7611     * This can be called with or without the global lock held.
7612     */
7613    void enforceCallingPermission(String permission, String func) {
7614        if (checkCallingPermission(permission)
7615                == PackageManager.PERMISSION_GRANTED) {
7616            return;
7617        }
7618
7619        String msg = "Permission Denial: " + func + " from pid="
7620                + Binder.getCallingPid()
7621                + ", uid=" + Binder.getCallingUid()
7622                + " requires " + permission;
7623        Slog.w(TAG, msg);
7624        throw new SecurityException(msg);
7625    }
7626
7627    /**
7628     * Determine if UID is holding permissions required to access {@link Uri} in
7629     * the given {@link ProviderInfo}. Final permission checking is always done
7630     * in {@link ContentProvider}.
7631     */
7632    private final boolean checkHoldingPermissionsLocked(
7633            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7634        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7635                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7636        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7637            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7638                    != PERMISSION_GRANTED) {
7639                return false;
7640            }
7641        }
7642        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7643    }
7644
7645    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7646            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7647        if (pi.applicationInfo.uid == uid) {
7648            return true;
7649        } else if (!pi.exported) {
7650            return false;
7651        }
7652
7653        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7654        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7655        try {
7656            // check if target holds top-level <provider> permissions
7657            if (!readMet && pi.readPermission != null && considerUidPermissions
7658                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7659                readMet = true;
7660            }
7661            if (!writeMet && pi.writePermission != null && considerUidPermissions
7662                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7663                writeMet = true;
7664            }
7665
7666            // track if unprotected read/write is allowed; any denied
7667            // <path-permission> below removes this ability
7668            boolean allowDefaultRead = pi.readPermission == null;
7669            boolean allowDefaultWrite = pi.writePermission == null;
7670
7671            // check if target holds any <path-permission> that match uri
7672            final PathPermission[] pps = pi.pathPermissions;
7673            if (pps != null) {
7674                final String path = grantUri.uri.getPath();
7675                int i = pps.length;
7676                while (i > 0 && (!readMet || !writeMet)) {
7677                    i--;
7678                    PathPermission pp = pps[i];
7679                    if (pp.match(path)) {
7680                        if (!readMet) {
7681                            final String pprperm = pp.getReadPermission();
7682                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7683                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7684                                    + ": match=" + pp.match(path)
7685                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7686                            if (pprperm != null) {
7687                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7688                                        == PERMISSION_GRANTED) {
7689                                    readMet = true;
7690                                } else {
7691                                    allowDefaultRead = false;
7692                                }
7693                            }
7694                        }
7695                        if (!writeMet) {
7696                            final String ppwperm = pp.getWritePermission();
7697                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7698                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7699                                    + ": match=" + pp.match(path)
7700                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7701                            if (ppwperm != null) {
7702                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7703                                        == PERMISSION_GRANTED) {
7704                                    writeMet = true;
7705                                } else {
7706                                    allowDefaultWrite = false;
7707                                }
7708                            }
7709                        }
7710                    }
7711                }
7712            }
7713
7714            // grant unprotected <provider> read/write, if not blocked by
7715            // <path-permission> above
7716            if (allowDefaultRead) readMet = true;
7717            if (allowDefaultWrite) writeMet = true;
7718
7719        } catch (RemoteException e) {
7720            return false;
7721        }
7722
7723        return readMet && writeMet;
7724    }
7725
7726    public int getAppStartMode(int uid, String packageName) {
7727        synchronized (this) {
7728            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7729        }
7730    }
7731
7732    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7733            boolean allowWhenForeground) {
7734        UidRecord uidRec = mActiveUids.get(uid);
7735        if (!mLenientBackgroundCheck) {
7736            if (!allowWhenForeground || uidRec == null
7737                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7738                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7739                        packageName) != AppOpsManager.MODE_ALLOWED) {
7740                    return ActivityManager.APP_START_MODE_DELAYED;
7741                }
7742            }
7743
7744        } else if (uidRec == null || uidRec.idle) {
7745            if (callingPid >= 0) {
7746                ProcessRecord proc;
7747                synchronized (mPidsSelfLocked) {
7748                    proc = mPidsSelfLocked.get(callingPid);
7749                }
7750                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7751                    // Whoever is instigating this is in the foreground, so we will allow it
7752                    // to go through.
7753                    return ActivityManager.APP_START_MODE_NORMAL;
7754                }
7755            }
7756            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7757                    != AppOpsManager.MODE_ALLOWED) {
7758                return ActivityManager.APP_START_MODE_DELAYED;
7759            }
7760        }
7761        return ActivityManager.APP_START_MODE_NORMAL;
7762    }
7763
7764    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7765        ProviderInfo pi = null;
7766        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7767        if (cpr != null) {
7768            pi = cpr.info;
7769        } else {
7770            try {
7771                pi = AppGlobals.getPackageManager().resolveContentProvider(
7772                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7773            } catch (RemoteException ex) {
7774            }
7775        }
7776        return pi;
7777    }
7778
7779    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7780        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7781        if (targetUris != null) {
7782            return targetUris.get(grantUri);
7783        }
7784        return null;
7785    }
7786
7787    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7788            String targetPkg, int targetUid, GrantUri grantUri) {
7789        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7790        if (targetUris == null) {
7791            targetUris = Maps.newArrayMap();
7792            mGrantedUriPermissions.put(targetUid, targetUris);
7793        }
7794
7795        UriPermission perm = targetUris.get(grantUri);
7796        if (perm == null) {
7797            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7798            targetUris.put(grantUri, perm);
7799        }
7800
7801        return perm;
7802    }
7803
7804    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7805            final int modeFlags) {
7806        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7807        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7808                : UriPermission.STRENGTH_OWNED;
7809
7810        // Root gets to do everything.
7811        if (uid == 0) {
7812            return true;
7813        }
7814
7815        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7816        if (perms == null) return false;
7817
7818        // First look for exact match
7819        final UriPermission exactPerm = perms.get(grantUri);
7820        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7821            return true;
7822        }
7823
7824        // No exact match, look for prefixes
7825        final int N = perms.size();
7826        for (int i = 0; i < N; i++) {
7827            final UriPermission perm = perms.valueAt(i);
7828            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7829                    && perm.getStrength(modeFlags) >= minStrength) {
7830                return true;
7831            }
7832        }
7833
7834        return false;
7835    }
7836
7837    /**
7838     * @param uri This uri must NOT contain an embedded userId.
7839     * @param userId The userId in which the uri is to be resolved.
7840     */
7841    @Override
7842    public int checkUriPermission(Uri uri, int pid, int uid,
7843            final int modeFlags, int userId, IBinder callerToken) {
7844        enforceNotIsolatedCaller("checkUriPermission");
7845
7846        // Another redirected-binder-call permissions check as in
7847        // {@link checkPermissionWithToken}.
7848        Identity tlsIdentity = sCallerIdentity.get();
7849        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7850            uid = tlsIdentity.uid;
7851            pid = tlsIdentity.pid;
7852        }
7853
7854        // Our own process gets to do everything.
7855        if (pid == MY_PID) {
7856            return PackageManager.PERMISSION_GRANTED;
7857        }
7858        synchronized (this) {
7859            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7860                    ? PackageManager.PERMISSION_GRANTED
7861                    : PackageManager.PERMISSION_DENIED;
7862        }
7863    }
7864
7865    /**
7866     * Check if the targetPkg can be granted permission to access uri by
7867     * the callingUid using the given modeFlags.  Throws a security exception
7868     * if callingUid is not allowed to do this.  Returns the uid of the target
7869     * if the URI permission grant should be performed; returns -1 if it is not
7870     * needed (for example targetPkg already has permission to access the URI).
7871     * If you already know the uid of the target, you can supply it in
7872     * lastTargetUid else set that to -1.
7873     */
7874    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7875            final int modeFlags, int lastTargetUid) {
7876        if (!Intent.isAccessUriMode(modeFlags)) {
7877            return -1;
7878        }
7879
7880        if (targetPkg != null) {
7881            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7882                    "Checking grant " + targetPkg + " permission to " + grantUri);
7883        }
7884
7885        final IPackageManager pm = AppGlobals.getPackageManager();
7886
7887        // If this is not a content: uri, we can't do anything with it.
7888        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7889            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7890                    "Can't grant URI permission for non-content URI: " + grantUri);
7891            return -1;
7892        }
7893
7894        final String authority = grantUri.uri.getAuthority();
7895        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7896        if (pi == null) {
7897            Slog.w(TAG, "No content provider found for permission check: " +
7898                    grantUri.uri.toSafeString());
7899            return -1;
7900        }
7901
7902        int targetUid = lastTargetUid;
7903        if (targetUid < 0 && targetPkg != null) {
7904            try {
7905                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7906                        UserHandle.getUserId(callingUid));
7907                if (targetUid < 0) {
7908                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7909                            "Can't grant URI permission no uid for: " + targetPkg);
7910                    return -1;
7911                }
7912            } catch (RemoteException ex) {
7913                return -1;
7914            }
7915        }
7916
7917        if (targetUid >= 0) {
7918            // First...  does the target actually need this permission?
7919            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7920                // No need to grant the target this permission.
7921                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7922                        "Target " + targetPkg + " already has full permission to " + grantUri);
7923                return -1;
7924            }
7925        } else {
7926            // First...  there is no target package, so can anyone access it?
7927            boolean allowed = pi.exported;
7928            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7929                if (pi.readPermission != null) {
7930                    allowed = false;
7931                }
7932            }
7933            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7934                if (pi.writePermission != null) {
7935                    allowed = false;
7936                }
7937            }
7938            if (allowed) {
7939                return -1;
7940            }
7941        }
7942
7943        /* There is a special cross user grant if:
7944         * - The target is on another user.
7945         * - Apps on the current user can access the uri without any uid permissions.
7946         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7947         * grant uri permissions.
7948         */
7949        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7950                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7951                modeFlags, false /*without considering the uid permissions*/);
7952
7953        // Second...  is the provider allowing granting of URI permissions?
7954        if (!specialCrossUserGrant) {
7955            if (!pi.grantUriPermissions) {
7956                throw new SecurityException("Provider " + pi.packageName
7957                        + "/" + pi.name
7958                        + " does not allow granting of Uri permissions (uri "
7959                        + grantUri + ")");
7960            }
7961            if (pi.uriPermissionPatterns != null) {
7962                final int N = pi.uriPermissionPatterns.length;
7963                boolean allowed = false;
7964                for (int i=0; i<N; i++) {
7965                    if (pi.uriPermissionPatterns[i] != null
7966                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7967                        allowed = true;
7968                        break;
7969                    }
7970                }
7971                if (!allowed) {
7972                    throw new SecurityException("Provider " + pi.packageName
7973                            + "/" + pi.name
7974                            + " does not allow granting of permission to path of Uri "
7975                            + grantUri);
7976                }
7977            }
7978        }
7979
7980        // Third...  does the caller itself have permission to access
7981        // this uri?
7982        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7983            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7984                // Require they hold a strong enough Uri permission
7985                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7986                    throw new SecurityException("Uid " + callingUid
7987                            + " does not have permission to uri " + grantUri);
7988                }
7989            }
7990        }
7991        return targetUid;
7992    }
7993
7994    /**
7995     * @param uri This uri must NOT contain an embedded userId.
7996     * @param userId The userId in which the uri is to be resolved.
7997     */
7998    @Override
7999    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8000            final int modeFlags, int userId) {
8001        enforceNotIsolatedCaller("checkGrantUriPermission");
8002        synchronized(this) {
8003            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8004                    new GrantUri(userId, uri, false), modeFlags, -1);
8005        }
8006    }
8007
8008    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8009            final int modeFlags, UriPermissionOwner owner) {
8010        if (!Intent.isAccessUriMode(modeFlags)) {
8011            return;
8012        }
8013
8014        // So here we are: the caller has the assumed permission
8015        // to the uri, and the target doesn't.  Let's now give this to
8016        // the target.
8017
8018        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8019                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8020
8021        final String authority = grantUri.uri.getAuthority();
8022        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8023        if (pi == null) {
8024            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8025            return;
8026        }
8027
8028        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8029            grantUri.prefix = true;
8030        }
8031        final UriPermission perm = findOrCreateUriPermissionLocked(
8032                pi.packageName, targetPkg, targetUid, grantUri);
8033        perm.grantModes(modeFlags, owner);
8034    }
8035
8036    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8037            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8038        if (targetPkg == null) {
8039            throw new NullPointerException("targetPkg");
8040        }
8041        int targetUid;
8042        final IPackageManager pm = AppGlobals.getPackageManager();
8043        try {
8044            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8045        } catch (RemoteException ex) {
8046            return;
8047        }
8048
8049        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8050                targetUid);
8051        if (targetUid < 0) {
8052            return;
8053        }
8054
8055        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8056                owner);
8057    }
8058
8059    static class NeededUriGrants extends ArrayList<GrantUri> {
8060        final String targetPkg;
8061        final int targetUid;
8062        final int flags;
8063
8064        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8065            this.targetPkg = targetPkg;
8066            this.targetUid = targetUid;
8067            this.flags = flags;
8068        }
8069    }
8070
8071    /**
8072     * Like checkGrantUriPermissionLocked, but takes an Intent.
8073     */
8074    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8075            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8076        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8077                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8078                + " clip=" + (intent != null ? intent.getClipData() : null)
8079                + " from " + intent + "; flags=0x"
8080                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8081
8082        if (targetPkg == null) {
8083            throw new NullPointerException("targetPkg");
8084        }
8085
8086        if (intent == null) {
8087            return null;
8088        }
8089        Uri data = intent.getData();
8090        ClipData clip = intent.getClipData();
8091        if (data == null && clip == null) {
8092            return null;
8093        }
8094        // Default userId for uris in the intent (if they don't specify it themselves)
8095        int contentUserHint = intent.getContentUserHint();
8096        if (contentUserHint == UserHandle.USER_CURRENT) {
8097            contentUserHint = UserHandle.getUserId(callingUid);
8098        }
8099        final IPackageManager pm = AppGlobals.getPackageManager();
8100        int targetUid;
8101        if (needed != null) {
8102            targetUid = needed.targetUid;
8103        } else {
8104            try {
8105                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8106                        targetUserId);
8107            } catch (RemoteException ex) {
8108                return null;
8109            }
8110            if (targetUid < 0) {
8111                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112                        "Can't grant URI permission no uid for: " + targetPkg
8113                        + " on user " + targetUserId);
8114                return null;
8115            }
8116        }
8117        if (data != null) {
8118            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8119            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8120                    targetUid);
8121            if (targetUid > 0) {
8122                if (needed == null) {
8123                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8124                }
8125                needed.add(grantUri);
8126            }
8127        }
8128        if (clip != null) {
8129            for (int i=0; i<clip.getItemCount(); i++) {
8130                Uri uri = clip.getItemAt(i).getUri();
8131                if (uri != null) {
8132                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8133                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8134                            targetUid);
8135                    if (targetUid > 0) {
8136                        if (needed == null) {
8137                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8138                        }
8139                        needed.add(grantUri);
8140                    }
8141                } else {
8142                    Intent clipIntent = clip.getItemAt(i).getIntent();
8143                    if (clipIntent != null) {
8144                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8145                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8146                        if (newNeeded != null) {
8147                            needed = newNeeded;
8148                        }
8149                    }
8150                }
8151            }
8152        }
8153
8154        return needed;
8155    }
8156
8157    /**
8158     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8159     */
8160    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8161            UriPermissionOwner owner) {
8162        if (needed != null) {
8163            for (int i=0; i<needed.size(); i++) {
8164                GrantUri grantUri = needed.get(i);
8165                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8166                        grantUri, needed.flags, owner);
8167            }
8168        }
8169    }
8170
8171    void grantUriPermissionFromIntentLocked(int callingUid,
8172            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8173        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8174                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8175        if (needed == null) {
8176            return;
8177        }
8178
8179        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8180    }
8181
8182    /**
8183     * @param uri This uri must NOT contain an embedded userId.
8184     * @param userId The userId in which the uri is to be resolved.
8185     */
8186    @Override
8187    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8188            final int modeFlags, int userId) {
8189        enforceNotIsolatedCaller("grantUriPermission");
8190        GrantUri grantUri = new GrantUri(userId, uri, false);
8191        synchronized(this) {
8192            final ProcessRecord r = getRecordForAppLocked(caller);
8193            if (r == null) {
8194                throw new SecurityException("Unable to find app for caller "
8195                        + caller
8196                        + " when granting permission to uri " + grantUri);
8197            }
8198            if (targetPkg == null) {
8199                throw new IllegalArgumentException("null target");
8200            }
8201            if (grantUri == null) {
8202                throw new IllegalArgumentException("null uri");
8203            }
8204
8205            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8206                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8207                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8208                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8209
8210            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8211                    UserHandle.getUserId(r.uid));
8212        }
8213    }
8214
8215    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8216        if (perm.modeFlags == 0) {
8217            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8218                    perm.targetUid);
8219            if (perms != null) {
8220                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8221                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8222
8223                perms.remove(perm.uri);
8224                if (perms.isEmpty()) {
8225                    mGrantedUriPermissions.remove(perm.targetUid);
8226                }
8227            }
8228        }
8229    }
8230
8231    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8232        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8233                "Revoking all granted permissions to " + grantUri);
8234
8235        final IPackageManager pm = AppGlobals.getPackageManager();
8236        final String authority = grantUri.uri.getAuthority();
8237        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8238        if (pi == null) {
8239            Slog.w(TAG, "No content provider found for permission revoke: "
8240                    + grantUri.toSafeString());
8241            return;
8242        }
8243
8244        // Does the caller have this permission on the URI?
8245        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8246            // If they don't have direct access to the URI, then revoke any
8247            // ownerless URI permissions that have been granted to them.
8248            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8249            if (perms != null) {
8250                boolean persistChanged = false;
8251                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8252                    final UriPermission perm = it.next();
8253                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8254                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8255                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8256                                "Revoking non-owned " + perm.targetUid
8257                                + " permission to " + perm.uri);
8258                        persistChanged |= perm.revokeModes(
8259                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8260                        if (perm.modeFlags == 0) {
8261                            it.remove();
8262                        }
8263                    }
8264                }
8265                if (perms.isEmpty()) {
8266                    mGrantedUriPermissions.remove(callingUid);
8267                }
8268                if (persistChanged) {
8269                    schedulePersistUriGrants();
8270                }
8271            }
8272            return;
8273        }
8274
8275        boolean persistChanged = false;
8276
8277        // Go through all of the permissions and remove any that match.
8278        int N = mGrantedUriPermissions.size();
8279        for (int i = 0; i < N; i++) {
8280            final int targetUid = mGrantedUriPermissions.keyAt(i);
8281            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8282
8283            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8284                final UriPermission perm = it.next();
8285                if (perm.uri.sourceUserId == grantUri.sourceUserId
8286                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8287                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8288                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8289                    persistChanged |= perm.revokeModes(
8290                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8291                    if (perm.modeFlags == 0) {
8292                        it.remove();
8293                    }
8294                }
8295            }
8296
8297            if (perms.isEmpty()) {
8298                mGrantedUriPermissions.remove(targetUid);
8299                N--;
8300                i--;
8301            }
8302        }
8303
8304        if (persistChanged) {
8305            schedulePersistUriGrants();
8306        }
8307    }
8308
8309    /**
8310     * @param uri This uri must NOT contain an embedded userId.
8311     * @param userId The userId in which the uri is to be resolved.
8312     */
8313    @Override
8314    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8315            int userId) {
8316        enforceNotIsolatedCaller("revokeUriPermission");
8317        synchronized(this) {
8318            final ProcessRecord r = getRecordForAppLocked(caller);
8319            if (r == null) {
8320                throw new SecurityException("Unable to find app for caller "
8321                        + caller
8322                        + " when revoking permission to uri " + uri);
8323            }
8324            if (uri == null) {
8325                Slog.w(TAG, "revokeUriPermission: null uri");
8326                return;
8327            }
8328
8329            if (!Intent.isAccessUriMode(modeFlags)) {
8330                return;
8331            }
8332
8333            final String authority = uri.getAuthority();
8334            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8335            if (pi == null) {
8336                Slog.w(TAG, "No content provider found for permission revoke: "
8337                        + uri.toSafeString());
8338                return;
8339            }
8340
8341            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8342        }
8343    }
8344
8345    /**
8346     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8347     * given package.
8348     *
8349     * @param packageName Package name to match, or {@code null} to apply to all
8350     *            packages.
8351     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8352     *            to all users.
8353     * @param persistable If persistable grants should be removed.
8354     */
8355    private void removeUriPermissionsForPackageLocked(
8356            String packageName, int userHandle, boolean persistable) {
8357        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8358            throw new IllegalArgumentException("Must narrow by either package or user");
8359        }
8360
8361        boolean persistChanged = false;
8362
8363        int N = mGrantedUriPermissions.size();
8364        for (int i = 0; i < N; i++) {
8365            final int targetUid = mGrantedUriPermissions.keyAt(i);
8366            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8367
8368            // Only inspect grants matching user
8369            if (userHandle == UserHandle.USER_ALL
8370                    || userHandle == UserHandle.getUserId(targetUid)) {
8371                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8372                    final UriPermission perm = it.next();
8373
8374                    // Only inspect grants matching package
8375                    if (packageName == null || perm.sourcePkg.equals(packageName)
8376                            || perm.targetPkg.equals(packageName)) {
8377                        persistChanged |= perm.revokeModes(persistable
8378                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8379
8380                        // Only remove when no modes remain; any persisted grants
8381                        // will keep this alive.
8382                        if (perm.modeFlags == 0) {
8383                            it.remove();
8384                        }
8385                    }
8386                }
8387
8388                if (perms.isEmpty()) {
8389                    mGrantedUriPermissions.remove(targetUid);
8390                    N--;
8391                    i--;
8392                }
8393            }
8394        }
8395
8396        if (persistChanged) {
8397            schedulePersistUriGrants();
8398        }
8399    }
8400
8401    @Override
8402    public IBinder newUriPermissionOwner(String name) {
8403        enforceNotIsolatedCaller("newUriPermissionOwner");
8404        synchronized(this) {
8405            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8406            return owner.getExternalTokenLocked();
8407        }
8408    }
8409
8410    @Override
8411    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8412        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8413        synchronized(this) {
8414            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8415            if (r == null) {
8416                throw new IllegalArgumentException("Activity does not exist; token="
8417                        + activityToken);
8418            }
8419            return r.getUriPermissionsLocked().getExternalTokenLocked();
8420        }
8421    }
8422    /**
8423     * @param uri This uri must NOT contain an embedded userId.
8424     * @param sourceUserId The userId in which the uri is to be resolved.
8425     * @param targetUserId The userId of the app that receives the grant.
8426     */
8427    @Override
8428    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8429            final int modeFlags, int sourceUserId, int targetUserId) {
8430        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8431                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8432                "grantUriPermissionFromOwner", null);
8433        synchronized(this) {
8434            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8435            if (owner == null) {
8436                throw new IllegalArgumentException("Unknown owner: " + token);
8437            }
8438            if (fromUid != Binder.getCallingUid()) {
8439                if (Binder.getCallingUid() != Process.myUid()) {
8440                    // Only system code can grant URI permissions on behalf
8441                    // of other users.
8442                    throw new SecurityException("nice try");
8443                }
8444            }
8445            if (targetPkg == null) {
8446                throw new IllegalArgumentException("null target");
8447            }
8448            if (uri == null) {
8449                throw new IllegalArgumentException("null uri");
8450            }
8451
8452            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8453                    modeFlags, owner, targetUserId);
8454        }
8455    }
8456
8457    /**
8458     * @param uri This uri must NOT contain an embedded userId.
8459     * @param userId The userId in which the uri is to be resolved.
8460     */
8461    @Override
8462    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8463        synchronized(this) {
8464            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8465            if (owner == null) {
8466                throw new IllegalArgumentException("Unknown owner: " + token);
8467            }
8468
8469            if (uri == null) {
8470                owner.removeUriPermissionsLocked(mode);
8471            } else {
8472                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8473            }
8474        }
8475    }
8476
8477    private void schedulePersistUriGrants() {
8478        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8479            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8480                    10 * DateUtils.SECOND_IN_MILLIS);
8481        }
8482    }
8483
8484    private void writeGrantedUriPermissions() {
8485        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8486
8487        // Snapshot permissions so we can persist without lock
8488        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8489        synchronized (this) {
8490            final int size = mGrantedUriPermissions.size();
8491            for (int i = 0; i < size; i++) {
8492                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8493                for (UriPermission perm : perms.values()) {
8494                    if (perm.persistedModeFlags != 0) {
8495                        persist.add(perm.snapshot());
8496                    }
8497                }
8498            }
8499        }
8500
8501        FileOutputStream fos = null;
8502        try {
8503            fos = mGrantFile.startWrite();
8504
8505            XmlSerializer out = new FastXmlSerializer();
8506            out.setOutput(fos, StandardCharsets.UTF_8.name());
8507            out.startDocument(null, true);
8508            out.startTag(null, TAG_URI_GRANTS);
8509            for (UriPermission.Snapshot perm : persist) {
8510                out.startTag(null, TAG_URI_GRANT);
8511                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8512                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8513                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8514                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8515                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8516                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8517                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8518                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8519                out.endTag(null, TAG_URI_GRANT);
8520            }
8521            out.endTag(null, TAG_URI_GRANTS);
8522            out.endDocument();
8523
8524            mGrantFile.finishWrite(fos);
8525        } catch (IOException e) {
8526            if (fos != null) {
8527                mGrantFile.failWrite(fos);
8528            }
8529        }
8530    }
8531
8532    private void readGrantedUriPermissionsLocked() {
8533        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8534
8535        final long now = System.currentTimeMillis();
8536
8537        FileInputStream fis = null;
8538        try {
8539            fis = mGrantFile.openRead();
8540            final XmlPullParser in = Xml.newPullParser();
8541            in.setInput(fis, StandardCharsets.UTF_8.name());
8542
8543            int type;
8544            while ((type = in.next()) != END_DOCUMENT) {
8545                final String tag = in.getName();
8546                if (type == START_TAG) {
8547                    if (TAG_URI_GRANT.equals(tag)) {
8548                        final int sourceUserId;
8549                        final int targetUserId;
8550                        final int userHandle = readIntAttribute(in,
8551                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8552                        if (userHandle != UserHandle.USER_NULL) {
8553                            // For backwards compatibility.
8554                            sourceUserId = userHandle;
8555                            targetUserId = userHandle;
8556                        } else {
8557                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8558                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8559                        }
8560                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8561                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8562                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8563                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8566
8567                        // Sanity check that provider still belongs to source package
8568                        final ProviderInfo pi = getProviderInfoLocked(
8569                                uri.getAuthority(), sourceUserId);
8570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8571                            int targetUid = -1;
8572                            try {
8573                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8574                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8575                            } catch (RemoteException e) {
8576                            }
8577                            if (targetUid != -1) {
8578                                final UriPermission perm = findOrCreateUriPermissionLocked(
8579                                        sourcePkg, targetPkg, targetUid,
8580                                        new GrantUri(sourceUserId, uri, prefix));
8581                                perm.initPersistedModes(modeFlags, createdTime);
8582                            }
8583                        } else {
8584                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8585                                    + " but instead found " + pi);
8586                        }
8587                    }
8588                }
8589            }
8590        } catch (FileNotFoundException e) {
8591            // Missing grants is okay
8592        } catch (IOException e) {
8593            Slog.wtf(TAG, "Failed reading Uri grants", e);
8594        } catch (XmlPullParserException e) {
8595            Slog.wtf(TAG, "Failed reading Uri grants", e);
8596        } finally {
8597            IoUtils.closeQuietly(fis);
8598        }
8599    }
8600
8601    /**
8602     * @param uri This uri must NOT contain an embedded userId.
8603     * @param userId The userId in which the uri is to be resolved.
8604     */
8605    @Override
8606    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8607        enforceNotIsolatedCaller("takePersistableUriPermission");
8608
8609        Preconditions.checkFlagsArgument(modeFlags,
8610                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8611
8612        synchronized (this) {
8613            final int callingUid = Binder.getCallingUid();
8614            boolean persistChanged = false;
8615            GrantUri grantUri = new GrantUri(userId, uri, false);
8616
8617            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8618                    new GrantUri(userId, uri, false));
8619            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8620                    new GrantUri(userId, uri, true));
8621
8622            final boolean exactValid = (exactPerm != null)
8623                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8624            final boolean prefixValid = (prefixPerm != null)
8625                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8626
8627            if (!(exactValid || prefixValid)) {
8628                throw new SecurityException("No persistable permission grants found for UID "
8629                        + callingUid + " and Uri " + grantUri.toSafeString());
8630            }
8631
8632            if (exactValid) {
8633                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8634            }
8635            if (prefixValid) {
8636                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8637            }
8638
8639            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8640
8641            if (persistChanged) {
8642                schedulePersistUriGrants();
8643            }
8644        }
8645    }
8646
8647    /**
8648     * @param uri This uri must NOT contain an embedded userId.
8649     * @param userId The userId in which the uri is to be resolved.
8650     */
8651    @Override
8652    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8653        enforceNotIsolatedCaller("releasePersistableUriPermission");
8654
8655        Preconditions.checkFlagsArgument(modeFlags,
8656                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8657
8658        synchronized (this) {
8659            final int callingUid = Binder.getCallingUid();
8660            boolean persistChanged = false;
8661
8662            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8663                    new GrantUri(userId, uri, false));
8664            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8665                    new GrantUri(userId, uri, true));
8666            if (exactPerm == null && prefixPerm == null) {
8667                throw new SecurityException("No permission grants found for UID " + callingUid
8668                        + " and Uri " + uri.toSafeString());
8669            }
8670
8671            if (exactPerm != null) {
8672                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8673                removeUriPermissionIfNeededLocked(exactPerm);
8674            }
8675            if (prefixPerm != null) {
8676                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8677                removeUriPermissionIfNeededLocked(prefixPerm);
8678            }
8679
8680            if (persistChanged) {
8681                schedulePersistUriGrants();
8682            }
8683        }
8684    }
8685
8686    /**
8687     * Prune any older {@link UriPermission} for the given UID until outstanding
8688     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8689     *
8690     * @return if any mutations occured that require persisting.
8691     */
8692    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8693        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8694        if (perms == null) return false;
8695        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8696
8697        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8698        for (UriPermission perm : perms.values()) {
8699            if (perm.persistedModeFlags != 0) {
8700                persisted.add(perm);
8701            }
8702        }
8703
8704        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8705        if (trimCount <= 0) return false;
8706
8707        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8708        for (int i = 0; i < trimCount; i++) {
8709            final UriPermission perm = persisted.get(i);
8710
8711            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8712                    "Trimming grant created at " + perm.persistedCreateTime);
8713
8714            perm.releasePersistableModes(~0);
8715            removeUriPermissionIfNeededLocked(perm);
8716        }
8717
8718        return true;
8719    }
8720
8721    @Override
8722    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8723            String packageName, boolean incoming) {
8724        enforceNotIsolatedCaller("getPersistedUriPermissions");
8725        Preconditions.checkNotNull(packageName, "packageName");
8726
8727        final int callingUid = Binder.getCallingUid();
8728        final IPackageManager pm = AppGlobals.getPackageManager();
8729        try {
8730            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8731                    UserHandle.getUserId(callingUid));
8732            if (packageUid != callingUid) {
8733                throw new SecurityException(
8734                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8735            }
8736        } catch (RemoteException e) {
8737            throw new SecurityException("Failed to verify package name ownership");
8738        }
8739
8740        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8741        synchronized (this) {
8742            if (incoming) {
8743                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8744                        callingUid);
8745                if (perms == null) {
8746                    Slog.w(TAG, "No permission grants found for " + packageName);
8747                } else {
8748                    for (UriPermission perm : perms.values()) {
8749                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8750                            result.add(perm.buildPersistedPublicApiObject());
8751                        }
8752                    }
8753                }
8754            } else {
8755                final int size = mGrantedUriPermissions.size();
8756                for (int i = 0; i < size; i++) {
8757                    final ArrayMap<GrantUri, UriPermission> perms =
8758                            mGrantedUriPermissions.valueAt(i);
8759                    for (UriPermission perm : perms.values()) {
8760                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8761                            result.add(perm.buildPersistedPublicApiObject());
8762                        }
8763                    }
8764                }
8765            }
8766        }
8767        return new ParceledListSlice<android.content.UriPermission>(result);
8768    }
8769
8770    @Override
8771    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8772            String packageName, int userId) {
8773        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8774                "getGrantedUriPermissions");
8775
8776        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8777        synchronized (this) {
8778            final int size = mGrantedUriPermissions.size();
8779            for (int i = 0; i < size; i++) {
8780                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8781                for (UriPermission perm : perms.values()) {
8782                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8783                            && perm.persistedModeFlags != 0) {
8784                        result.add(perm.buildPersistedPublicApiObject());
8785                    }
8786                }
8787            }
8788        }
8789        return new ParceledListSlice<android.content.UriPermission>(result);
8790    }
8791
8792    @Override
8793    public void clearGrantedUriPermissions(String packageName, int userId) {
8794        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8795                "clearGrantedUriPermissions");
8796        removeUriPermissionsForPackageLocked(packageName, userId, true);
8797    }
8798
8799    @Override
8800    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8801        synchronized (this) {
8802            ProcessRecord app =
8803                who != null ? getRecordForAppLocked(who) : null;
8804            if (app == null) return;
8805
8806            Message msg = Message.obtain();
8807            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8808            msg.obj = app;
8809            msg.arg1 = waiting ? 1 : 0;
8810            mUiHandler.sendMessage(msg);
8811        }
8812    }
8813
8814    @Override
8815    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8816        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8817        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8818        outInfo.availMem = Process.getFreeMemory();
8819        outInfo.totalMem = Process.getTotalMemory();
8820        outInfo.threshold = homeAppMem;
8821        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8822        outInfo.hiddenAppThreshold = cachedAppMem;
8823        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8824                ProcessList.SERVICE_ADJ);
8825        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8826                ProcessList.VISIBLE_APP_ADJ);
8827        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8828                ProcessList.FOREGROUND_APP_ADJ);
8829    }
8830
8831    // =========================================================
8832    // TASK MANAGEMENT
8833    // =========================================================
8834
8835    @Override
8836    public List<IAppTask> getAppTasks(String callingPackage) {
8837        int callingUid = Binder.getCallingUid();
8838        long ident = Binder.clearCallingIdentity();
8839
8840        synchronized(this) {
8841            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8842            try {
8843                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8844
8845                final int N = mRecentTasks.size();
8846                for (int i = 0; i < N; i++) {
8847                    TaskRecord tr = mRecentTasks.get(i);
8848                    // Skip tasks that do not match the caller.  We don't need to verify
8849                    // callingPackage, because we are also limiting to callingUid and know
8850                    // that will limit to the correct security sandbox.
8851                    if (tr.effectiveUid != callingUid) {
8852                        continue;
8853                    }
8854                    Intent intent = tr.getBaseIntent();
8855                    if (intent == null ||
8856                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8857                        continue;
8858                    }
8859                    ActivityManager.RecentTaskInfo taskInfo =
8860                            createRecentTaskInfoFromTaskRecord(tr);
8861                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8862                    list.add(taskImpl);
8863                }
8864            } finally {
8865                Binder.restoreCallingIdentity(ident);
8866            }
8867            return list;
8868        }
8869    }
8870
8871    @Override
8872    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8873        final int callingUid = Binder.getCallingUid();
8874        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8875
8876        synchronized(this) {
8877            if (DEBUG_ALL) Slog.v(
8878                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8879
8880            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8881                    callingUid);
8882
8883            // TODO: Improve with MRU list from all ActivityStacks.
8884            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8885        }
8886
8887        return list;
8888    }
8889
8890    /**
8891     * Creates a new RecentTaskInfo from a TaskRecord.
8892     */
8893    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8894        // Update the task description to reflect any changes in the task stack
8895        tr.updateTaskDescription();
8896
8897        // Compose the recent task info
8898        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8899        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8900        rti.persistentId = tr.taskId;
8901        rti.baseIntent = new Intent(tr.getBaseIntent());
8902        rti.origActivity = tr.origActivity;
8903        rti.realActivity = tr.realActivity;
8904        rti.description = tr.lastDescription;
8905        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8906        rti.userId = tr.userId;
8907        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8908        rti.firstActiveTime = tr.firstActiveTime;
8909        rti.lastActiveTime = tr.lastActiveTime;
8910        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8911        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8912        rti.numActivities = 0;
8913        if (tr.mBounds != null) {
8914            rti.bounds = new Rect(tr.mBounds);
8915        }
8916        rti.isDockable = tr.canGoInDockedStack();
8917        rti.resizeMode = tr.mResizeMode;
8918
8919        ActivityRecord base = null;
8920        ActivityRecord top = null;
8921        ActivityRecord tmp;
8922
8923        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8924            tmp = tr.mActivities.get(i);
8925            if (tmp.finishing) {
8926                continue;
8927            }
8928            base = tmp;
8929            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8930                top = base;
8931            }
8932            rti.numActivities++;
8933        }
8934
8935        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8936        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8937
8938        return rti;
8939    }
8940
8941    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8942        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8943                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8944        if (!allowed) {
8945            if (checkPermission(android.Manifest.permission.GET_TASKS,
8946                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8947                // Temporary compatibility: some existing apps on the system image may
8948                // still be requesting the old permission and not switched to the new
8949                // one; if so, we'll still allow them full access.  This means we need
8950                // to see if they are holding the old permission and are a system app.
8951                try {
8952                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8953                        allowed = true;
8954                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8955                                + " is using old GET_TASKS but privileged; allowing");
8956                    }
8957                } catch (RemoteException e) {
8958                }
8959            }
8960        }
8961        if (!allowed) {
8962            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8963                    + " does not hold REAL_GET_TASKS; limiting output");
8964        }
8965        return allowed;
8966    }
8967
8968    @Override
8969    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8970        final int callingUid = Binder.getCallingUid();
8971        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8972                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8973
8974        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8975        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8976        synchronized (this) {
8977            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8978                    callingUid);
8979            final boolean detailed = checkCallingPermission(
8980                    android.Manifest.permission.GET_DETAILED_TASKS)
8981                    == PackageManager.PERMISSION_GRANTED;
8982
8983            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8984                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8985                return Collections.emptyList();
8986            }
8987            mRecentTasks.loadUserRecentsLocked(userId);
8988
8989            final int recentsCount = mRecentTasks.size();
8990            ArrayList<ActivityManager.RecentTaskInfo> res =
8991                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8992
8993            final Set<Integer> includedUsers;
8994            if (includeProfiles) {
8995                includedUsers = mUserController.getProfileIds(userId);
8996            } else {
8997                includedUsers = new HashSet<>();
8998            }
8999            includedUsers.add(Integer.valueOf(userId));
9000
9001            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9002                TaskRecord tr = mRecentTasks.get(i);
9003                // Only add calling user or related users recent tasks
9004                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9005                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9006                    continue;
9007                }
9008
9009                if (tr.realActivitySuspended) {
9010                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9011                    continue;
9012                }
9013
9014                // Return the entry if desired by the caller.  We always return
9015                // the first entry, because callers always expect this to be the
9016                // foreground app.  We may filter others if the caller has
9017                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9018                // we should exclude the entry.
9019
9020                if (i == 0
9021                        || withExcluded
9022                        || (tr.intent == null)
9023                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9024                                == 0)) {
9025                    if (!allowed) {
9026                        // If the caller doesn't have the GET_TASKS permission, then only
9027                        // allow them to see a small subset of tasks -- their own and home.
9028                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9029                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9030                            continue;
9031                        }
9032                    }
9033                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9034                        if (tr.stack != null && tr.stack.isHomeStack()) {
9035                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9036                                    "Skipping, home stack task: " + tr);
9037                            continue;
9038                        }
9039                    }
9040                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9041                        final ActivityStack stack = tr.stack;
9042                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9043                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9044                                    "Skipping, top task in docked stack: " + tr);
9045                            continue;
9046                        }
9047                    }
9048                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9049                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9050                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9051                                    "Skipping, pinned stack task: " + tr);
9052                            continue;
9053                        }
9054                    }
9055                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9056                        // Don't include auto remove tasks that are finished or finishing.
9057                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9058                                "Skipping, auto-remove without activity: " + tr);
9059                        continue;
9060                    }
9061                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9062                            && !tr.isAvailable) {
9063                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9064                                "Skipping, unavail real act: " + tr);
9065                        continue;
9066                    }
9067
9068                    if (!tr.mUserSetupComplete) {
9069                        // Don't include task launched while user is not done setting-up.
9070                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9071                                "Skipping, user setup not complete: " + tr);
9072                        continue;
9073                    }
9074
9075                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9076                    if (!detailed) {
9077                        rti.baseIntent.replaceExtras((Bundle)null);
9078                    }
9079
9080                    res.add(rti);
9081                    maxNum--;
9082                }
9083            }
9084            return res;
9085        }
9086    }
9087
9088    @Override
9089    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9090        synchronized (this) {
9091            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9092                    "getTaskThumbnail()");
9093            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9094                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9095            if (tr != null) {
9096                return tr.getTaskThumbnailLocked();
9097            }
9098        }
9099        return null;
9100    }
9101
9102    @Override
9103    public int addAppTask(IBinder activityToken, Intent intent,
9104            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9105        final int callingUid = Binder.getCallingUid();
9106        final long callingIdent = Binder.clearCallingIdentity();
9107
9108        try {
9109            synchronized (this) {
9110                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9111                if (r == null) {
9112                    throw new IllegalArgumentException("Activity does not exist; token="
9113                            + activityToken);
9114                }
9115                ComponentName comp = intent.getComponent();
9116                if (comp == null) {
9117                    throw new IllegalArgumentException("Intent " + intent
9118                            + " must specify explicit component");
9119                }
9120                if (thumbnail.getWidth() != mThumbnailWidth
9121                        || thumbnail.getHeight() != mThumbnailHeight) {
9122                    throw new IllegalArgumentException("Bad thumbnail size: got "
9123                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9124                            + mThumbnailWidth + "x" + mThumbnailHeight);
9125                }
9126                if (intent.getSelector() != null) {
9127                    intent.setSelector(null);
9128                }
9129                if (intent.getSourceBounds() != null) {
9130                    intent.setSourceBounds(null);
9131                }
9132                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9133                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9134                        // The caller has added this as an auto-remove task...  that makes no
9135                        // sense, so turn off auto-remove.
9136                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9137                    }
9138                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9139                    // Must be a new task.
9140                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9141                }
9142                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9143                    mLastAddedTaskActivity = null;
9144                }
9145                ActivityInfo ainfo = mLastAddedTaskActivity;
9146                if (ainfo == null) {
9147                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9148                            comp, 0, UserHandle.getUserId(callingUid));
9149                    if (ainfo.applicationInfo.uid != callingUid) {
9150                        throw new SecurityException(
9151                                "Can't add task for another application: target uid="
9152                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9153                    }
9154                }
9155
9156                // Use the full screen as the context for the task thumbnail
9157                final Point displaySize = new Point();
9158                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9159                r.task.stack.getDisplaySize(displaySize);
9160                thumbnailInfo.taskWidth = displaySize.x;
9161                thumbnailInfo.taskHeight = displaySize.y;
9162                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9163
9164                TaskRecord task = new TaskRecord(this,
9165                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9166                        ainfo, intent, description, thumbnailInfo);
9167
9168                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9169                if (trimIdx >= 0) {
9170                    // If this would have caused a trim, then we'll abort because that
9171                    // means it would be added at the end of the list but then just removed.
9172                    return INVALID_TASK_ID;
9173                }
9174
9175                final int N = mRecentTasks.size();
9176                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9177                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9178                    tr.removedFromRecents();
9179                }
9180
9181                task.inRecents = true;
9182                mRecentTasks.add(task);
9183                r.task.stack.addTask(task, false, "addAppTask");
9184
9185                task.setLastThumbnailLocked(thumbnail);
9186                task.freeLastThumbnail();
9187
9188                return task.taskId;
9189            }
9190        } finally {
9191            Binder.restoreCallingIdentity(callingIdent);
9192        }
9193    }
9194
9195    @Override
9196    public Point getAppTaskThumbnailSize() {
9197        synchronized (this) {
9198            return new Point(mThumbnailWidth,  mThumbnailHeight);
9199        }
9200    }
9201
9202    @Override
9203    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9204        synchronized (this) {
9205            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9206            if (r != null) {
9207                r.setTaskDescription(td);
9208                r.task.updateTaskDescription();
9209            }
9210        }
9211    }
9212
9213    @Override
9214    public void setTaskResizeable(int taskId, int resizeableMode) {
9215        synchronized (this) {
9216            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9217                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9218            if (task == null) {
9219                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9220                return;
9221            }
9222            if (task.mResizeMode != resizeableMode) {
9223                task.mResizeMode = resizeableMode;
9224                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9225                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9226                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9227            }
9228        }
9229    }
9230
9231    @Override
9232    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9233        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9234        long ident = Binder.clearCallingIdentity();
9235        try {
9236            synchronized (this) {
9237                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9238                if (task == null) {
9239                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9240                    return;
9241                }
9242                int stackId = task.stack.mStackId;
9243                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9244                // in crop windows resize mode or if the task size is affected by the docked stack
9245                // changing size. No need to update configuration.
9246                if (bounds != null && task.inCropWindowsResizeMode()
9247                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9248                    mWindowManager.scrollTask(task.taskId, bounds);
9249                    return;
9250                }
9251
9252                // Place the task in the right stack if it isn't there already based on
9253                // the requested bounds.
9254                // The stack transition logic is:
9255                // - a null bounds on a freeform task moves that task to fullscreen
9256                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9257                //   that task to freeform
9258                // - otherwise the task is not moved
9259                if (!StackId.isTaskResizeAllowed(stackId)) {
9260                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9261                }
9262                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9263                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9264                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9265                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9266                }
9267                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9268                if (stackId != task.stack.mStackId) {
9269                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9270                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9271                    preserveWindow = false;
9272                }
9273
9274                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9275                        false /* deferResume */);
9276            }
9277        } finally {
9278            Binder.restoreCallingIdentity(ident);
9279        }
9280    }
9281
9282    @Override
9283    public Rect getTaskBounds(int taskId) {
9284        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9285        long ident = Binder.clearCallingIdentity();
9286        Rect rect = new Rect();
9287        try {
9288            synchronized (this) {
9289                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9290                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9291                if (task == null) {
9292                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9293                    return rect;
9294                }
9295                if (task.stack != null) {
9296                    // Return the bounds from window manager since it will be adjusted for various
9297                    // things like the presense of a docked stack for tasks that aren't resizeable.
9298                    mWindowManager.getTaskBounds(task.taskId, rect);
9299                } else {
9300                    // Task isn't in window manager yet since it isn't associated with a stack.
9301                    // Return the persist value from activity manager
9302                    if (task.mBounds != null) {
9303                        rect.set(task.mBounds);
9304                    } else if (task.mLastNonFullscreenBounds != null) {
9305                        rect.set(task.mLastNonFullscreenBounds);
9306                    }
9307                }
9308            }
9309        } finally {
9310            Binder.restoreCallingIdentity(ident);
9311        }
9312        return rect;
9313    }
9314
9315    @Override
9316    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9317        if (userId != UserHandle.getCallingUserId()) {
9318            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9319                    "getTaskDescriptionIcon");
9320        }
9321        final File passedIconFile = new File(filePath);
9322        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9323                passedIconFile.getName());
9324        if (!legitIconFile.getPath().equals(filePath)
9325                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9326            throw new IllegalArgumentException("Bad file path: " + filePath
9327                    + " passed for userId " + userId);
9328        }
9329        return mRecentTasks.getTaskDescriptionIcon(filePath);
9330    }
9331
9332    @Override
9333    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9334            throws RemoteException {
9335        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9336                opts.getCustomInPlaceResId() == 0) {
9337            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9338                    "with valid animation");
9339        }
9340        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9341        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9342                opts.getCustomInPlaceResId());
9343        mWindowManager.executeAppTransition();
9344    }
9345
9346    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9347            boolean removeFromRecents) {
9348        if (removeFromRecents) {
9349            mRecentTasks.remove(tr);
9350            tr.removedFromRecents();
9351        }
9352        ComponentName component = tr.getBaseIntent().getComponent();
9353        if (component == null) {
9354            Slog.w(TAG, "No component for base intent of task: " + tr);
9355            return;
9356        }
9357
9358        // Find any running services associated with this app and stop if needed.
9359        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9360
9361        if (!killProcess) {
9362            return;
9363        }
9364
9365        // Determine if the process(es) for this task should be killed.
9366        final String pkg = component.getPackageName();
9367        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9368        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9369        for (int i = 0; i < pmap.size(); i++) {
9370
9371            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9372            for (int j = 0; j < uids.size(); j++) {
9373                ProcessRecord proc = uids.valueAt(j);
9374                if (proc.userId != tr.userId) {
9375                    // Don't kill process for a different user.
9376                    continue;
9377                }
9378                if (proc == mHomeProcess) {
9379                    // Don't kill the home process along with tasks from the same package.
9380                    continue;
9381                }
9382                if (!proc.pkgList.containsKey(pkg)) {
9383                    // Don't kill process that is not associated with this task.
9384                    continue;
9385                }
9386
9387                for (int k = 0; k < proc.activities.size(); k++) {
9388                    TaskRecord otherTask = proc.activities.get(k).task;
9389                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9390                        // Don't kill process(es) that has an activity in a different task that is
9391                        // also in recents.
9392                        return;
9393                    }
9394                }
9395
9396                if (proc.foregroundServices) {
9397                    // Don't kill process(es) with foreground service.
9398                    return;
9399                }
9400
9401                // Add process to kill list.
9402                procsToKill.add(proc);
9403            }
9404        }
9405
9406        // Kill the running processes.
9407        for (int i = 0; i < procsToKill.size(); i++) {
9408            ProcessRecord pr = procsToKill.get(i);
9409            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9410                    && pr.curReceiver == null) {
9411                pr.kill("remove task", true);
9412            } else {
9413                // We delay killing processes that are not in the background or running a receiver.
9414                pr.waitingToKill = "remove task";
9415            }
9416        }
9417    }
9418
9419    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9420        // Remove all tasks with activities in the specified package from the list of recent tasks
9421        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9422            TaskRecord tr = mRecentTasks.get(i);
9423            if (tr.userId != userId) continue;
9424
9425            ComponentName cn = tr.intent.getComponent();
9426            if (cn != null && cn.getPackageName().equals(packageName)) {
9427                // If the package name matches, remove the task.
9428                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9429            }
9430        }
9431    }
9432
9433    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9434            int userId) {
9435
9436        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9437            TaskRecord tr = mRecentTasks.get(i);
9438            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9439                continue;
9440            }
9441
9442            ComponentName cn = tr.intent.getComponent();
9443            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9444                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9445            if (sameComponent) {
9446                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9447            }
9448        }
9449    }
9450
9451    /**
9452     * Removes the task with the specified task id.
9453     *
9454     * @param taskId Identifier of the task to be removed.
9455     * @param killProcess Kill any process associated with the task if possible.
9456     * @param removeFromRecents Whether to also remove the task from recents.
9457     * @return Returns true if the given task was found and removed.
9458     */
9459    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9460            boolean removeFromRecents) {
9461        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9462                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9463        if (tr != null) {
9464            tr.removeTaskActivitiesLocked();
9465            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9466            if (tr.isPersistable) {
9467                notifyTaskPersisterLocked(null, true);
9468            }
9469            return true;
9470        }
9471        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9472        return false;
9473    }
9474
9475    @Override
9476    public void removeStack(int stackId) {
9477        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9478        if (stackId == HOME_STACK_ID) {
9479            throw new IllegalArgumentException("Removing home stack is not allowed.");
9480        }
9481
9482        synchronized (this) {
9483            final long ident = Binder.clearCallingIdentity();
9484            try {
9485                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9486                if (stack == null) {
9487                    return;
9488                }
9489                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9490                for (int i = tasks.size() - 1; i >= 0; i--) {
9491                    removeTaskByIdLocked(
9492                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9493                }
9494            } finally {
9495                Binder.restoreCallingIdentity(ident);
9496            }
9497        }
9498    }
9499
9500    @Override
9501    public boolean removeTask(int taskId) {
9502        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9503        synchronized (this) {
9504            final long ident = Binder.clearCallingIdentity();
9505            try {
9506                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9507            } finally {
9508                Binder.restoreCallingIdentity(ident);
9509            }
9510        }
9511    }
9512
9513    /**
9514     * TODO: Add mController hook
9515     */
9516    @Override
9517    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9519
9520        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9521        synchronized(this) {
9522            moveTaskToFrontLocked(taskId, flags, bOptions);
9523        }
9524    }
9525
9526    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9527        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9528
9529        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9530                Binder.getCallingUid(), -1, -1, "Task to front")) {
9531            ActivityOptions.abort(options);
9532            return;
9533        }
9534        final long origId = Binder.clearCallingIdentity();
9535        try {
9536            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9537            if (task == null) {
9538                Slog.d(TAG, "Could not find task for id: "+ taskId);
9539                return;
9540            }
9541            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9542                mStackSupervisor.showLockTaskToast();
9543                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9544                return;
9545            }
9546            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9547            if (prev != null && prev.isRecentsActivity()) {
9548                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9549            }
9550            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9551                    false /* forceNonResizable */);
9552        } finally {
9553            Binder.restoreCallingIdentity(origId);
9554        }
9555        ActivityOptions.abort(options);
9556    }
9557
9558    /**
9559     * Moves an activity, and all of the other activities within the same task, to the bottom
9560     * of the history stack.  The activity's order within the task is unchanged.
9561     *
9562     * @param token A reference to the activity we wish to move
9563     * @param nonRoot If false then this only works if the activity is the root
9564     *                of a task; if true it will work for any activity in a task.
9565     * @return Returns true if the move completed, false if not.
9566     */
9567    @Override
9568    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9569        enforceNotIsolatedCaller("moveActivityTaskToBack");
9570        synchronized(this) {
9571            final long origId = Binder.clearCallingIdentity();
9572            try {
9573                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9574                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9575                if (task != null) {
9576                    if (mStackSupervisor.isLockedTask(task)) {
9577                        mStackSupervisor.showLockTaskToast();
9578                        return false;
9579                    }
9580                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9581                }
9582            } finally {
9583                Binder.restoreCallingIdentity(origId);
9584            }
9585        }
9586        return false;
9587    }
9588
9589    @Override
9590    public void moveTaskBackwards(int task) {
9591        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9592                "moveTaskBackwards()");
9593
9594        synchronized(this) {
9595            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9596                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9597                return;
9598            }
9599            final long origId = Binder.clearCallingIdentity();
9600            moveTaskBackwardsLocked(task);
9601            Binder.restoreCallingIdentity(origId);
9602        }
9603    }
9604
9605    private final void moveTaskBackwardsLocked(int task) {
9606        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9607    }
9608
9609    @Override
9610    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9611            IActivityContainerCallback callback) throws RemoteException {
9612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9613        synchronized (this) {
9614            if (parentActivityToken == null) {
9615                throw new IllegalArgumentException("parent token must not be null");
9616            }
9617            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9618            if (r == null) {
9619                return null;
9620            }
9621            if (callback == null) {
9622                throw new IllegalArgumentException("callback must not be null");
9623            }
9624            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9625        }
9626    }
9627
9628    @Override
9629    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9630        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9631        synchronized (this) {
9632            mStackSupervisor.deleteActivityContainer(container);
9633        }
9634    }
9635
9636    @Override
9637    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9638        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9639        synchronized (this) {
9640            final int stackId = mStackSupervisor.getNextStackId();
9641            final ActivityStack stack =
9642                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9643            if (stack == null) {
9644                return null;
9645            }
9646            return stack.mActivityContainer;
9647        }
9648    }
9649
9650    @Override
9651    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9652        synchronized (this) {
9653            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9654            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9655                return stack.mActivityContainer.getDisplayId();
9656            }
9657            return Display.DEFAULT_DISPLAY;
9658        }
9659    }
9660
9661    @Override
9662    public int getActivityStackId(IBinder token) throws RemoteException {
9663        synchronized (this) {
9664            ActivityStack stack = ActivityRecord.getStackLocked(token);
9665            if (stack == null) {
9666                return INVALID_STACK_ID;
9667            }
9668            return stack.mStackId;
9669        }
9670    }
9671
9672    @Override
9673    public void exitFreeformMode(IBinder token) throws RemoteException {
9674        synchronized (this) {
9675            long ident = Binder.clearCallingIdentity();
9676            try {
9677                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9678                if (r == null) {
9679                    throw new IllegalArgumentException(
9680                            "exitFreeformMode: No activity record matching token=" + token);
9681                }
9682                final ActivityStack stack = r.getStackLocked(token);
9683                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9684                    throw new IllegalStateException(
9685                            "exitFreeformMode: You can only go fullscreen from freeform.");
9686                }
9687                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9688                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9689                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    @Override
9697    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9698        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9699        if (stackId == HOME_STACK_ID) {
9700            throw new IllegalArgumentException(
9701                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9702        }
9703        synchronized (this) {
9704            long ident = Binder.clearCallingIdentity();
9705            try {
9706                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9707                        + " to stackId=" + stackId + " toTop=" + toTop);
9708                if (stackId == DOCKED_STACK_ID) {
9709                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9710                            null /* initialBounds */);
9711                }
9712                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9713                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9714                if (result && stackId == DOCKED_STACK_ID) {
9715                    // If task moved to docked stack - show recents if needed.
9716                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9717                            "moveTaskToDockedStack");
9718                }
9719            } finally {
9720                Binder.restoreCallingIdentity(ident);
9721            }
9722        }
9723    }
9724
9725    @Override
9726    public void swapDockedAndFullscreenStack() throws RemoteException {
9727        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9728        synchronized (this) {
9729            long ident = Binder.clearCallingIdentity();
9730            try {
9731                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9732                        FULLSCREEN_WORKSPACE_STACK_ID);
9733                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9734                        : null;
9735                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9736                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9737                        : null;
9738                if (topTask == null || tasks == null || tasks.size() == 0) {
9739                    Slog.w(TAG,
9740                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9741                    return;
9742                }
9743
9744                // TODO: App transition
9745                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9746
9747                // Defer the resume so resume/pausing while moving stacks is dangerous.
9748                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9749                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9750                        ANIMATE, true /* deferResume */);
9751                final int size = tasks.size();
9752                for (int i = 0; i < size; i++) {
9753                    final int id = tasks.get(i).taskId;
9754                    if (id == topTask.taskId) {
9755                        continue;
9756                    }
9757                    mStackSupervisor.moveTaskToStackLocked(id,
9758                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9759                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9760                }
9761
9762                // Because we deferred the resume, to avoid conflicts with stack switches while
9763                // resuming, we need to do it after all the tasks are moved.
9764                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9765                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9766
9767                mWindowManager.executeAppTransition();
9768            } finally {
9769                Binder.restoreCallingIdentity(ident);
9770            }
9771        }
9772    }
9773
9774    /**
9775     * Moves the input task to the docked stack.
9776     *
9777     * @param taskId Id of task to move.
9778     * @param createMode The mode the docked stack should be created in if it doesn't exist
9779     *                   already. See
9780     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9781     *                   and
9782     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9783     * @param toTop If the task and stack should be moved to the top.
9784     * @param animate Whether we should play an animation for the moving the task
9785     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9786     *                      docked stack. Pass {@code null} to use default bounds.
9787     */
9788    @Override
9789    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9790            Rect initialBounds, boolean moveHomeStackFront) {
9791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9792        synchronized (this) {
9793            long ident = Binder.clearCallingIdentity();
9794            try {
9795                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9796                        + " to createMode=" + createMode + " toTop=" + toTop);
9797                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9798                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9799                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9800                        animate, DEFER_RESUME);
9801                if (moved) {
9802                    if (moveHomeStackFront) {
9803                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9804                    }
9805                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9806                }
9807                return moved;
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811        }
9812    }
9813
9814    /**
9815     * Moves the top activity in the input stackId to the pinned stack.
9816     *
9817     * @param stackId Id of stack to move the top activity to pinned stack.
9818     * @param bounds Bounds to use for pinned stack.
9819     *
9820     * @return True if the top activity of the input stack was successfully moved to the pinned
9821     *          stack.
9822     */
9823    @Override
9824    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9825        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9826        synchronized (this) {
9827            if (!mSupportsPictureInPicture) {
9828                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9829                        + "Device doesn't support picture-in-pciture mode");
9830            }
9831
9832            long ident = Binder.clearCallingIdentity();
9833            try {
9834                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9835            } finally {
9836                Binder.restoreCallingIdentity(ident);
9837            }
9838        }
9839    }
9840
9841    @Override
9842    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9843            boolean preserveWindows, boolean animate, int animationDuration) {
9844        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9845        long ident = Binder.clearCallingIdentity();
9846        try {
9847            synchronized (this) {
9848                if (animate) {
9849                    if (stackId == PINNED_STACK_ID) {
9850                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9851                    } else {
9852                        throw new IllegalArgumentException("Stack: " + stackId
9853                                + " doesn't support animated resize.");
9854                    }
9855                } else {
9856                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9857                            null /* tempTaskInsetBounds */, preserveWindows,
9858                            allowResizeInDockedMode, !DEFER_RESUME);
9859                }
9860            }
9861        } finally {
9862            Binder.restoreCallingIdentity(ident);
9863        }
9864    }
9865
9866    @Override
9867    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9868            Rect tempDockedTaskInsetBounds,
9869            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9871                "resizeDockedStack()");
9872        long ident = Binder.clearCallingIdentity();
9873        try {
9874            synchronized (this) {
9875                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9876                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9877                        PRESERVE_WINDOWS);
9878            }
9879        } finally {
9880            Binder.restoreCallingIdentity(ident);
9881        }
9882    }
9883
9884    @Override
9885    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9886        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9887                "resizePinnedStack()");
9888        final long ident = Binder.clearCallingIdentity();
9889        try {
9890            synchronized (this) {
9891                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9892            }
9893        } finally {
9894            Binder.restoreCallingIdentity(ident);
9895        }
9896    }
9897
9898    @Override
9899    public void positionTaskInStack(int taskId, int stackId, int position) {
9900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9901        if (stackId == HOME_STACK_ID) {
9902            throw new IllegalArgumentException(
9903                    "positionTaskInStack: Attempt to change the position of task "
9904                    + taskId + " in/to home stack");
9905        }
9906        synchronized (this) {
9907            long ident = Binder.clearCallingIdentity();
9908            try {
9909                if (DEBUG_STACK) Slog.d(TAG_STACK,
9910                        "positionTaskInStack: positioning task=" + taskId
9911                        + " in stackId=" + stackId + " at position=" + position);
9912                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9913            } finally {
9914                Binder.restoreCallingIdentity(ident);
9915            }
9916        }
9917    }
9918
9919    @Override
9920    public List<StackInfo> getAllStackInfos() {
9921        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9922        long ident = Binder.clearCallingIdentity();
9923        try {
9924            synchronized (this) {
9925                return mStackSupervisor.getAllStackInfosLocked();
9926            }
9927        } finally {
9928            Binder.restoreCallingIdentity(ident);
9929        }
9930    }
9931
9932    @Override
9933    public StackInfo getStackInfo(int stackId) {
9934        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9935        long ident = Binder.clearCallingIdentity();
9936        try {
9937            synchronized (this) {
9938                return mStackSupervisor.getStackInfoLocked(stackId);
9939            }
9940        } finally {
9941            Binder.restoreCallingIdentity(ident);
9942        }
9943    }
9944
9945    @Override
9946    public boolean isInHomeStack(int taskId) {
9947        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9948        long ident = Binder.clearCallingIdentity();
9949        try {
9950            synchronized (this) {
9951                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9952                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9953                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9954            }
9955        } finally {
9956            Binder.restoreCallingIdentity(ident);
9957        }
9958    }
9959
9960    @Override
9961    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9962        synchronized(this) {
9963            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9964        }
9965    }
9966
9967    @Override
9968    public void updateDeviceOwner(String packageName) {
9969        final int callingUid = Binder.getCallingUid();
9970        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9971            throw new SecurityException("updateDeviceOwner called from non-system process");
9972        }
9973        synchronized (this) {
9974            mDeviceOwnerName = packageName;
9975        }
9976    }
9977
9978    @Override
9979    public void updateLockTaskPackages(int userId, String[] packages) {
9980        final int callingUid = Binder.getCallingUid();
9981        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9982            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9983                    "updateLockTaskPackages()");
9984        }
9985        synchronized (this) {
9986            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9987                    Arrays.toString(packages));
9988            mLockTaskPackages.put(userId, packages);
9989            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9990        }
9991    }
9992
9993
9994    void startLockTaskModeLocked(TaskRecord task) {
9995        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9996        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9997            return;
9998        }
9999
10000        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10001        // is initiated by system after the pinning request was shown and locked mode is initiated
10002        // by an authorized app directly
10003        final int callingUid = Binder.getCallingUid();
10004        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            if (!isSystemInitiated) {
10008                task.mLockTaskUid = callingUid;
10009                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10010                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10011                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10012                    StatusBarManagerInternal statusBarManager =
10013                            LocalServices.getService(StatusBarManagerInternal.class);
10014                    if (statusBarManager != null) {
10015                        statusBarManager.showScreenPinningRequest(task.taskId);
10016                    }
10017                    return;
10018                }
10019
10020                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10021                if (stack == null || task != stack.topTask()) {
10022                    throw new IllegalArgumentException("Invalid task, not in foreground");
10023                }
10024            }
10025            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10026                    "Locking fully");
10027            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10028                    ActivityManager.LOCK_TASK_MODE_PINNED :
10029                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10030                    "startLockTask", true);
10031        } finally {
10032            Binder.restoreCallingIdentity(ident);
10033        }
10034    }
10035
10036    @Override
10037    public void startLockTaskMode(int taskId) {
10038        synchronized (this) {
10039            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10040            if (task != null) {
10041                startLockTaskModeLocked(task);
10042            }
10043        }
10044    }
10045
10046    @Override
10047    public void startLockTaskMode(IBinder token) {
10048        synchronized (this) {
10049            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10050            if (r == null) {
10051                return;
10052            }
10053            final TaskRecord task = r.task;
10054            if (task != null) {
10055                startLockTaskModeLocked(task);
10056            }
10057        }
10058    }
10059
10060    @Override
10061    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10062        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10063        // This makes inner call to look as if it was initiated by system.
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                startLockTaskMode(taskId);
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(ident);
10071        }
10072    }
10073
10074    @Override
10075    public void stopLockTaskMode() {
10076        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10077        if (lockTask == null) {
10078            // Our work here is done.
10079            return;
10080        }
10081
10082        final int callingUid = Binder.getCallingUid();
10083        final int lockTaskUid = lockTask.mLockTaskUid;
10084        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10085        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10086            // Done.
10087            return;
10088        } else {
10089            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10090            // It is possible lockTaskMode was started by the system process because
10091            // android:lockTaskMode is set to a locking value in the application manifest
10092            // instead of the app calling startLockTaskMode. In this case
10093            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10094            // {@link TaskRecord.effectiveUid} instead. Also caller with
10095            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10096            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10097                    && callingUid != lockTaskUid
10098                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10099                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10100                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10101            }
10102        }
10103        long ident = Binder.clearCallingIdentity();
10104        try {
10105            Log.d(TAG, "stopLockTaskMode");
10106            // Stop lock task
10107            synchronized (this) {
10108                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10109                        "stopLockTask", true);
10110            }
10111        } finally {
10112            Binder.restoreCallingIdentity(ident);
10113        }
10114    }
10115
10116    /**
10117     * This API should be called by SystemUI only when user perform certain action to dismiss
10118     * lock task mode. We should only dismiss pinned lock task mode in this case.
10119     */
10120    @Override
10121    public void stopSystemLockTaskMode() throws RemoteException {
10122        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10123            stopLockTaskMode();
10124        } else {
10125            mStackSupervisor.showLockTaskToast();
10126        }
10127    }
10128
10129    @Override
10130    public boolean isInLockTaskMode() {
10131        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10132    }
10133
10134    @Override
10135    public int getLockTaskModeState() {
10136        synchronized (this) {
10137            return mStackSupervisor.getLockTaskModeState();
10138        }
10139    }
10140
10141    @Override
10142    public void showLockTaskEscapeMessage(IBinder token) {
10143        synchronized (this) {
10144            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10145            if (r == null) {
10146                return;
10147            }
10148            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10149        }
10150    }
10151
10152    // =========================================================
10153    // CONTENT PROVIDERS
10154    // =========================================================
10155
10156    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10157        List<ProviderInfo> providers = null;
10158        try {
10159            providers = AppGlobals.getPackageManager()
10160                    .queryContentProviders(app.processName, app.uid,
10161                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10162                                    | MATCH_DEBUG_TRIAGED_MISSING)
10163                    .getList();
10164        } catch (RemoteException ex) {
10165        }
10166        if (DEBUG_MU) Slog.v(TAG_MU,
10167                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10168        int userId = app.userId;
10169        if (providers != null) {
10170            int N = providers.size();
10171            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10172            for (int i=0; i<N; i++) {
10173                ProviderInfo cpi =
10174                    (ProviderInfo)providers.get(i);
10175                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10176                        cpi.name, cpi.flags);
10177                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10178                    // This is a singleton provider, but a user besides the
10179                    // default user is asking to initialize a process it runs
10180                    // in...  well, no, it doesn't actually run in this process,
10181                    // it runs in the process of the default user.  Get rid of it.
10182                    providers.remove(i);
10183                    N--;
10184                    i--;
10185                    continue;
10186                }
10187
10188                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10189                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10190                if (cpr == null) {
10191                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10192                    mProviderMap.putProviderByClass(comp, cpr);
10193                }
10194                if (DEBUG_MU) Slog.v(TAG_MU,
10195                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10196                app.pubProviders.put(cpi.name, cpr);
10197                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10198                    // Don't add this if it is a platform component that is marked
10199                    // to run in multiple processes, because this is actually
10200                    // part of the framework so doesn't make sense to track as a
10201                    // separate apk in the process.
10202                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10203                            mProcessStats);
10204                }
10205                notifyPackageUse(cpi.applicationInfo.packageName,
10206                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10207            }
10208        }
10209        return providers;
10210    }
10211
10212    /**
10213     * Check if {@link ProcessRecord} has a possible chance at accessing the
10214     * given {@link ProviderInfo}. Final permission checking is always done
10215     * in {@link ContentProvider}.
10216     */
10217    private final String checkContentProviderPermissionLocked(
10218            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10219        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10220        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10221        boolean checkedGrants = false;
10222        if (checkUser) {
10223            // Looking for cross-user grants before enforcing the typical cross-users permissions
10224            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10225            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10226                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10227                    return null;
10228                }
10229                checkedGrants = true;
10230            }
10231            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10232                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10233            if (userId != tmpTargetUserId) {
10234                // When we actually went to determine the final targer user ID, this ended
10235                // up different than our initial check for the authority.  This is because
10236                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10237                // SELF.  So we need to re-check the grants again.
10238                checkedGrants = false;
10239            }
10240        }
10241        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10242                cpi.applicationInfo.uid, cpi.exported)
10243                == PackageManager.PERMISSION_GRANTED) {
10244            return null;
10245        }
10246        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10247                cpi.applicationInfo.uid, cpi.exported)
10248                == PackageManager.PERMISSION_GRANTED) {
10249            return null;
10250        }
10251
10252        PathPermission[] pps = cpi.pathPermissions;
10253        if (pps != null) {
10254            int i = pps.length;
10255            while (i > 0) {
10256                i--;
10257                PathPermission pp = pps[i];
10258                String pprperm = pp.getReadPermission();
10259                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10260                        cpi.applicationInfo.uid, cpi.exported)
10261                        == PackageManager.PERMISSION_GRANTED) {
10262                    return null;
10263                }
10264                String ppwperm = pp.getWritePermission();
10265                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10266                        cpi.applicationInfo.uid, cpi.exported)
10267                        == PackageManager.PERMISSION_GRANTED) {
10268                    return null;
10269                }
10270            }
10271        }
10272        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10273            return null;
10274        }
10275
10276        String msg;
10277        if (!cpi.exported) {
10278            msg = "Permission Denial: opening provider " + cpi.name
10279                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10280                    + ", uid=" + callingUid + ") that is not exported from uid "
10281                    + cpi.applicationInfo.uid;
10282        } else {
10283            msg = "Permission Denial: opening provider " + cpi.name
10284                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10285                    + ", uid=" + callingUid + ") requires "
10286                    + cpi.readPermission + " or " + cpi.writePermission;
10287        }
10288        Slog.w(TAG, msg);
10289        return msg;
10290    }
10291
10292    /**
10293     * Returns if the ContentProvider has granted a uri to callingUid
10294     */
10295    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10296        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10297        if (perms != null) {
10298            for (int i=perms.size()-1; i>=0; i--) {
10299                GrantUri grantUri = perms.keyAt(i);
10300                if (grantUri.sourceUserId == userId || !checkUser) {
10301                    if (matchesProvider(grantUri.uri, cpi)) {
10302                        return true;
10303                    }
10304                }
10305            }
10306        }
10307        return false;
10308    }
10309
10310    /**
10311     * Returns true if the uri authority is one of the authorities specified in the provider.
10312     */
10313    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10314        String uriAuth = uri.getAuthority();
10315        String cpiAuth = cpi.authority;
10316        if (cpiAuth.indexOf(';') == -1) {
10317            return cpiAuth.equals(uriAuth);
10318        }
10319        String[] cpiAuths = cpiAuth.split(";");
10320        int length = cpiAuths.length;
10321        for (int i = 0; i < length; i++) {
10322            if (cpiAuths[i].equals(uriAuth)) return true;
10323        }
10324        return false;
10325    }
10326
10327    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10328            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10329        if (r != null) {
10330            for (int i=0; i<r.conProviders.size(); i++) {
10331                ContentProviderConnection conn = r.conProviders.get(i);
10332                if (conn.provider == cpr) {
10333                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10334                            "Adding provider requested by "
10335                            + r.processName + " from process "
10336                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10337                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10338                    if (stable) {
10339                        conn.stableCount++;
10340                        conn.numStableIncs++;
10341                    } else {
10342                        conn.unstableCount++;
10343                        conn.numUnstableIncs++;
10344                    }
10345                    return conn;
10346                }
10347            }
10348            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10349            if (stable) {
10350                conn.stableCount = 1;
10351                conn.numStableIncs = 1;
10352            } else {
10353                conn.unstableCount = 1;
10354                conn.numUnstableIncs = 1;
10355            }
10356            cpr.connections.add(conn);
10357            r.conProviders.add(conn);
10358            startAssociationLocked(r.uid, r.processName, r.curProcState,
10359                    cpr.uid, cpr.name, cpr.info.processName);
10360            return conn;
10361        }
10362        cpr.addExternalProcessHandleLocked(externalProcessToken);
10363        return null;
10364    }
10365
10366    boolean decProviderCountLocked(ContentProviderConnection conn,
10367            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10368        if (conn != null) {
10369            cpr = conn.provider;
10370            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10371                    "Removing provider requested by "
10372                    + conn.client.processName + " from process "
10373                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10374                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10375            if (stable) {
10376                conn.stableCount--;
10377            } else {
10378                conn.unstableCount--;
10379            }
10380            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10381                cpr.connections.remove(conn);
10382                conn.client.conProviders.remove(conn);
10383                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10384                    // The client is more important than last activity -- note the time this
10385                    // is happening, so we keep the old provider process around a bit as last
10386                    // activity to avoid thrashing it.
10387                    if (cpr.proc != null) {
10388                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10389                    }
10390                }
10391                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10392                return true;
10393            }
10394            return false;
10395        }
10396        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10397        return false;
10398    }
10399
10400    private void checkTime(long startTime, String where) {
10401        long now = SystemClock.uptimeMillis();
10402        if ((now-startTime) > 50) {
10403            // If we are taking more than 50ms, log about it.
10404            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10405        }
10406    }
10407
10408    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10409            String name, IBinder token, boolean stable, int userId) {
10410        ContentProviderRecord cpr;
10411        ContentProviderConnection conn = null;
10412        ProviderInfo cpi = null;
10413
10414        synchronized(this) {
10415            long startTime = SystemClock.uptimeMillis();
10416
10417            ProcessRecord r = null;
10418            if (caller != null) {
10419                r = getRecordForAppLocked(caller);
10420                if (r == null) {
10421                    throw new SecurityException(
10422                            "Unable to find app for caller " + caller
10423                          + " (pid=" + Binder.getCallingPid()
10424                          + ") when getting content provider " + name);
10425                }
10426            }
10427
10428            boolean checkCrossUser = true;
10429
10430            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10431
10432            // First check if this content provider has been published...
10433            cpr = mProviderMap.getProviderByName(name, userId);
10434            // If that didn't work, check if it exists for user 0 and then
10435            // verify that it's a singleton provider before using it.
10436            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10437                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10438                if (cpr != null) {
10439                    cpi = cpr.info;
10440                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10441                            cpi.name, cpi.flags)
10442                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10443                        userId = UserHandle.USER_SYSTEM;
10444                        checkCrossUser = false;
10445                    } else {
10446                        cpr = null;
10447                        cpi = null;
10448                    }
10449                }
10450            }
10451
10452            boolean providerRunning = cpr != null;
10453            if (providerRunning) {
10454                cpi = cpr.info;
10455                String msg;
10456                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10457                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10458                        != null) {
10459                    throw new SecurityException(msg);
10460                }
10461                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10462
10463                if (r != null && cpr.canRunHere(r)) {
10464                    // This provider has been published or is in the process
10465                    // of being published...  but it is also allowed to run
10466                    // in the caller's process, so don't make a connection
10467                    // and just let the caller instantiate its own instance.
10468                    ContentProviderHolder holder = cpr.newHolder(null);
10469                    // don't give caller the provider object, it needs
10470                    // to make its own.
10471                    holder.provider = null;
10472                    return holder;
10473                }
10474
10475                final long origId = Binder.clearCallingIdentity();
10476
10477                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10478
10479                // In this case the provider instance already exists, so we can
10480                // return it right away.
10481                conn = incProviderCountLocked(r, cpr, token, stable);
10482                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10483                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10484                        // If this is a perceptible app accessing the provider,
10485                        // make sure to count it as being accessed and thus
10486                        // back up on the LRU list.  This is good because
10487                        // content providers are often expensive to start.
10488                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10489                        updateLruProcessLocked(cpr.proc, false, null);
10490                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10491                    }
10492                }
10493
10494                if (cpr.proc != null) {
10495                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10496                    boolean success = updateOomAdjLocked(cpr.proc);
10497                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10498                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10499                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10500                    // NOTE: there is still a race here where a signal could be
10501                    // pending on the process even though we managed to update its
10502                    // adj level.  Not sure what to do about this, but at least
10503                    // the race is now smaller.
10504                    if (!success) {
10505                        // Uh oh...  it looks like the provider's process
10506                        // has been killed on us.  We need to wait for a new
10507                        // process to be started, and make sure its death
10508                        // doesn't kill our process.
10509                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10510                                + " is crashing; detaching " + r);
10511                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10512                        checkTime(startTime, "getContentProviderImpl: before appDied");
10513                        appDiedLocked(cpr.proc);
10514                        checkTime(startTime, "getContentProviderImpl: after appDied");
10515                        if (!lastRef) {
10516                            // This wasn't the last ref our process had on
10517                            // the provider...  we have now been killed, bail.
10518                            return null;
10519                        }
10520                        providerRunning = false;
10521                        conn = null;
10522                    }
10523                }
10524
10525                Binder.restoreCallingIdentity(origId);
10526            }
10527
10528            if (!providerRunning) {
10529                try {
10530                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10531                    cpi = AppGlobals.getPackageManager().
10532                        resolveContentProvider(name,
10533                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10534                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10535                } catch (RemoteException ex) {
10536                }
10537                if (cpi == null) {
10538                    return null;
10539                }
10540                // If the provider is a singleton AND
10541                // (it's a call within the same user || the provider is a
10542                // privileged app)
10543                // Then allow connecting to the singleton provider
10544                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10545                        cpi.name, cpi.flags)
10546                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10547                if (singleton) {
10548                    userId = UserHandle.USER_SYSTEM;
10549                }
10550                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10551                checkTime(startTime, "getContentProviderImpl: got app info for user");
10552
10553                String msg;
10554                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10555                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10556                        != null) {
10557                    throw new SecurityException(msg);
10558                }
10559                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10560
10561                if (!mProcessesReady
10562                        && !cpi.processName.equals("system")) {
10563                    // If this content provider does not run in the system
10564                    // process, and the system is not yet ready to run other
10565                    // processes, then fail fast instead of hanging.
10566                    throw new IllegalArgumentException(
10567                            "Attempt to launch content provider before system ready");
10568                }
10569
10570                // Make sure that the user who owns this provider is running.  If not,
10571                // we don't want to allow it to run.
10572                if (!mUserController.isUserRunningLocked(userId, 0)) {
10573                    Slog.w(TAG, "Unable to launch app "
10574                            + cpi.applicationInfo.packageName + "/"
10575                            + cpi.applicationInfo.uid + " for provider "
10576                            + name + ": user " + userId + " is stopped");
10577                    return null;
10578                }
10579
10580                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10581                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10582                cpr = mProviderMap.getProviderByClass(comp, userId);
10583                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10584                final boolean firstClass = cpr == null;
10585                if (firstClass) {
10586                    final long ident = Binder.clearCallingIdentity();
10587
10588                    // If permissions need a review before any of the app components can run,
10589                    // we return no provider and launch a review activity if the calling app
10590                    // is in the foreground.
10591                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10592                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10593                            return null;
10594                        }
10595                    }
10596
10597                    try {
10598                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10599                        ApplicationInfo ai =
10600                            AppGlobals.getPackageManager().
10601                                getApplicationInfo(
10602                                        cpi.applicationInfo.packageName,
10603                                        STOCK_PM_FLAGS, userId);
10604                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10605                        if (ai == null) {
10606                            Slog.w(TAG, "No package info for content provider "
10607                                    + cpi.name);
10608                            return null;
10609                        }
10610                        ai = getAppInfoForUser(ai, userId);
10611                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10612                    } catch (RemoteException ex) {
10613                        // pm is in same process, this will never happen.
10614                    } finally {
10615                        Binder.restoreCallingIdentity(ident);
10616                    }
10617                }
10618
10619                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10620
10621                if (r != null && cpr.canRunHere(r)) {
10622                    // If this is a multiprocess provider, then just return its
10623                    // info and allow the caller to instantiate it.  Only do
10624                    // this if the provider is the same user as the caller's
10625                    // process, or can run as root (so can be in any process).
10626                    return cpr.newHolder(null);
10627                }
10628
10629                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10630                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10631                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10632
10633                // This is single process, and our app is now connecting to it.
10634                // See if we are already in the process of launching this
10635                // provider.
10636                final int N = mLaunchingProviders.size();
10637                int i;
10638                for (i = 0; i < N; i++) {
10639                    if (mLaunchingProviders.get(i) == cpr) {
10640                        break;
10641                    }
10642                }
10643
10644                // If the provider is not already being launched, then get it
10645                // started.
10646                if (i >= N) {
10647                    final long origId = Binder.clearCallingIdentity();
10648
10649                    try {
10650                        // Content provider is now in use, its package can't be stopped.
10651                        try {
10652                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10653                            AppGlobals.getPackageManager().setPackageStoppedState(
10654                                    cpr.appInfo.packageName, false, userId);
10655                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10656                        } catch (RemoteException e) {
10657                        } catch (IllegalArgumentException e) {
10658                            Slog.w(TAG, "Failed trying to unstop package "
10659                                    + cpr.appInfo.packageName + ": " + e);
10660                        }
10661
10662                        // Use existing process if already started
10663                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10664                        ProcessRecord proc = getProcessRecordLocked(
10665                                cpi.processName, cpr.appInfo.uid, false);
10666                        if (proc != null && proc.thread != null) {
10667                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10668                                    "Installing in existing process " + proc);
10669                            if (!proc.pubProviders.containsKey(cpi.name)) {
10670                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10671                                proc.pubProviders.put(cpi.name, cpr);
10672                                try {
10673                                    proc.thread.scheduleInstallProvider(cpi);
10674                                } catch (RemoteException e) {
10675                                }
10676                            }
10677                        } else {
10678                            checkTime(startTime, "getContentProviderImpl: before start process");
10679                            proc = startProcessLocked(cpi.processName,
10680                                    cpr.appInfo, false, 0, "content provider",
10681                                    new ComponentName(cpi.applicationInfo.packageName,
10682                                            cpi.name), false, false, false);
10683                            checkTime(startTime, "getContentProviderImpl: after start process");
10684                            if (proc == null) {
10685                                Slog.w(TAG, "Unable to launch app "
10686                                        + cpi.applicationInfo.packageName + "/"
10687                                        + cpi.applicationInfo.uid + " for provider "
10688                                        + name + ": process is bad");
10689                                return null;
10690                            }
10691                        }
10692                        cpr.launchingApp = proc;
10693                        mLaunchingProviders.add(cpr);
10694                    } finally {
10695                        Binder.restoreCallingIdentity(origId);
10696                    }
10697                }
10698
10699                checkTime(startTime, "getContentProviderImpl: updating data structures");
10700
10701                // Make sure the provider is published (the same provider class
10702                // may be published under multiple names).
10703                if (firstClass) {
10704                    mProviderMap.putProviderByClass(comp, cpr);
10705                }
10706
10707                mProviderMap.putProviderByName(name, cpr);
10708                conn = incProviderCountLocked(r, cpr, token, stable);
10709                if (conn != null) {
10710                    conn.waiting = true;
10711                }
10712            }
10713            checkTime(startTime, "getContentProviderImpl: done!");
10714        }
10715
10716        // Wait for the provider to be published...
10717        synchronized (cpr) {
10718            while (cpr.provider == null) {
10719                if (cpr.launchingApp == null) {
10720                    Slog.w(TAG, "Unable to launch app "
10721                            + cpi.applicationInfo.packageName + "/"
10722                            + cpi.applicationInfo.uid + " for provider "
10723                            + name + ": launching app became null");
10724                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10725                            UserHandle.getUserId(cpi.applicationInfo.uid),
10726                            cpi.applicationInfo.packageName,
10727                            cpi.applicationInfo.uid, name);
10728                    return null;
10729                }
10730                try {
10731                    if (DEBUG_MU) Slog.v(TAG_MU,
10732                            "Waiting to start provider " + cpr
10733                            + " launchingApp=" + cpr.launchingApp);
10734                    if (conn != null) {
10735                        conn.waiting = true;
10736                    }
10737                    cpr.wait();
10738                } catch (InterruptedException ex) {
10739                } finally {
10740                    if (conn != null) {
10741                        conn.waiting = false;
10742                    }
10743                }
10744            }
10745        }
10746        return cpr != null ? cpr.newHolder(conn) : null;
10747    }
10748
10749    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10750            ProcessRecord r, final int userId) {
10751        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10752                cpi.packageName, userId)) {
10753
10754            final boolean callerForeground = r == null || r.setSchedGroup
10755                    != ProcessList.SCHED_GROUP_BACKGROUND;
10756
10757            // Show a permission review UI only for starting from a foreground app
10758            if (!callerForeground) {
10759                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10760                        + cpi.packageName + " requires a permissions review");
10761                return false;
10762            }
10763
10764            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10765            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10766                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10767            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10768
10769            if (DEBUG_PERMISSIONS_REVIEW) {
10770                Slog.i(TAG, "u" + userId + " Launching permission review "
10771                        + "for package " + cpi.packageName);
10772            }
10773
10774            final UserHandle userHandle = new UserHandle(userId);
10775            mHandler.post(new Runnable() {
10776                @Override
10777                public void run() {
10778                    mContext.startActivityAsUser(intent, userHandle);
10779                }
10780            });
10781
10782            return false;
10783        }
10784
10785        return true;
10786    }
10787
10788    PackageManagerInternal getPackageManagerInternalLocked() {
10789        if (mPackageManagerInt == null) {
10790            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10791        }
10792        return mPackageManagerInt;
10793    }
10794
10795    @Override
10796    public final ContentProviderHolder getContentProvider(
10797            IApplicationThread caller, String name, int userId, boolean stable) {
10798        enforceNotIsolatedCaller("getContentProvider");
10799        if (caller == null) {
10800            String msg = "null IApplicationThread when getting content provider "
10801                    + name;
10802            Slog.w(TAG, msg);
10803            throw new SecurityException(msg);
10804        }
10805        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10806        // with cross-user grant.
10807        return getContentProviderImpl(caller, name, null, stable, userId);
10808    }
10809
10810    public ContentProviderHolder getContentProviderExternal(
10811            String name, int userId, IBinder token) {
10812        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10813            "Do not have permission in call getContentProviderExternal()");
10814        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10815                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10816        return getContentProviderExternalUnchecked(name, token, userId);
10817    }
10818
10819    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10820            IBinder token, int userId) {
10821        return getContentProviderImpl(null, name, token, true, userId);
10822    }
10823
10824    /**
10825     * Drop a content provider from a ProcessRecord's bookkeeping
10826     */
10827    public void removeContentProvider(IBinder connection, boolean stable) {
10828        enforceNotIsolatedCaller("removeContentProvider");
10829        long ident = Binder.clearCallingIdentity();
10830        try {
10831            synchronized (this) {
10832                ContentProviderConnection conn;
10833                try {
10834                    conn = (ContentProviderConnection)connection;
10835                } catch (ClassCastException e) {
10836                    String msg ="removeContentProvider: " + connection
10837                            + " not a ContentProviderConnection";
10838                    Slog.w(TAG, msg);
10839                    throw new IllegalArgumentException(msg);
10840                }
10841                if (conn == null) {
10842                    throw new NullPointerException("connection is null");
10843                }
10844                if (decProviderCountLocked(conn, null, null, stable)) {
10845                    updateOomAdjLocked();
10846                }
10847            }
10848        } finally {
10849            Binder.restoreCallingIdentity(ident);
10850        }
10851    }
10852
10853    public void removeContentProviderExternal(String name, IBinder token) {
10854        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10855            "Do not have permission in call removeContentProviderExternal()");
10856        int userId = UserHandle.getCallingUserId();
10857        long ident = Binder.clearCallingIdentity();
10858        try {
10859            removeContentProviderExternalUnchecked(name, token, userId);
10860        } finally {
10861            Binder.restoreCallingIdentity(ident);
10862        }
10863    }
10864
10865    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10866        synchronized (this) {
10867            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10868            if(cpr == null) {
10869                //remove from mProvidersByClass
10870                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10871                return;
10872            }
10873
10874            //update content provider record entry info
10875            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10876            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10877            if (localCpr.hasExternalProcessHandles()) {
10878                if (localCpr.removeExternalProcessHandleLocked(token)) {
10879                    updateOomAdjLocked();
10880                } else {
10881                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10882                            + " with no external reference for token: "
10883                            + token + ".");
10884                }
10885            } else {
10886                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10887                        + " with no external references.");
10888            }
10889        }
10890    }
10891
10892    public final void publishContentProviders(IApplicationThread caller,
10893            List<ContentProviderHolder> providers) {
10894        if (providers == null) {
10895            return;
10896        }
10897
10898        enforceNotIsolatedCaller("publishContentProviders");
10899        synchronized (this) {
10900            final ProcessRecord r = getRecordForAppLocked(caller);
10901            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10902            if (r == null) {
10903                throw new SecurityException(
10904                        "Unable to find app for caller " + caller
10905                      + " (pid=" + Binder.getCallingPid()
10906                      + ") when publishing content providers");
10907            }
10908
10909            final long origId = Binder.clearCallingIdentity();
10910
10911            final int N = providers.size();
10912            for (int i = 0; i < N; i++) {
10913                ContentProviderHolder src = providers.get(i);
10914                if (src == null || src.info == null || src.provider == null) {
10915                    continue;
10916                }
10917                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10918                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10919                if (dst != null) {
10920                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10921                    mProviderMap.putProviderByClass(comp, dst);
10922                    String names[] = dst.info.authority.split(";");
10923                    for (int j = 0; j < names.length; j++) {
10924                        mProviderMap.putProviderByName(names[j], dst);
10925                    }
10926
10927                    int launchingCount = mLaunchingProviders.size();
10928                    int j;
10929                    boolean wasInLaunchingProviders = false;
10930                    for (j = 0; j < launchingCount; j++) {
10931                        if (mLaunchingProviders.get(j) == dst) {
10932                            mLaunchingProviders.remove(j);
10933                            wasInLaunchingProviders = true;
10934                            j--;
10935                            launchingCount--;
10936                        }
10937                    }
10938                    if (wasInLaunchingProviders) {
10939                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10940                    }
10941                    synchronized (dst) {
10942                        dst.provider = src.provider;
10943                        dst.proc = r;
10944                        dst.notifyAll();
10945                    }
10946                    updateOomAdjLocked(r);
10947                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10948                            src.info.authority);
10949                }
10950            }
10951
10952            Binder.restoreCallingIdentity(origId);
10953        }
10954    }
10955
10956    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10957        ContentProviderConnection conn;
10958        try {
10959            conn = (ContentProviderConnection)connection;
10960        } catch (ClassCastException e) {
10961            String msg ="refContentProvider: " + connection
10962                    + " not a ContentProviderConnection";
10963            Slog.w(TAG, msg);
10964            throw new IllegalArgumentException(msg);
10965        }
10966        if (conn == null) {
10967            throw new NullPointerException("connection is null");
10968        }
10969
10970        synchronized (this) {
10971            if (stable > 0) {
10972                conn.numStableIncs += stable;
10973            }
10974            stable = conn.stableCount + stable;
10975            if (stable < 0) {
10976                throw new IllegalStateException("stableCount < 0: " + stable);
10977            }
10978
10979            if (unstable > 0) {
10980                conn.numUnstableIncs += unstable;
10981            }
10982            unstable = conn.unstableCount + unstable;
10983            if (unstable < 0) {
10984                throw new IllegalStateException("unstableCount < 0: " + unstable);
10985            }
10986
10987            if ((stable+unstable) <= 0) {
10988                throw new IllegalStateException("ref counts can't go to zero here: stable="
10989                        + stable + " unstable=" + unstable);
10990            }
10991            conn.stableCount = stable;
10992            conn.unstableCount = unstable;
10993            return !conn.dead;
10994        }
10995    }
10996
10997    public void unstableProviderDied(IBinder connection) {
10998        ContentProviderConnection conn;
10999        try {
11000            conn = (ContentProviderConnection)connection;
11001        } catch (ClassCastException e) {
11002            String msg ="refContentProvider: " + connection
11003                    + " not a ContentProviderConnection";
11004            Slog.w(TAG, msg);
11005            throw new IllegalArgumentException(msg);
11006        }
11007        if (conn == null) {
11008            throw new NullPointerException("connection is null");
11009        }
11010
11011        // Safely retrieve the content provider associated with the connection.
11012        IContentProvider provider;
11013        synchronized (this) {
11014            provider = conn.provider.provider;
11015        }
11016
11017        if (provider == null) {
11018            // Um, yeah, we're way ahead of you.
11019            return;
11020        }
11021
11022        // Make sure the caller is being honest with us.
11023        if (provider.asBinder().pingBinder()) {
11024            // Er, no, still looks good to us.
11025            synchronized (this) {
11026                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11027                        + " says " + conn + " died, but we don't agree");
11028                return;
11029            }
11030        }
11031
11032        // Well look at that!  It's dead!
11033        synchronized (this) {
11034            if (conn.provider.provider != provider) {
11035                // But something changed...  good enough.
11036                return;
11037            }
11038
11039            ProcessRecord proc = conn.provider.proc;
11040            if (proc == null || proc.thread == null) {
11041                // Seems like the process is already cleaned up.
11042                return;
11043            }
11044
11045            // As far as we're concerned, this is just like receiving a
11046            // death notification...  just a bit prematurely.
11047            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11048                    + ") early provider death");
11049            final long ident = Binder.clearCallingIdentity();
11050            try {
11051                appDiedLocked(proc);
11052            } finally {
11053                Binder.restoreCallingIdentity(ident);
11054            }
11055        }
11056    }
11057
11058    @Override
11059    public void appNotRespondingViaProvider(IBinder connection) {
11060        enforceCallingPermission(
11061                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11062
11063        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11064        if (conn == null) {
11065            Slog.w(TAG, "ContentProviderConnection is null");
11066            return;
11067        }
11068
11069        final ProcessRecord host = conn.provider.proc;
11070        if (host == null) {
11071            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11072            return;
11073        }
11074
11075        mHandler.post(new Runnable() {
11076            @Override
11077            public void run() {
11078                mAppErrors.appNotResponding(host, null, null, false,
11079                        "ContentProvider not responding");
11080            }
11081        });
11082    }
11083
11084    public final void installSystemProviders() {
11085        List<ProviderInfo> providers;
11086        synchronized (this) {
11087            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11088            providers = generateApplicationProvidersLocked(app);
11089            if (providers != null) {
11090                for (int i=providers.size()-1; i>=0; i--) {
11091                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11092                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11093                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11094                                + ": not system .apk");
11095                        providers.remove(i);
11096                    }
11097                }
11098            }
11099        }
11100        if (providers != null) {
11101            mSystemThread.installSystemProviders(providers);
11102        }
11103
11104        mCoreSettingsObserver = new CoreSettingsObserver(this);
11105        mFontScaleSettingObserver = new FontScaleSettingObserver();
11106
11107        //mUsageStatsService.monitorPackages();
11108    }
11109
11110    private void startPersistentApps(int matchFlags) {
11111        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11112
11113        synchronized (this) {
11114            try {
11115                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11116                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11117                for (ApplicationInfo app : apps) {
11118                    if (!"android".equals(app.packageName)) {
11119                        addAppLocked(app, false, null /* ABI override */);
11120                    }
11121                }
11122            } catch (RemoteException ex) {
11123            }
11124        }
11125    }
11126
11127    /**
11128     * When a user is unlocked, we need to install encryption-unaware providers
11129     * belonging to any running apps.
11130     */
11131    private void installEncryptionUnawareProviders(int userId) {
11132        // We're only interested in providers that are encryption unaware, and
11133        // we don't care about uninstalled apps, since there's no way they're
11134        // running at this point.
11135        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11136
11137        synchronized (this) {
11138            final int NP = mProcessNames.getMap().size();
11139            for (int ip = 0; ip < NP; ip++) {
11140                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11141                final int NA = apps.size();
11142                for (int ia = 0; ia < NA; ia++) {
11143                    final ProcessRecord app = apps.valueAt(ia);
11144                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11145
11146                    final int NG = app.pkgList.size();
11147                    for (int ig = 0; ig < NG; ig++) {
11148                        try {
11149                            final String pkgName = app.pkgList.keyAt(ig);
11150                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11151                                    .getPackageInfo(pkgName, matchFlags, userId);
11152                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11153                                for (ProviderInfo provInfo : pkgInfo.providers) {
11154                                    if (Objects.equals(provInfo.processName, app.processName)) {
11155                                        Log.v(TAG, "Installing " + provInfo);
11156                                        app.thread.scheduleInstallProvider(provInfo);
11157                                    } else {
11158                                        Log.v(TAG, "Skipping " + provInfo);
11159                                    }
11160                                }
11161                            }
11162                        } catch (RemoteException ignored) {
11163                        }
11164                    }
11165                }
11166            }
11167        }
11168    }
11169
11170    /**
11171     * Allows apps to retrieve the MIME type of a URI.
11172     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11173     * users, then it does not need permission to access the ContentProvider.
11174     * Either, it needs cross-user uri grants.
11175     *
11176     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11177     *
11178     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11179     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11180     */
11181    public String getProviderMimeType(Uri uri, int userId) {
11182        enforceNotIsolatedCaller("getProviderMimeType");
11183        final String name = uri.getAuthority();
11184        int callingUid = Binder.getCallingUid();
11185        int callingPid = Binder.getCallingPid();
11186        long ident = 0;
11187        boolean clearedIdentity = false;
11188        synchronized (this) {
11189            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11190        }
11191        if (canClearIdentity(callingPid, callingUid, userId)) {
11192            clearedIdentity = true;
11193            ident = Binder.clearCallingIdentity();
11194        }
11195        ContentProviderHolder holder = null;
11196        try {
11197            holder = getContentProviderExternalUnchecked(name, null, userId);
11198            if (holder != null) {
11199                return holder.provider.getType(uri);
11200            }
11201        } catch (RemoteException e) {
11202            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11203            return null;
11204        } finally {
11205            // We need to clear the identity to call removeContentProviderExternalUnchecked
11206            if (!clearedIdentity) {
11207                ident = Binder.clearCallingIdentity();
11208            }
11209            try {
11210                if (holder != null) {
11211                    removeContentProviderExternalUnchecked(name, null, userId);
11212                }
11213            } finally {
11214                Binder.restoreCallingIdentity(ident);
11215            }
11216        }
11217
11218        return null;
11219    }
11220
11221    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11222        if (UserHandle.getUserId(callingUid) == userId) {
11223            return true;
11224        }
11225        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11226                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11227                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11228                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11229                return true;
11230        }
11231        return false;
11232    }
11233
11234    // =========================================================
11235    // GLOBAL MANAGEMENT
11236    // =========================================================
11237
11238    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11239            boolean isolated, int isolatedUid) {
11240        String proc = customProcess != null ? customProcess : info.processName;
11241        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11242        final int userId = UserHandle.getUserId(info.uid);
11243        int uid = info.uid;
11244        if (isolated) {
11245            if (isolatedUid == 0) {
11246                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11247                while (true) {
11248                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11249                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11250                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11251                    }
11252                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11253                    mNextIsolatedProcessUid++;
11254                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11255                        // No process for this uid, use it.
11256                        break;
11257                    }
11258                    stepsLeft--;
11259                    if (stepsLeft <= 0) {
11260                        return null;
11261                    }
11262                }
11263            } else {
11264                // Special case for startIsolatedProcess (internal only), where
11265                // the uid of the isolated process is specified by the caller.
11266                uid = isolatedUid;
11267            }
11268        }
11269        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11270        if (!mBooted && !mBooting
11271                && userId == UserHandle.USER_SYSTEM
11272                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11273            r.persistent = true;
11274        }
11275        addProcessNameLocked(r);
11276        return r;
11277    }
11278
11279    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11280            String abiOverride) {
11281        ProcessRecord app;
11282        if (!isolated) {
11283            app = getProcessRecordLocked(info.processName, info.uid, true);
11284        } else {
11285            app = null;
11286        }
11287
11288        if (app == null) {
11289            app = newProcessRecordLocked(info, null, isolated, 0);
11290            updateLruProcessLocked(app, false, null);
11291            updateOomAdjLocked();
11292        }
11293
11294        // This package really, really can not be stopped.
11295        try {
11296            AppGlobals.getPackageManager().setPackageStoppedState(
11297                    info.packageName, false, UserHandle.getUserId(app.uid));
11298        } catch (RemoteException e) {
11299        } catch (IllegalArgumentException e) {
11300            Slog.w(TAG, "Failed trying to unstop package "
11301                    + info.packageName + ": " + e);
11302        }
11303
11304        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11305            app.persistent = true;
11306            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11307        }
11308        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11309            mPersistentStartingProcesses.add(app);
11310            startProcessLocked(app, "added application", app.processName, abiOverride,
11311                    null /* entryPoint */, null /* entryPointArgs */);
11312        }
11313
11314        return app;
11315    }
11316
11317    public void unhandledBack() {
11318        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11319                "unhandledBack()");
11320
11321        synchronized(this) {
11322            final long origId = Binder.clearCallingIdentity();
11323            try {
11324                getFocusedStack().unhandledBackLocked();
11325            } finally {
11326                Binder.restoreCallingIdentity(origId);
11327            }
11328        }
11329    }
11330
11331    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11332        enforceNotIsolatedCaller("openContentUri");
11333        final int userId = UserHandle.getCallingUserId();
11334        String name = uri.getAuthority();
11335        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11336        ParcelFileDescriptor pfd = null;
11337        if (cph != null) {
11338            // We record the binder invoker's uid in thread-local storage before
11339            // going to the content provider to open the file.  Later, in the code
11340            // that handles all permissions checks, we look for this uid and use
11341            // that rather than the Activity Manager's own uid.  The effect is that
11342            // we do the check against the caller's permissions even though it looks
11343            // to the content provider like the Activity Manager itself is making
11344            // the request.
11345            Binder token = new Binder();
11346            sCallerIdentity.set(new Identity(
11347                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11348            try {
11349                pfd = cph.provider.openFile(null, uri, "r", null, token);
11350            } catch (FileNotFoundException e) {
11351                // do nothing; pfd will be returned null
11352            } finally {
11353                // Ensure that whatever happens, we clean up the identity state
11354                sCallerIdentity.remove();
11355                // Ensure we're done with the provider.
11356                removeContentProviderExternalUnchecked(name, null, userId);
11357            }
11358        } else {
11359            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11360        }
11361        return pfd;
11362    }
11363
11364    // Actually is sleeping or shutting down or whatever else in the future
11365    // is an inactive state.
11366    public boolean isSleepingOrShuttingDown() {
11367        return isSleeping() || mShuttingDown;
11368    }
11369
11370    public boolean isSleeping() {
11371        return mSleeping;
11372    }
11373
11374    void onWakefulnessChanged(int wakefulness) {
11375        synchronized(this) {
11376            mWakefulness = wakefulness;
11377            updateSleepIfNeededLocked();
11378        }
11379    }
11380
11381    void finishRunningVoiceLocked() {
11382        if (mRunningVoice != null) {
11383            mRunningVoice = null;
11384            mVoiceWakeLock.release();
11385            updateSleepIfNeededLocked();
11386        }
11387    }
11388
11389    void startTimeTrackingFocusedActivityLocked() {
11390        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11391            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11392        }
11393    }
11394
11395    void updateSleepIfNeededLocked() {
11396        if (mSleeping && !shouldSleepLocked()) {
11397            mSleeping = false;
11398            startTimeTrackingFocusedActivityLocked();
11399            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11400            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11401            updateOomAdjLocked();
11402        } else if (!mSleeping && shouldSleepLocked()) {
11403            mSleeping = true;
11404            if (mCurAppTimeTracker != null) {
11405                mCurAppTimeTracker.stop();
11406            }
11407            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11408            mStackSupervisor.goingToSleepLocked();
11409            updateOomAdjLocked();
11410
11411            // Initialize the wake times of all processes.
11412            checkExcessivePowerUsageLocked(false);
11413            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11414            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11415            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11416        }
11417    }
11418
11419    private boolean shouldSleepLocked() {
11420        // Resume applications while running a voice interactor.
11421        if (mRunningVoice != null) {
11422            return false;
11423        }
11424
11425        // TODO: Transform the lock screen state into a sleep token instead.
11426        switch (mWakefulness) {
11427            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11428            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11429            case PowerManagerInternal.WAKEFULNESS_DOZING:
11430                // Pause applications whenever the lock screen is shown or any sleep
11431                // tokens have been acquired.
11432                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11433            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11434            default:
11435                // If we're asleep then pause applications unconditionally.
11436                return true;
11437        }
11438    }
11439
11440    /** Pokes the task persister. */
11441    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11442        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11443    }
11444
11445    /** Notifies all listeners when the task stack has changed. */
11446    void notifyTaskStackChangedLocked() {
11447        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11448        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11449        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11450        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11451    }
11452
11453    /** Notifies all listeners when an Activity is pinned. */
11454    void notifyActivityPinnedLocked() {
11455        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11456        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11457    }
11458
11459    /**
11460     * Notifies all listeners when an attempt was made to start an an activity that is already
11461     * running in the pinned stack and the activity was not actually started, but the task is
11462     * either brought to the front or a new Intent is delivered to it.
11463     */
11464    void notifyPinnedActivityRestartAttemptLocked() {
11465        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11466        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11467    }
11468
11469    /** Notifies all listeners when the pinned stack animation ends. */
11470    @Override
11471    public void notifyPinnedStackAnimationEnded() {
11472        synchronized (this) {
11473            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11474            mHandler.obtainMessage(
11475                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11476        }
11477    }
11478
11479    @Override
11480    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11481        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11482    }
11483
11484    @Override
11485    public boolean shutdown(int timeout) {
11486        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11487                != PackageManager.PERMISSION_GRANTED) {
11488            throw new SecurityException("Requires permission "
11489                    + android.Manifest.permission.SHUTDOWN);
11490        }
11491
11492        boolean timedout = false;
11493
11494        synchronized(this) {
11495            mShuttingDown = true;
11496            updateEventDispatchingLocked();
11497            timedout = mStackSupervisor.shutdownLocked(timeout);
11498        }
11499
11500        mAppOpsService.shutdown();
11501        if (mUsageStatsService != null) {
11502            mUsageStatsService.prepareShutdown();
11503        }
11504        mBatteryStatsService.shutdown();
11505        synchronized (this) {
11506            mProcessStats.shutdownLocked();
11507            notifyTaskPersisterLocked(null, true);
11508        }
11509
11510        return timedout;
11511    }
11512
11513    public final void activitySlept(IBinder token) {
11514        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11515
11516        final long origId = Binder.clearCallingIdentity();
11517
11518        synchronized (this) {
11519            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11520            if (r != null) {
11521                mStackSupervisor.activitySleptLocked(r);
11522            }
11523        }
11524
11525        Binder.restoreCallingIdentity(origId);
11526    }
11527
11528    private String lockScreenShownToString() {
11529        switch (mLockScreenShown) {
11530            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11531            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11532            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11533            default: return "Unknown=" + mLockScreenShown;
11534        }
11535    }
11536
11537    void logLockScreen(String msg) {
11538        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11539                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11540                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11541                + " mSleeping=" + mSleeping);
11542    }
11543
11544    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11545        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11546        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11547        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11548            boolean wasRunningVoice = mRunningVoice != null;
11549            mRunningVoice = session;
11550            if (!wasRunningVoice) {
11551                mVoiceWakeLock.acquire();
11552                updateSleepIfNeededLocked();
11553            }
11554        }
11555    }
11556
11557    private void updateEventDispatchingLocked() {
11558        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11559    }
11560
11561    public void setLockScreenShown(boolean showing, boolean occluded) {
11562        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11563                != PackageManager.PERMISSION_GRANTED) {
11564            throw new SecurityException("Requires permission "
11565                    + android.Manifest.permission.DEVICE_POWER);
11566        }
11567
11568        synchronized(this) {
11569            long ident = Binder.clearCallingIdentity();
11570            try {
11571                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11572                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11573                if (showing && occluded) {
11574                    // The lock screen is currently showing, but is occluded by a window that can
11575                    // show on top of the lock screen. In this can we want to dismiss the docked
11576                    // stack since it will be complicated/risky to try to put the activity on top
11577                    // of the lock screen in the right fullscreen configuration.
11578                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11579                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11580                }
11581
11582                updateSleepIfNeededLocked();
11583            } finally {
11584                Binder.restoreCallingIdentity(ident);
11585            }
11586        }
11587    }
11588
11589    @Override
11590    public void notifyLockedProfile(@UserIdInt int userId) {
11591        try {
11592            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11593                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11594            }
11595        } catch (RemoteException ex) {
11596            throw new SecurityException("Fail to check is caller a privileged app", ex);
11597        }
11598
11599        synchronized (this) {
11600            if (mStackSupervisor.isUserLockedProfile(userId)) {
11601                final long ident = Binder.clearCallingIdentity();
11602                try {
11603                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11604                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11605                        // If there is no device lock, we will show the profile's credential page.
11606                        mActivityStarter.showConfirmDeviceCredential(userId);
11607                    } else {
11608                        // Showing launcher to avoid user entering credential twice.
11609                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11610                    }
11611                } finally {
11612                    Binder.restoreCallingIdentity(ident);
11613                }
11614            }
11615        }
11616    }
11617
11618    @Override
11619    public void startConfirmDeviceCredentialIntent(Intent intent) {
11620        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11621        synchronized (this) {
11622            final long ident = Binder.clearCallingIdentity();
11623            try {
11624                mActivityStarter.startConfirmCredentialIntent(intent);
11625            } finally {
11626                Binder.restoreCallingIdentity(ident);
11627            }
11628        }
11629    }
11630
11631    @Override
11632    public void stopAppSwitches() {
11633        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11634                != PackageManager.PERMISSION_GRANTED) {
11635            throw new SecurityException("viewquires permission "
11636                    + android.Manifest.permission.STOP_APP_SWITCHES);
11637        }
11638
11639        synchronized(this) {
11640            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11641                    + APP_SWITCH_DELAY_TIME;
11642            mDidAppSwitch = false;
11643            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11644            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11645            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11646        }
11647    }
11648
11649    public void resumeAppSwitches() {
11650        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11651                != PackageManager.PERMISSION_GRANTED) {
11652            throw new SecurityException("Requires permission "
11653                    + android.Manifest.permission.STOP_APP_SWITCHES);
11654        }
11655
11656        synchronized(this) {
11657            // Note that we don't execute any pending app switches... we will
11658            // let those wait until either the timeout, or the next start
11659            // activity request.
11660            mAppSwitchesAllowedTime = 0;
11661        }
11662    }
11663
11664    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11665            int callingPid, int callingUid, String name) {
11666        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11667            return true;
11668        }
11669
11670        int perm = checkComponentPermission(
11671                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11672                sourceUid, -1, true);
11673        if (perm == PackageManager.PERMISSION_GRANTED) {
11674            return true;
11675        }
11676
11677        // If the actual IPC caller is different from the logical source, then
11678        // also see if they are allowed to control app switches.
11679        if (callingUid != -1 && callingUid != sourceUid) {
11680            perm = checkComponentPermission(
11681                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11682                    callingUid, -1, true);
11683            if (perm == PackageManager.PERMISSION_GRANTED) {
11684                return true;
11685            }
11686        }
11687
11688        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11689        return false;
11690    }
11691
11692    public void setDebugApp(String packageName, boolean waitForDebugger,
11693            boolean persistent) {
11694        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11695                "setDebugApp()");
11696
11697        long ident = Binder.clearCallingIdentity();
11698        try {
11699            // Note that this is not really thread safe if there are multiple
11700            // callers into it at the same time, but that's not a situation we
11701            // care about.
11702            if (persistent) {
11703                final ContentResolver resolver = mContext.getContentResolver();
11704                Settings.Global.putString(
11705                    resolver, Settings.Global.DEBUG_APP,
11706                    packageName);
11707                Settings.Global.putInt(
11708                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11709                    waitForDebugger ? 1 : 0);
11710            }
11711
11712            synchronized (this) {
11713                if (!persistent) {
11714                    mOrigDebugApp = mDebugApp;
11715                    mOrigWaitForDebugger = mWaitForDebugger;
11716                }
11717                mDebugApp = packageName;
11718                mWaitForDebugger = waitForDebugger;
11719                mDebugTransient = !persistent;
11720                if (packageName != null) {
11721                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11722                            false, UserHandle.USER_ALL, "set debug app");
11723                }
11724            }
11725        } finally {
11726            Binder.restoreCallingIdentity(ident);
11727        }
11728    }
11729
11730    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11731        synchronized (this) {
11732            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11733            if (!isDebuggable) {
11734                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11735                    throw new SecurityException("Process not debuggable: " + app.packageName);
11736                }
11737            }
11738
11739            mTrackAllocationApp = processName;
11740        }
11741    }
11742
11743    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11744        synchronized (this) {
11745            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11746            if (!isDebuggable) {
11747                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11748                    throw new SecurityException("Process not debuggable: " + app.packageName);
11749                }
11750            }
11751            mProfileApp = processName;
11752            mProfileFile = profilerInfo.profileFile;
11753            if (mProfileFd != null) {
11754                try {
11755                    mProfileFd.close();
11756                } catch (IOException e) {
11757                }
11758                mProfileFd = null;
11759            }
11760            mProfileFd = profilerInfo.profileFd;
11761            mSamplingInterval = profilerInfo.samplingInterval;
11762            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11763            mProfileType = 0;
11764        }
11765    }
11766
11767    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11768        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11769        if (!isDebuggable) {
11770            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11771                throw new SecurityException("Process not debuggable: " + app.packageName);
11772            }
11773        }
11774        mNativeDebuggingApp = processName;
11775    }
11776
11777    @Override
11778    public void setAlwaysFinish(boolean enabled) {
11779        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11780                "setAlwaysFinish()");
11781
11782        long ident = Binder.clearCallingIdentity();
11783        try {
11784            Settings.Global.putInt(
11785                    mContext.getContentResolver(),
11786                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11787
11788            synchronized (this) {
11789                mAlwaysFinishActivities = enabled;
11790            }
11791        } finally {
11792            Binder.restoreCallingIdentity(ident);
11793        }
11794    }
11795
11796    @Override
11797    public void setLenientBackgroundCheck(boolean enabled) {
11798        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11799                "setLenientBackgroundCheck()");
11800
11801        long ident = Binder.clearCallingIdentity();
11802        try {
11803            Settings.Global.putInt(
11804                    mContext.getContentResolver(),
11805                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11806
11807            synchronized (this) {
11808                mLenientBackgroundCheck = enabled;
11809            }
11810        } finally {
11811            Binder.restoreCallingIdentity(ident);
11812        }
11813    }
11814
11815    @Override
11816    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11817        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11818                "setActivityController()");
11819        synchronized (this) {
11820            mController = controller;
11821            mControllerIsAMonkey = imAMonkey;
11822            Watchdog.getInstance().setActivityController(controller);
11823        }
11824    }
11825
11826    @Override
11827    public void setUserIsMonkey(boolean userIsMonkey) {
11828        synchronized (this) {
11829            synchronized (mPidsSelfLocked) {
11830                final int callingPid = Binder.getCallingPid();
11831                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11832                if (precessRecord == null) {
11833                    throw new SecurityException("Unknown process: " + callingPid);
11834                }
11835                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11836                    throw new SecurityException("Only an instrumentation process "
11837                            + "with a UiAutomation can call setUserIsMonkey");
11838                }
11839            }
11840            mUserIsMonkey = userIsMonkey;
11841        }
11842    }
11843
11844    @Override
11845    public boolean isUserAMonkey() {
11846        synchronized (this) {
11847            // If there is a controller also implies the user is a monkey.
11848            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11849        }
11850    }
11851
11852    public void requestBugReport(int bugreportType) {
11853        String service = null;
11854        switch (bugreportType) {
11855            case ActivityManager.BUGREPORT_OPTION_FULL:
11856                service = "bugreport";
11857                break;
11858            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11859                service = "bugreportplus";
11860                break;
11861            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11862                service = "bugreportremote";
11863                break;
11864        }
11865        if (service == null) {
11866            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11867                    + bugreportType);
11868        }
11869        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11870        SystemProperties.set("ctl.start", service);
11871    }
11872
11873    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11874        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11875    }
11876
11877    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11878        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11879            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11880        }
11881        return KEY_DISPATCHING_TIMEOUT;
11882    }
11883
11884    @Override
11885    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11886        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11887                != PackageManager.PERMISSION_GRANTED) {
11888            throw new SecurityException("Requires permission "
11889                    + android.Manifest.permission.FILTER_EVENTS);
11890        }
11891        ProcessRecord proc;
11892        long timeout;
11893        synchronized (this) {
11894            synchronized (mPidsSelfLocked) {
11895                proc = mPidsSelfLocked.get(pid);
11896            }
11897            timeout = getInputDispatchingTimeoutLocked(proc);
11898        }
11899
11900        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11901            return -1;
11902        }
11903
11904        return timeout;
11905    }
11906
11907    /**
11908     * Handle input dispatching timeouts.
11909     * Returns whether input dispatching should be aborted or not.
11910     */
11911    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11912            final ActivityRecord activity, final ActivityRecord parent,
11913            final boolean aboveSystem, String reason) {
11914        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11915                != PackageManager.PERMISSION_GRANTED) {
11916            throw new SecurityException("Requires permission "
11917                    + android.Manifest.permission.FILTER_EVENTS);
11918        }
11919
11920        final String annotation;
11921        if (reason == null) {
11922            annotation = "Input dispatching timed out";
11923        } else {
11924            annotation = "Input dispatching timed out (" + reason + ")";
11925        }
11926
11927        if (proc != null) {
11928            synchronized (this) {
11929                if (proc.debugging) {
11930                    return false;
11931                }
11932
11933                if (mDidDexOpt) {
11934                    // Give more time since we were dexopting.
11935                    mDidDexOpt = false;
11936                    return false;
11937                }
11938
11939                if (proc.instrumentationClass != null) {
11940                    Bundle info = new Bundle();
11941                    info.putString("shortMsg", "keyDispatchingTimedOut");
11942                    info.putString("longMsg", annotation);
11943                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11944                    return true;
11945                }
11946            }
11947            mHandler.post(new Runnable() {
11948                @Override
11949                public void run() {
11950                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11951                }
11952            });
11953        }
11954
11955        return true;
11956    }
11957
11958    @Override
11959    public Bundle getAssistContextExtras(int requestType) {
11960        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11961                null, null, true /* focused */, true /* newSessionId */,
11962                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11963        if (pae == null) {
11964            return null;
11965        }
11966        synchronized (pae) {
11967            while (!pae.haveResult) {
11968                try {
11969                    pae.wait();
11970                } catch (InterruptedException e) {
11971                }
11972            }
11973        }
11974        synchronized (this) {
11975            buildAssistBundleLocked(pae, pae.result);
11976            mPendingAssistExtras.remove(pae);
11977            mUiHandler.removeCallbacks(pae);
11978        }
11979        return pae.extras;
11980    }
11981
11982    @Override
11983    public boolean isAssistDataAllowedOnCurrentActivity() {
11984        int userId;
11985        synchronized (this) {
11986            userId = mUserController.getCurrentUserIdLocked();
11987            ActivityRecord activity = getFocusedStack().topActivity();
11988            if (activity == null) {
11989                return false;
11990            }
11991            userId = activity.userId;
11992        }
11993        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11994                Context.DEVICE_POLICY_SERVICE);
11995        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11996    }
11997
11998    @Override
11999    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12000        long ident = Binder.clearCallingIdentity();
12001        try {
12002            synchronized (this) {
12003                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12004                ActivityRecord top = getFocusedStack().topActivity();
12005                if (top != caller) {
12006                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12007                            + " is not current top " + top);
12008                    return false;
12009                }
12010                if (!top.nowVisible) {
12011                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12012                            + " is not visible");
12013                    return false;
12014                }
12015            }
12016            AssistUtils utils = new AssistUtils(mContext);
12017            return utils.showSessionForActiveService(args,
12018                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12019        } finally {
12020            Binder.restoreCallingIdentity(ident);
12021        }
12022    }
12023
12024    @Override
12025    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12026            Bundle receiverExtras,
12027            IBinder activityToken, boolean focused, boolean newSessionId) {
12028        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12029                activityToken, focused, newSessionId,
12030                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12031                != null;
12032    }
12033
12034    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12035            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12036            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12037        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12038                "enqueueAssistContext()");
12039        synchronized (this) {
12040            ActivityRecord activity = getFocusedStack().topActivity();
12041            if (activity == null) {
12042                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12043                return null;
12044            }
12045            if (activity.app == null || activity.app.thread == null) {
12046                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12047                return null;
12048            }
12049            if (focused) {
12050                if (activityToken != null) {
12051                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12052                    if (activity != caller) {
12053                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12054                                + " is not current top " + activity);
12055                        return null;
12056                    }
12057                }
12058            } else {
12059                activity = ActivityRecord.forTokenLocked(activityToken);
12060                if (activity == null) {
12061                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12062                            + " couldn't be found");
12063                    return null;
12064                }
12065            }
12066
12067            PendingAssistExtras pae;
12068            Bundle extras = new Bundle();
12069            if (args != null) {
12070                extras.putAll(args);
12071            }
12072            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12073            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12074            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12075                    userHandle);
12076            // Increment the sessionId if necessary
12077            if (newSessionId) {
12078                mViSessionId++;
12079            }
12080            try {
12081                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12082                        requestType, mViSessionId);
12083                mPendingAssistExtras.add(pae);
12084                mUiHandler.postDelayed(pae, timeout);
12085            } catch (RemoteException e) {
12086                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12087                return null;
12088            }
12089            return pae;
12090        }
12091    }
12092
12093    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12094        IResultReceiver receiver;
12095        synchronized (this) {
12096            mPendingAssistExtras.remove(pae);
12097            receiver = pae.receiver;
12098        }
12099        if (receiver != null) {
12100            // Caller wants result sent back to them.
12101            Bundle sendBundle = new Bundle();
12102            // At least return the receiver extras
12103            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12104                    pae.receiverExtras);
12105            try {
12106                pae.receiver.send(0, sendBundle);
12107            } catch (RemoteException e) {
12108            }
12109        }
12110    }
12111
12112    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12113        if (result != null) {
12114            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12115        }
12116        if (pae.hint != null) {
12117            pae.extras.putBoolean(pae.hint, true);
12118        }
12119    }
12120
12121    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12122            AssistContent content, Uri referrer) {
12123        PendingAssistExtras pae = (PendingAssistExtras)token;
12124        synchronized (pae) {
12125            pae.result = extras;
12126            pae.structure = structure;
12127            pae.content = content;
12128            if (referrer != null) {
12129                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12130            }
12131            pae.haveResult = true;
12132            pae.notifyAll();
12133            if (pae.intent == null && pae.receiver == null) {
12134                // Caller is just waiting for the result.
12135                return;
12136            }
12137        }
12138
12139        // We are now ready to launch the assist activity.
12140        IResultReceiver sendReceiver = null;
12141        Bundle sendBundle = null;
12142        synchronized (this) {
12143            buildAssistBundleLocked(pae, extras);
12144            boolean exists = mPendingAssistExtras.remove(pae);
12145            mUiHandler.removeCallbacks(pae);
12146            if (!exists) {
12147                // Timed out.
12148                return;
12149            }
12150            if ((sendReceiver=pae.receiver) != null) {
12151                // Caller wants result sent back to them.
12152                sendBundle = new Bundle();
12153                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12154                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12155                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12156                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12157                        pae.receiverExtras);
12158            }
12159        }
12160        if (sendReceiver != null) {
12161            try {
12162                sendReceiver.send(0, sendBundle);
12163            } catch (RemoteException e) {
12164            }
12165            return;
12166        }
12167
12168        long ident = Binder.clearCallingIdentity();
12169        try {
12170            pae.intent.replaceExtras(pae.extras);
12171            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12172                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12173                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12174            closeSystemDialogs("assist");
12175            try {
12176                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12177            } catch (ActivityNotFoundException e) {
12178                Slog.w(TAG, "No activity to handle assist action.", e);
12179            }
12180        } finally {
12181            Binder.restoreCallingIdentity(ident);
12182        }
12183    }
12184
12185    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12186            Bundle args) {
12187        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12188                true /* focused */, true /* newSessionId */,
12189                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12190    }
12191
12192    public void registerProcessObserver(IProcessObserver observer) {
12193        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12194                "registerProcessObserver()");
12195        synchronized (this) {
12196            mProcessObservers.register(observer);
12197        }
12198    }
12199
12200    @Override
12201    public void unregisterProcessObserver(IProcessObserver observer) {
12202        synchronized (this) {
12203            mProcessObservers.unregister(observer);
12204        }
12205    }
12206
12207    @Override
12208    public void registerUidObserver(IUidObserver observer, int which) {
12209        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12210                "registerUidObserver()");
12211        synchronized (this) {
12212            mUidObservers.register(observer, which);
12213        }
12214    }
12215
12216    @Override
12217    public void unregisterUidObserver(IUidObserver observer) {
12218        synchronized (this) {
12219            mUidObservers.unregister(observer);
12220        }
12221    }
12222
12223    @Override
12224    public boolean convertFromTranslucent(IBinder token) {
12225        final long origId = Binder.clearCallingIdentity();
12226        try {
12227            synchronized (this) {
12228                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12229                if (r == null) {
12230                    return false;
12231                }
12232                final boolean translucentChanged = r.changeWindowTranslucency(true);
12233                if (translucentChanged) {
12234                    r.task.stack.releaseBackgroundResources(r);
12235                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12236                }
12237                mWindowManager.setAppFullscreen(token, true);
12238                return translucentChanged;
12239            }
12240        } finally {
12241            Binder.restoreCallingIdentity(origId);
12242        }
12243    }
12244
12245    @Override
12246    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12247        final long origId = Binder.clearCallingIdentity();
12248        try {
12249            synchronized (this) {
12250                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12251                if (r == null) {
12252                    return false;
12253                }
12254                int index = r.task.mActivities.lastIndexOf(r);
12255                if (index > 0) {
12256                    ActivityRecord under = r.task.mActivities.get(index - 1);
12257                    under.returningOptions = options;
12258                }
12259                final boolean translucentChanged = r.changeWindowTranslucency(false);
12260                if (translucentChanged) {
12261                    r.task.stack.convertActivityToTranslucent(r);
12262                }
12263                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12264                mWindowManager.setAppFullscreen(token, false);
12265                return translucentChanged;
12266            }
12267        } finally {
12268            Binder.restoreCallingIdentity(origId);
12269        }
12270    }
12271
12272    @Override
12273    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12274        final long origId = Binder.clearCallingIdentity();
12275        try {
12276            synchronized (this) {
12277                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12278                if (r != null) {
12279                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12280                }
12281            }
12282            return false;
12283        } finally {
12284            Binder.restoreCallingIdentity(origId);
12285        }
12286    }
12287
12288    @Override
12289    public boolean isBackgroundVisibleBehind(IBinder token) {
12290        final long origId = Binder.clearCallingIdentity();
12291        try {
12292            synchronized (this) {
12293                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12294                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12295                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12296                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12297                return visible;
12298            }
12299        } finally {
12300            Binder.restoreCallingIdentity(origId);
12301        }
12302    }
12303
12304    @Override
12305    public ActivityOptions getActivityOptions(IBinder token) {
12306        final long origId = Binder.clearCallingIdentity();
12307        try {
12308            synchronized (this) {
12309                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12310                if (r != null) {
12311                    final ActivityOptions activityOptions = r.pendingOptions;
12312                    r.pendingOptions = null;
12313                    return activityOptions;
12314                }
12315                return null;
12316            }
12317        } finally {
12318            Binder.restoreCallingIdentity(origId);
12319        }
12320    }
12321
12322    @Override
12323    public void setImmersive(IBinder token, boolean immersive) {
12324        synchronized(this) {
12325            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12326            if (r == null) {
12327                throw new IllegalArgumentException();
12328            }
12329            r.immersive = immersive;
12330
12331            // update associated state if we're frontmost
12332            if (r == mFocusedActivity) {
12333                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12334                applyUpdateLockStateLocked(r);
12335            }
12336        }
12337    }
12338
12339    @Override
12340    public boolean isImmersive(IBinder token) {
12341        synchronized (this) {
12342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12343            if (r == null) {
12344                throw new IllegalArgumentException();
12345            }
12346            return r.immersive;
12347        }
12348    }
12349
12350    @Override
12351    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12352        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12353            throw new UnsupportedOperationException("VR mode not supported on this device!");
12354        }
12355
12356        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12357
12358        ActivityRecord r;
12359        synchronized (this) {
12360            r = ActivityRecord.isInStackLocked(token);
12361        }
12362
12363        if (r == null) {
12364            throw new IllegalArgumentException();
12365        }
12366
12367        int err;
12368        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12369                VrManagerInternal.NO_ERROR) {
12370            return err;
12371        }
12372
12373        synchronized(this) {
12374            r.requestedVrComponent = (enabled) ? packageName : null;
12375
12376            // Update associated state if this activity is currently focused
12377            if (r == mFocusedActivity) {
12378                applyUpdateVrModeLocked(r);
12379            }
12380            return 0;
12381        }
12382    }
12383
12384    @Override
12385    public boolean isVrModePackageEnabled(ComponentName packageName) {
12386        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12387            throw new UnsupportedOperationException("VR mode not supported on this device!");
12388        }
12389
12390        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12391
12392        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12393                VrManagerInternal.NO_ERROR;
12394    }
12395
12396    public boolean isTopActivityImmersive() {
12397        enforceNotIsolatedCaller("startActivity");
12398        synchronized (this) {
12399            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12400            return (r != null) ? r.immersive : false;
12401        }
12402    }
12403
12404    @Override
12405    public boolean isTopOfTask(IBinder token) {
12406        synchronized (this) {
12407            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12408            if (r == null) {
12409                throw new IllegalArgumentException();
12410            }
12411            return r.task.getTopActivity() == r;
12412        }
12413    }
12414
12415    public final void enterSafeMode() {
12416        synchronized(this) {
12417            // It only makes sense to do this before the system is ready
12418            // and started launching other packages.
12419            if (!mSystemReady) {
12420                try {
12421                    AppGlobals.getPackageManager().enterSafeMode();
12422                } catch (RemoteException e) {
12423                }
12424            }
12425
12426            mSafeMode = true;
12427        }
12428    }
12429
12430    public final void showSafeModeOverlay() {
12431        View v = LayoutInflater.from(mContext).inflate(
12432                com.android.internal.R.layout.safe_mode, null);
12433        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12434        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12435        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12436        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12437        lp.gravity = Gravity.BOTTOM | Gravity.START;
12438        lp.format = v.getBackground().getOpacity();
12439        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12440                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12441        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12442        ((WindowManager)mContext.getSystemService(
12443                Context.WINDOW_SERVICE)).addView(v, lp);
12444    }
12445
12446    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12447        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12448            return;
12449        }
12450        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12451        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12452        synchronized (stats) {
12453            if (mBatteryStatsService.isOnBattery()) {
12454                mBatteryStatsService.enforceCallingPermission();
12455                int MY_UID = Binder.getCallingUid();
12456                final int uid;
12457                if (sender == null) {
12458                    uid = sourceUid;
12459                } else {
12460                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12461                }
12462                BatteryStatsImpl.Uid.Pkg pkg =
12463                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12464                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12465                pkg.noteWakeupAlarmLocked(tag);
12466            }
12467        }
12468    }
12469
12470    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12471        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12472            return;
12473        }
12474        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12475        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12476        synchronized (stats) {
12477            mBatteryStatsService.enforceCallingPermission();
12478            int MY_UID = Binder.getCallingUid();
12479            final int uid;
12480            if (sender == null) {
12481                uid = sourceUid;
12482            } else {
12483                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12484            }
12485            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12486        }
12487    }
12488
12489    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12490        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12491            return;
12492        }
12493        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12494        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12495        synchronized (stats) {
12496            mBatteryStatsService.enforceCallingPermission();
12497            int MY_UID = Binder.getCallingUid();
12498            final int uid;
12499            if (sender == null) {
12500                uid = sourceUid;
12501            } else {
12502                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12503            }
12504            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12505        }
12506    }
12507
12508    public boolean killPids(int[] pids, String pReason, boolean secure) {
12509        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12510            throw new SecurityException("killPids only available to the system");
12511        }
12512        String reason = (pReason == null) ? "Unknown" : pReason;
12513        // XXX Note: don't acquire main activity lock here, because the window
12514        // manager calls in with its locks held.
12515
12516        boolean killed = false;
12517        synchronized (mPidsSelfLocked) {
12518            int worstType = 0;
12519            for (int i=0; i<pids.length; i++) {
12520                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12521                if (proc != null) {
12522                    int type = proc.setAdj;
12523                    if (type > worstType) {
12524                        worstType = type;
12525                    }
12526                }
12527            }
12528
12529            // If the worst oom_adj is somewhere in the cached proc LRU range,
12530            // then constrain it so we will kill all cached procs.
12531            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12532                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12533                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12534            }
12535
12536            // If this is not a secure call, don't let it kill processes that
12537            // are important.
12538            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12539                worstType = ProcessList.SERVICE_ADJ;
12540            }
12541
12542            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12543            for (int i=0; i<pids.length; i++) {
12544                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12545                if (proc == null) {
12546                    continue;
12547                }
12548                int adj = proc.setAdj;
12549                if (adj >= worstType && !proc.killedByAm) {
12550                    proc.kill(reason, true);
12551                    killed = true;
12552                }
12553            }
12554        }
12555        return killed;
12556    }
12557
12558    @Override
12559    public void killUid(int appId, int userId, String reason) {
12560        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12561        synchronized (this) {
12562            final long identity = Binder.clearCallingIdentity();
12563            try {
12564                killPackageProcessesLocked(null, appId, userId,
12565                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12566                        reason != null ? reason : "kill uid");
12567            } finally {
12568                Binder.restoreCallingIdentity(identity);
12569            }
12570        }
12571    }
12572
12573    @Override
12574    public boolean killProcessesBelowForeground(String reason) {
12575        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12576            throw new SecurityException("killProcessesBelowForeground() only available to system");
12577        }
12578
12579        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12580    }
12581
12582    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12583        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12584            throw new SecurityException("killProcessesBelowAdj() only available to system");
12585        }
12586
12587        boolean killed = false;
12588        synchronized (mPidsSelfLocked) {
12589            final int size = mPidsSelfLocked.size();
12590            for (int i = 0; i < size; i++) {
12591                final int pid = mPidsSelfLocked.keyAt(i);
12592                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12593                if (proc == null) continue;
12594
12595                final int adj = proc.setAdj;
12596                if (adj > belowAdj && !proc.killedByAm) {
12597                    proc.kill(reason, true);
12598                    killed = true;
12599                }
12600            }
12601        }
12602        return killed;
12603    }
12604
12605    @Override
12606    public void hang(final IBinder who, boolean allowRestart) {
12607        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12608                != PackageManager.PERMISSION_GRANTED) {
12609            throw new SecurityException("Requires permission "
12610                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12611        }
12612
12613        final IBinder.DeathRecipient death = new DeathRecipient() {
12614            @Override
12615            public void binderDied() {
12616                synchronized (this) {
12617                    notifyAll();
12618                }
12619            }
12620        };
12621
12622        try {
12623            who.linkToDeath(death, 0);
12624        } catch (RemoteException e) {
12625            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12626            return;
12627        }
12628
12629        synchronized (this) {
12630            Watchdog.getInstance().setAllowRestart(allowRestart);
12631            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12632            synchronized (death) {
12633                while (who.isBinderAlive()) {
12634                    try {
12635                        death.wait();
12636                    } catch (InterruptedException e) {
12637                    }
12638                }
12639            }
12640            Watchdog.getInstance().setAllowRestart(true);
12641        }
12642    }
12643
12644    @Override
12645    public void restart() {
12646        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12647                != PackageManager.PERMISSION_GRANTED) {
12648            throw new SecurityException("Requires permission "
12649                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12650        }
12651
12652        Log.i(TAG, "Sending shutdown broadcast...");
12653
12654        BroadcastReceiver br = new BroadcastReceiver() {
12655            @Override public void onReceive(Context context, Intent intent) {
12656                // Now the broadcast is done, finish up the low-level shutdown.
12657                Log.i(TAG, "Shutting down activity manager...");
12658                shutdown(10000);
12659                Log.i(TAG, "Shutdown complete, restarting!");
12660                Process.killProcess(Process.myPid());
12661                System.exit(10);
12662            }
12663        };
12664
12665        // First send the high-level shut down broadcast.
12666        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12667        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12668        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12669        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12670        mContext.sendOrderedBroadcastAsUser(intent,
12671                UserHandle.ALL, null, br, mHandler, 0, null, null);
12672        */
12673        br.onReceive(mContext, intent);
12674    }
12675
12676    private long getLowRamTimeSinceIdle(long now) {
12677        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12678    }
12679
12680    @Override
12681    public void performIdleMaintenance() {
12682        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12683                != PackageManager.PERMISSION_GRANTED) {
12684            throw new SecurityException("Requires permission "
12685                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12686        }
12687
12688        synchronized (this) {
12689            final long now = SystemClock.uptimeMillis();
12690            final long timeSinceLastIdle = now - mLastIdleTime;
12691            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12692            mLastIdleTime = now;
12693            mLowRamTimeSinceLastIdle = 0;
12694            if (mLowRamStartTime != 0) {
12695                mLowRamStartTime = now;
12696            }
12697
12698            StringBuilder sb = new StringBuilder(128);
12699            sb.append("Idle maintenance over ");
12700            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12701            sb.append(" low RAM for ");
12702            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12703            Slog.i(TAG, sb.toString());
12704
12705            // If at least 1/3 of our time since the last idle period has been spent
12706            // with RAM low, then we want to kill processes.
12707            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12708
12709            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12710                ProcessRecord proc = mLruProcesses.get(i);
12711                if (proc.notCachedSinceIdle) {
12712                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12713                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12714                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12715                        if (doKilling && proc.initialIdlePss != 0
12716                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12717                            sb = new StringBuilder(128);
12718                            sb.append("Kill");
12719                            sb.append(proc.processName);
12720                            sb.append(" in idle maint: pss=");
12721                            sb.append(proc.lastPss);
12722                            sb.append(", swapPss=");
12723                            sb.append(proc.lastSwapPss);
12724                            sb.append(", initialPss=");
12725                            sb.append(proc.initialIdlePss);
12726                            sb.append(", period=");
12727                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12728                            sb.append(", lowRamPeriod=");
12729                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12730                            Slog.wtfQuiet(TAG, sb.toString());
12731                            proc.kill("idle maint (pss " + proc.lastPss
12732                                    + " from " + proc.initialIdlePss + ")", true);
12733                        }
12734                    }
12735                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12736                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12737                    proc.notCachedSinceIdle = true;
12738                    proc.initialIdlePss = 0;
12739                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12740                            mTestPssMode, isSleeping(), now);
12741                }
12742            }
12743
12744            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12745            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12746        }
12747    }
12748
12749    @Override
12750    public void sendIdleJobTrigger() {
12751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12752                != PackageManager.PERMISSION_GRANTED) {
12753            throw new SecurityException("Requires permission "
12754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12755        }
12756
12757        final long ident = Binder.clearCallingIdentity();
12758        try {
12759            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12760                    .setPackage("android")
12761                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12762            broadcastIntent(null, intent, null, null, 0, null, null, null,
12763                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12764        } finally {
12765            Binder.restoreCallingIdentity(ident);
12766        }
12767    }
12768
12769    private void retrieveSettings() {
12770        final ContentResolver resolver = mContext.getContentResolver();
12771        final boolean freeformWindowManagement =
12772                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12773                        || Settings.Global.getInt(
12774                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12775        final boolean supportsPictureInPicture =
12776                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12777
12778        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12779        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12780        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12781        final boolean alwaysFinishActivities =
12782                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12783        final boolean lenientBackgroundCheck =
12784                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12785        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12786        final boolean forceResizable = Settings.Global.getInt(
12787                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12788        // Transfer any global setting for forcing RTL layout, into a System Property
12789        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12790
12791        final Configuration configuration = new Configuration();
12792        Settings.System.getConfiguration(resolver, configuration);
12793        if (forceRtl) {
12794            // This will take care of setting the correct layout direction flags
12795            configuration.setLayoutDirection(configuration.locale);
12796        }
12797
12798        synchronized (this) {
12799            mDebugApp = mOrigDebugApp = debugApp;
12800            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12801            mAlwaysFinishActivities = alwaysFinishActivities;
12802            mLenientBackgroundCheck = lenientBackgroundCheck;
12803            mForceResizableActivities = forceResizable;
12804            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12805            if (supportsMultiWindow || forceResizable) {
12806                mSupportsMultiWindow = true;
12807                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12808                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12809            } else {
12810                mSupportsMultiWindow = false;
12811                mSupportsFreeformWindowManagement = false;
12812                mSupportsPictureInPicture = false;
12813            }
12814            // This happens before any activities are started, so we can
12815            // change mConfiguration in-place.
12816            updateConfigurationLocked(configuration, null, true);
12817            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12818                    "Initial config: " + mConfiguration);
12819
12820            // Load resources only after the current configuration has been set.
12821            final Resources res = mContext.getResources();
12822            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12823            mThumbnailWidth = res.getDimensionPixelSize(
12824                    com.android.internal.R.dimen.thumbnail_width);
12825            mThumbnailHeight = res.getDimensionPixelSize(
12826                    com.android.internal.R.dimen.thumbnail_height);
12827            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12828                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12829            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12830                    com.android.internal.R.string.config_appsNotReportingCrashes));
12831            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12832                mFullscreenThumbnailScale = (float) res
12833                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12834                    (float) mConfiguration.screenWidthDp;
12835            } else {
12836                mFullscreenThumbnailScale = res.getFraction(
12837                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12838            }
12839        }
12840    }
12841
12842    public boolean testIsSystemReady() {
12843        // no need to synchronize(this) just to read & return the value
12844        return mSystemReady;
12845    }
12846
12847    public void systemReady(final Runnable goingCallback) {
12848        synchronized(this) {
12849            if (mSystemReady) {
12850                // If we're done calling all the receivers, run the next "boot phase" passed in
12851                // by the SystemServer
12852                if (goingCallback != null) {
12853                    goingCallback.run();
12854                }
12855                return;
12856            }
12857
12858            mLocalDeviceIdleController
12859                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12860
12861            // Make sure we have the current profile info, since it is needed for security checks.
12862            mUserController.onSystemReady();
12863            mRecentTasks.onSystemReadyLocked();
12864            mAppOpsService.systemReady();
12865            mSystemReady = true;
12866        }
12867
12868        ArrayList<ProcessRecord> procsToKill = null;
12869        synchronized(mPidsSelfLocked) {
12870            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12871                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12872                if (!isAllowedWhileBooting(proc.info)){
12873                    if (procsToKill == null) {
12874                        procsToKill = new ArrayList<ProcessRecord>();
12875                    }
12876                    procsToKill.add(proc);
12877                }
12878            }
12879        }
12880
12881        synchronized(this) {
12882            if (procsToKill != null) {
12883                for (int i=procsToKill.size()-1; i>=0; i--) {
12884                    ProcessRecord proc = procsToKill.get(i);
12885                    Slog.i(TAG, "Removing system update proc: " + proc);
12886                    removeProcessLocked(proc, true, false, "system update done");
12887                }
12888            }
12889
12890            // Now that we have cleaned up any update processes, we
12891            // are ready to start launching real processes and know that
12892            // we won't trample on them any more.
12893            mProcessesReady = true;
12894        }
12895
12896        Slog.i(TAG, "System now ready");
12897        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12898            SystemClock.uptimeMillis());
12899
12900        synchronized(this) {
12901            // Make sure we have no pre-ready processes sitting around.
12902
12903            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12904                ResolveInfo ri = mContext.getPackageManager()
12905                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12906                                STOCK_PM_FLAGS);
12907                CharSequence errorMsg = null;
12908                if (ri != null) {
12909                    ActivityInfo ai = ri.activityInfo;
12910                    ApplicationInfo app = ai.applicationInfo;
12911                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12912                        mTopAction = Intent.ACTION_FACTORY_TEST;
12913                        mTopData = null;
12914                        mTopComponent = new ComponentName(app.packageName,
12915                                ai.name);
12916                    } else {
12917                        errorMsg = mContext.getResources().getText(
12918                                com.android.internal.R.string.factorytest_not_system);
12919                    }
12920                } else {
12921                    errorMsg = mContext.getResources().getText(
12922                            com.android.internal.R.string.factorytest_no_action);
12923                }
12924                if (errorMsg != null) {
12925                    mTopAction = null;
12926                    mTopData = null;
12927                    mTopComponent = null;
12928                    Message msg = Message.obtain();
12929                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12930                    msg.getData().putCharSequence("msg", errorMsg);
12931                    mUiHandler.sendMessage(msg);
12932                }
12933            }
12934        }
12935
12936        retrieveSettings();
12937        final int currentUserId;
12938        synchronized (this) {
12939            currentUserId = mUserController.getCurrentUserIdLocked();
12940            readGrantedUriPermissionsLocked();
12941        }
12942
12943        if (goingCallback != null) goingCallback.run();
12944
12945        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12946                Integer.toString(currentUserId), currentUserId);
12947        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12948                Integer.toString(currentUserId), currentUserId);
12949        mSystemServiceManager.startUser(currentUserId);
12950
12951        synchronized (this) {
12952            // Only start up encryption-aware persistent apps; once user is
12953            // unlocked we'll come back around and start unaware apps
12954            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12955
12956            // Start up initial activity.
12957            mBooting = true;
12958            // Enable home activity for system user, so that the system can always boot
12959            if (UserManager.isSplitSystemUser()) {
12960                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12961                try {
12962                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12963                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12964                            UserHandle.USER_SYSTEM);
12965                } catch (RemoteException e) {
12966                    throw e.rethrowAsRuntimeException();
12967                }
12968            }
12969            startHomeActivityLocked(currentUserId, "systemReady");
12970
12971            try {
12972                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12973                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12974                            + " data partition or your device will be unstable.");
12975                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12976                }
12977            } catch (RemoteException e) {
12978            }
12979
12980            if (!Build.isBuildConsistent()) {
12981                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12982                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12983            }
12984
12985            long ident = Binder.clearCallingIdentity();
12986            try {
12987                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12988                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12989                        | Intent.FLAG_RECEIVER_FOREGROUND);
12990                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12991                broadcastIntentLocked(null, null, intent,
12992                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12993                        null, false, false, MY_PID, Process.SYSTEM_UID,
12994                        currentUserId);
12995                intent = new Intent(Intent.ACTION_USER_STARTING);
12996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12997                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12998                broadcastIntentLocked(null, null, intent,
12999                        null, new IIntentReceiver.Stub() {
13000                            @Override
13001                            public void performReceive(Intent intent, int resultCode, String data,
13002                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13003                                    throws RemoteException {
13004                            }
13005                        }, 0, null, null,
13006                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13007                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13008            } catch (Throwable t) {
13009                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13010            } finally {
13011                Binder.restoreCallingIdentity(ident);
13012            }
13013            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13014            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13015        }
13016    }
13017
13018    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13019        synchronized (this) {
13020            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13021        }
13022    }
13023
13024    void skipCurrentReceiverLocked(ProcessRecord app) {
13025        for (BroadcastQueue queue : mBroadcastQueues) {
13026            queue.skipCurrentReceiverLocked(app);
13027        }
13028    }
13029
13030    /**
13031     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13032     * The application process will exit immediately after this call returns.
13033     * @param app object of the crashing app, null for the system server
13034     * @param crashInfo describing the exception
13035     */
13036    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13037        ProcessRecord r = findAppProcess(app, "Crash");
13038        final String processName = app == null ? "system_server"
13039                : (r == null ? "unknown" : r.processName);
13040
13041        handleApplicationCrashInner("crash", r, processName, crashInfo);
13042    }
13043
13044    /* Native crash reporting uses this inner version because it needs to be somewhat
13045     * decoupled from the AM-managed cleanup lifecycle
13046     */
13047    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13048            ApplicationErrorReport.CrashInfo crashInfo) {
13049        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13050                UserHandle.getUserId(Binder.getCallingUid()), processName,
13051                r == null ? -1 : r.info.flags,
13052                crashInfo.exceptionClassName,
13053                crashInfo.exceptionMessage,
13054                crashInfo.throwFileName,
13055                crashInfo.throwLineNumber);
13056
13057        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13058
13059        mAppErrors.crashApplication(r, crashInfo);
13060    }
13061
13062    public void handleApplicationStrictModeViolation(
13063            IBinder app,
13064            int violationMask,
13065            StrictMode.ViolationInfo info) {
13066        ProcessRecord r = findAppProcess(app, "StrictMode");
13067        if (r == null) {
13068            return;
13069        }
13070
13071        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13072            Integer stackFingerprint = info.hashCode();
13073            boolean logIt = true;
13074            synchronized (mAlreadyLoggedViolatedStacks) {
13075                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13076                    logIt = false;
13077                    // TODO: sub-sample into EventLog for these, with
13078                    // the info.durationMillis?  Then we'd get
13079                    // the relative pain numbers, without logging all
13080                    // the stack traces repeatedly.  We'd want to do
13081                    // likewise in the client code, which also does
13082                    // dup suppression, before the Binder call.
13083                } else {
13084                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13085                        mAlreadyLoggedViolatedStacks.clear();
13086                    }
13087                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13088                }
13089            }
13090            if (logIt) {
13091                logStrictModeViolationToDropBox(r, info);
13092            }
13093        }
13094
13095        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13096            AppErrorResult result = new AppErrorResult();
13097            synchronized (this) {
13098                final long origId = Binder.clearCallingIdentity();
13099
13100                Message msg = Message.obtain();
13101                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13102                HashMap<String, Object> data = new HashMap<String, Object>();
13103                data.put("result", result);
13104                data.put("app", r);
13105                data.put("violationMask", violationMask);
13106                data.put("info", info);
13107                msg.obj = data;
13108                mUiHandler.sendMessage(msg);
13109
13110                Binder.restoreCallingIdentity(origId);
13111            }
13112            int res = result.get();
13113            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13114        }
13115    }
13116
13117    // Depending on the policy in effect, there could be a bunch of
13118    // these in quick succession so we try to batch these together to
13119    // minimize disk writes, number of dropbox entries, and maximize
13120    // compression, by having more fewer, larger records.
13121    private void logStrictModeViolationToDropBox(
13122            ProcessRecord process,
13123            StrictMode.ViolationInfo info) {
13124        if (info == null) {
13125            return;
13126        }
13127        final boolean isSystemApp = process == null ||
13128                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13129                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13130        final String processName = process == null ? "unknown" : process.processName;
13131        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13132        final DropBoxManager dbox = (DropBoxManager)
13133                mContext.getSystemService(Context.DROPBOX_SERVICE);
13134
13135        // Exit early if the dropbox isn't configured to accept this report type.
13136        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13137
13138        boolean bufferWasEmpty;
13139        boolean needsFlush;
13140        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13141        synchronized (sb) {
13142            bufferWasEmpty = sb.length() == 0;
13143            appendDropBoxProcessHeaders(process, processName, sb);
13144            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13145            sb.append("System-App: ").append(isSystemApp).append("\n");
13146            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13147            if (info.violationNumThisLoop != 0) {
13148                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13149            }
13150            if (info.numAnimationsRunning != 0) {
13151                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13152            }
13153            if (info.broadcastIntentAction != null) {
13154                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13155            }
13156            if (info.durationMillis != -1) {
13157                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13158            }
13159            if (info.numInstances != -1) {
13160                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13161            }
13162            if (info.tags != null) {
13163                for (String tag : info.tags) {
13164                    sb.append("Span-Tag: ").append(tag).append("\n");
13165                }
13166            }
13167            sb.append("\n");
13168            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13169                sb.append(info.crashInfo.stackTrace);
13170                sb.append("\n");
13171            }
13172            if (info.message != null) {
13173                sb.append(info.message);
13174                sb.append("\n");
13175            }
13176
13177            // Only buffer up to ~64k.  Various logging bits truncate
13178            // things at 128k.
13179            needsFlush = (sb.length() > 64 * 1024);
13180        }
13181
13182        // Flush immediately if the buffer's grown too large, or this
13183        // is a non-system app.  Non-system apps are isolated with a
13184        // different tag & policy and not batched.
13185        //
13186        // Batching is useful during internal testing with
13187        // StrictMode settings turned up high.  Without batching,
13188        // thousands of separate files could be created on boot.
13189        if (!isSystemApp || needsFlush) {
13190            new Thread("Error dump: " + dropboxTag) {
13191                @Override
13192                public void run() {
13193                    String report;
13194                    synchronized (sb) {
13195                        report = sb.toString();
13196                        sb.delete(0, sb.length());
13197                        sb.trimToSize();
13198                    }
13199                    if (report.length() != 0) {
13200                        dbox.addText(dropboxTag, report);
13201                    }
13202                }
13203            }.start();
13204            return;
13205        }
13206
13207        // System app batching:
13208        if (!bufferWasEmpty) {
13209            // An existing dropbox-writing thread is outstanding, so
13210            // we don't need to start it up.  The existing thread will
13211            // catch the buffer appends we just did.
13212            return;
13213        }
13214
13215        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13216        // (After this point, we shouldn't access AMS internal data structures.)
13217        new Thread("Error dump: " + dropboxTag) {
13218            @Override
13219            public void run() {
13220                // 5 second sleep to let stacks arrive and be batched together
13221                try {
13222                    Thread.sleep(5000);  // 5 seconds
13223                } catch (InterruptedException e) {}
13224
13225                String errorReport;
13226                synchronized (mStrictModeBuffer) {
13227                    errorReport = mStrictModeBuffer.toString();
13228                    if (errorReport.length() == 0) {
13229                        return;
13230                    }
13231                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13232                    mStrictModeBuffer.trimToSize();
13233                }
13234                dbox.addText(dropboxTag, errorReport);
13235            }
13236        }.start();
13237    }
13238
13239    /**
13240     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13241     * @param app object of the crashing app, null for the system server
13242     * @param tag reported by the caller
13243     * @param system whether this wtf is coming from the system
13244     * @param crashInfo describing the context of the error
13245     * @return true if the process should exit immediately (WTF is fatal)
13246     */
13247    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13248            final ApplicationErrorReport.CrashInfo crashInfo) {
13249        final int callingUid = Binder.getCallingUid();
13250        final int callingPid = Binder.getCallingPid();
13251
13252        if (system) {
13253            // If this is coming from the system, we could very well have low-level
13254            // system locks held, so we want to do this all asynchronously.  And we
13255            // never want this to become fatal, so there is that too.
13256            mHandler.post(new Runnable() {
13257                @Override public void run() {
13258                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13259                }
13260            });
13261            return false;
13262        }
13263
13264        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13265                crashInfo);
13266
13267        if (r != null && r.pid != Process.myPid() &&
13268                Settings.Global.getInt(mContext.getContentResolver(),
13269                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13270            mAppErrors.crashApplication(r, crashInfo);
13271            return true;
13272        } else {
13273            return false;
13274        }
13275    }
13276
13277    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13278            final ApplicationErrorReport.CrashInfo crashInfo) {
13279        final ProcessRecord r = findAppProcess(app, "WTF");
13280        final String processName = app == null ? "system_server"
13281                : (r == null ? "unknown" : r.processName);
13282
13283        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13284                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13285
13286        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13287
13288        return r;
13289    }
13290
13291    /**
13292     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13293     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13294     */
13295    private ProcessRecord findAppProcess(IBinder app, String reason) {
13296        if (app == null) {
13297            return null;
13298        }
13299
13300        synchronized (this) {
13301            final int NP = mProcessNames.getMap().size();
13302            for (int ip=0; ip<NP; ip++) {
13303                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13304                final int NA = apps.size();
13305                for (int ia=0; ia<NA; ia++) {
13306                    ProcessRecord p = apps.valueAt(ia);
13307                    if (p.thread != null && p.thread.asBinder() == app) {
13308                        return p;
13309                    }
13310                }
13311            }
13312
13313            Slog.w(TAG, "Can't find mystery application for " + reason
13314                    + " from pid=" + Binder.getCallingPid()
13315                    + " uid=" + Binder.getCallingUid() + ": " + app);
13316            return null;
13317        }
13318    }
13319
13320    /**
13321     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13322     * to append various headers to the dropbox log text.
13323     */
13324    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13325            StringBuilder sb) {
13326        // Watchdog thread ends up invoking this function (with
13327        // a null ProcessRecord) to add the stack file to dropbox.
13328        // Do not acquire a lock on this (am) in such cases, as it
13329        // could cause a potential deadlock, if and when watchdog
13330        // is invoked due to unavailability of lock on am and it
13331        // would prevent watchdog from killing system_server.
13332        if (process == null) {
13333            sb.append("Process: ").append(processName).append("\n");
13334            return;
13335        }
13336        // Note: ProcessRecord 'process' is guarded by the service
13337        // instance.  (notably process.pkgList, which could otherwise change
13338        // concurrently during execution of this method)
13339        synchronized (this) {
13340            sb.append("Process: ").append(processName).append("\n");
13341            int flags = process.info.flags;
13342            IPackageManager pm = AppGlobals.getPackageManager();
13343            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13344            for (int ip=0; ip<process.pkgList.size(); ip++) {
13345                String pkg = process.pkgList.keyAt(ip);
13346                sb.append("Package: ").append(pkg);
13347                try {
13348                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13349                    if (pi != null) {
13350                        sb.append(" v").append(pi.versionCode);
13351                        if (pi.versionName != null) {
13352                            sb.append(" (").append(pi.versionName).append(")");
13353                        }
13354                    }
13355                } catch (RemoteException e) {
13356                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13357                }
13358                sb.append("\n");
13359            }
13360        }
13361    }
13362
13363    private static String processClass(ProcessRecord process) {
13364        if (process == null || process.pid == MY_PID) {
13365            return "system_server";
13366        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13367            return "system_app";
13368        } else {
13369            return "data_app";
13370        }
13371    }
13372
13373    private volatile long mWtfClusterStart;
13374    private volatile int mWtfClusterCount;
13375
13376    /**
13377     * Write a description of an error (crash, WTF, ANR) to the drop box.
13378     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13379     * @param process which caused the error, null means the system server
13380     * @param activity which triggered the error, null if unknown
13381     * @param parent activity related to the error, null if unknown
13382     * @param subject line related to the error, null if absent
13383     * @param report in long form describing the error, null if absent
13384     * @param logFile to include in the report, null if none
13385     * @param crashInfo giving an application stack trace, null if absent
13386     */
13387    public void addErrorToDropBox(String eventType,
13388            ProcessRecord process, String processName, ActivityRecord activity,
13389            ActivityRecord parent, String subject,
13390            final String report, final File logFile,
13391            final ApplicationErrorReport.CrashInfo crashInfo) {
13392        // NOTE -- this must never acquire the ActivityManagerService lock,
13393        // otherwise the watchdog may be prevented from resetting the system.
13394
13395        final String dropboxTag = processClass(process) + "_" + eventType;
13396        final DropBoxManager dbox = (DropBoxManager)
13397                mContext.getSystemService(Context.DROPBOX_SERVICE);
13398
13399        // Exit early if the dropbox isn't configured to accept this report type.
13400        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13401
13402        // Rate-limit how often we're willing to do the heavy lifting below to
13403        // collect and record logs; currently 5 logs per 10 second period.
13404        final long now = SystemClock.elapsedRealtime();
13405        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13406            mWtfClusterStart = now;
13407            mWtfClusterCount = 1;
13408        } else {
13409            if (mWtfClusterCount++ >= 5) return;
13410        }
13411
13412        final StringBuilder sb = new StringBuilder(1024);
13413        appendDropBoxProcessHeaders(process, processName, sb);
13414        if (process != null) {
13415            sb.append("Foreground: ")
13416                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13417                    .append("\n");
13418        }
13419        if (activity != null) {
13420            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13421        }
13422        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13423            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13424        }
13425        if (parent != null && parent != activity) {
13426            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13427        }
13428        if (subject != null) {
13429            sb.append("Subject: ").append(subject).append("\n");
13430        }
13431        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13432        if (Debug.isDebuggerConnected()) {
13433            sb.append("Debugger: Connected\n");
13434        }
13435        sb.append("\n");
13436
13437        // Do the rest in a worker thread to avoid blocking the caller on I/O
13438        // (After this point, we shouldn't access AMS internal data structures.)
13439        Thread worker = new Thread("Error dump: " + dropboxTag) {
13440            @Override
13441            public void run() {
13442                if (report != null) {
13443                    sb.append(report);
13444                }
13445                if (logFile != null) {
13446                    try {
13447                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13448                                    "\n\n[[TRUNCATED]]"));
13449                    } catch (IOException e) {
13450                        Slog.e(TAG, "Error reading " + logFile, e);
13451                    }
13452                }
13453                if (crashInfo != null && crashInfo.stackTrace != null) {
13454                    sb.append(crashInfo.stackTrace);
13455                }
13456
13457                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13458                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13459                if (lines > 0) {
13460                    sb.append("\n");
13461
13462                    // Merge several logcat streams, and take the last N lines
13463                    InputStreamReader input = null;
13464                    try {
13465                        java.lang.Process logcat = new ProcessBuilder(
13466                                "/system/bin/timeout", "-k", "15s", "10s",
13467                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13468                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13469                                        .redirectErrorStream(true).start();
13470
13471                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13472                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13473                        input = new InputStreamReader(logcat.getInputStream());
13474
13475                        int num;
13476                        char[] buf = new char[8192];
13477                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13478                    } catch (IOException e) {
13479                        Slog.e(TAG, "Error running logcat", e);
13480                    } finally {
13481                        if (input != null) try { input.close(); } catch (IOException e) {}
13482                    }
13483                }
13484
13485                dbox.addText(dropboxTag, sb.toString());
13486            }
13487        };
13488
13489        if (process == null) {
13490            // If process is null, we are being called from some internal code
13491            // and may be about to die -- run this synchronously.
13492            worker.run();
13493        } else {
13494            worker.start();
13495        }
13496    }
13497
13498    @Override
13499    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13500        enforceNotIsolatedCaller("getProcessesInErrorState");
13501        // assume our apps are happy - lazy create the list
13502        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13503
13504        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13505                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13506        int userId = UserHandle.getUserId(Binder.getCallingUid());
13507
13508        synchronized (this) {
13509
13510            // iterate across all processes
13511            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13512                ProcessRecord app = mLruProcesses.get(i);
13513                if (!allUsers && app.userId != userId) {
13514                    continue;
13515                }
13516                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13517                    // This one's in trouble, so we'll generate a report for it
13518                    // crashes are higher priority (in case there's a crash *and* an anr)
13519                    ActivityManager.ProcessErrorStateInfo report = null;
13520                    if (app.crashing) {
13521                        report = app.crashingReport;
13522                    } else if (app.notResponding) {
13523                        report = app.notRespondingReport;
13524                    }
13525
13526                    if (report != null) {
13527                        if (errList == null) {
13528                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13529                        }
13530                        errList.add(report);
13531                    } else {
13532                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13533                                " crashing = " + app.crashing +
13534                                " notResponding = " + app.notResponding);
13535                    }
13536                }
13537            }
13538        }
13539
13540        return errList;
13541    }
13542
13543    static int procStateToImportance(int procState, int memAdj,
13544            ActivityManager.RunningAppProcessInfo currApp) {
13545        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13546        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13547            currApp.lru = memAdj;
13548        } else {
13549            currApp.lru = 0;
13550        }
13551        return imp;
13552    }
13553
13554    private void fillInProcMemInfo(ProcessRecord app,
13555            ActivityManager.RunningAppProcessInfo outInfo) {
13556        outInfo.pid = app.pid;
13557        outInfo.uid = app.info.uid;
13558        if (mHeavyWeightProcess == app) {
13559            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13560        }
13561        if (app.persistent) {
13562            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13563        }
13564        if (app.activities.size() > 0) {
13565            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13566        }
13567        outInfo.lastTrimLevel = app.trimMemoryLevel;
13568        int adj = app.curAdj;
13569        int procState = app.curProcState;
13570        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13571        outInfo.importanceReasonCode = app.adjTypeCode;
13572        outInfo.processState = app.curProcState;
13573    }
13574
13575    @Override
13576    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13577        enforceNotIsolatedCaller("getRunningAppProcesses");
13578
13579        final int callingUid = Binder.getCallingUid();
13580
13581        // Lazy instantiation of list
13582        List<ActivityManager.RunningAppProcessInfo> runList = null;
13583        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13584                callingUid) == PackageManager.PERMISSION_GRANTED;
13585        final int userId = UserHandle.getUserId(callingUid);
13586        final boolean allUids = isGetTasksAllowed(
13587                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13588
13589        synchronized (this) {
13590            // Iterate across all processes
13591            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13592                ProcessRecord app = mLruProcesses.get(i);
13593                if ((!allUsers && app.userId != userId)
13594                        || (!allUids && app.uid != callingUid)) {
13595                    continue;
13596                }
13597                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13598                    // Generate process state info for running application
13599                    ActivityManager.RunningAppProcessInfo currApp =
13600                        new ActivityManager.RunningAppProcessInfo(app.processName,
13601                                app.pid, app.getPackageList());
13602                    fillInProcMemInfo(app, currApp);
13603                    if (app.adjSource instanceof ProcessRecord) {
13604                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13605                        currApp.importanceReasonImportance =
13606                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13607                                        app.adjSourceProcState);
13608                    } else if (app.adjSource instanceof ActivityRecord) {
13609                        ActivityRecord r = (ActivityRecord)app.adjSource;
13610                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13611                    }
13612                    if (app.adjTarget instanceof ComponentName) {
13613                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13614                    }
13615                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13616                    //        + " lru=" + currApp.lru);
13617                    if (runList == null) {
13618                        runList = new ArrayList<>();
13619                    }
13620                    runList.add(currApp);
13621                }
13622            }
13623        }
13624        return runList;
13625    }
13626
13627    @Override
13628    public List<ApplicationInfo> getRunningExternalApplications() {
13629        enforceNotIsolatedCaller("getRunningExternalApplications");
13630        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13631        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13632        if (runningApps != null && runningApps.size() > 0) {
13633            Set<String> extList = new HashSet<String>();
13634            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13635                if (app.pkgList != null) {
13636                    for (String pkg : app.pkgList) {
13637                        extList.add(pkg);
13638                    }
13639                }
13640            }
13641            IPackageManager pm = AppGlobals.getPackageManager();
13642            for (String pkg : extList) {
13643                try {
13644                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13645                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13646                        retList.add(info);
13647                    }
13648                } catch (RemoteException e) {
13649                }
13650            }
13651        }
13652        return retList;
13653    }
13654
13655    @Override
13656    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13657        enforceNotIsolatedCaller("getMyMemoryState");
13658        synchronized (this) {
13659            ProcessRecord proc;
13660            synchronized (mPidsSelfLocked) {
13661                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13662            }
13663            fillInProcMemInfo(proc, outInfo);
13664        }
13665    }
13666
13667    @Override
13668    public int getMemoryTrimLevel() {
13669        enforceNotIsolatedCaller("getMyMemoryState");
13670        synchronized (this) {
13671            return mLastMemoryLevel;
13672        }
13673    }
13674
13675    @Override
13676    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13677            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13678        (new ActivityManagerShellCommand(this, false)).exec(
13679                this, in, out, err, args, resultReceiver);
13680    }
13681
13682    @Override
13683    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13684        if (checkCallingPermission(android.Manifest.permission.DUMP)
13685                != PackageManager.PERMISSION_GRANTED) {
13686            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13687                    + Binder.getCallingPid()
13688                    + ", uid=" + Binder.getCallingUid()
13689                    + " without permission "
13690                    + android.Manifest.permission.DUMP);
13691            return;
13692        }
13693
13694        boolean dumpAll = false;
13695        boolean dumpClient = false;
13696        String dumpPackage = null;
13697
13698        int opti = 0;
13699        while (opti < args.length) {
13700            String opt = args[opti];
13701            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13702                break;
13703            }
13704            opti++;
13705            if ("-a".equals(opt)) {
13706                dumpAll = true;
13707            } else if ("-c".equals(opt)) {
13708                dumpClient = true;
13709            } else if ("-p".equals(opt)) {
13710                if (opti < args.length) {
13711                    dumpPackage = args[opti];
13712                    opti++;
13713                } else {
13714                    pw.println("Error: -p option requires package argument");
13715                    return;
13716                }
13717                dumpClient = true;
13718            } else if ("-h".equals(opt)) {
13719                ActivityManagerShellCommand.dumpHelp(pw, true);
13720                return;
13721            } else {
13722                pw.println("Unknown argument: " + opt + "; use -h for help");
13723            }
13724        }
13725
13726        long origId = Binder.clearCallingIdentity();
13727        boolean more = false;
13728        // Is the caller requesting to dump a particular piece of data?
13729        if (opti < args.length) {
13730            String cmd = args[opti];
13731            opti++;
13732            if ("activities".equals(cmd) || "a".equals(cmd)) {
13733                synchronized (this) {
13734                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13735                }
13736            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13737                synchronized (this) {
13738                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13739                }
13740            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13741                String[] newArgs;
13742                String name;
13743                if (opti >= args.length) {
13744                    name = null;
13745                    newArgs = EMPTY_STRING_ARRAY;
13746                } else {
13747                    dumpPackage = args[opti];
13748                    opti++;
13749                    newArgs = new String[args.length - opti];
13750                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13751                            args.length - opti);
13752                }
13753                synchronized (this) {
13754                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13755                }
13756            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13757                String[] newArgs;
13758                String name;
13759                if (opti >= args.length) {
13760                    name = null;
13761                    newArgs = EMPTY_STRING_ARRAY;
13762                } else {
13763                    dumpPackage = args[opti];
13764                    opti++;
13765                    newArgs = new String[args.length - opti];
13766                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13767                            args.length - opti);
13768                }
13769                synchronized (this) {
13770                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13771                }
13772            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13773                String[] newArgs;
13774                String name;
13775                if (opti >= args.length) {
13776                    name = null;
13777                    newArgs = EMPTY_STRING_ARRAY;
13778                } else {
13779                    dumpPackage = args[opti];
13780                    opti++;
13781                    newArgs = new String[args.length - opti];
13782                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13783                            args.length - opti);
13784                }
13785                synchronized (this) {
13786                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13787                }
13788            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13789                synchronized (this) {
13790                    dumpOomLocked(fd, pw, args, opti, true);
13791                }
13792            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13793                synchronized (this) {
13794                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13795                }
13796            } else if ("provider".equals(cmd)) {
13797                String[] newArgs;
13798                String name;
13799                if (opti >= args.length) {
13800                    name = null;
13801                    newArgs = EMPTY_STRING_ARRAY;
13802                } else {
13803                    name = args[opti];
13804                    opti++;
13805                    newArgs = new String[args.length - opti];
13806                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13807                }
13808                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13809                    pw.println("No providers match: " + name);
13810                    pw.println("Use -h for help.");
13811                }
13812            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13813                synchronized (this) {
13814                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13815                }
13816            } else if ("service".equals(cmd)) {
13817                String[] newArgs;
13818                String name;
13819                if (opti >= args.length) {
13820                    name = null;
13821                    newArgs = EMPTY_STRING_ARRAY;
13822                } else {
13823                    name = args[opti];
13824                    opti++;
13825                    newArgs = new String[args.length - opti];
13826                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13827                            args.length - opti);
13828                }
13829                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13830                    pw.println("No services match: " + name);
13831                    pw.println("Use -h for help.");
13832                }
13833            } else if ("package".equals(cmd)) {
13834                String[] newArgs;
13835                if (opti >= args.length) {
13836                    pw.println("package: no package name specified");
13837                    pw.println("Use -h for help.");
13838                } else {
13839                    dumpPackage = args[opti];
13840                    opti++;
13841                    newArgs = new String[args.length - opti];
13842                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13843                            args.length - opti);
13844                    args = newArgs;
13845                    opti = 0;
13846                    more = true;
13847                }
13848            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13849                synchronized (this) {
13850                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13851                }
13852            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13853                if (dumpClient) {
13854                    ActiveServices.ServiceDumper dumper;
13855                    synchronized (this) {
13856                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13857                                dumpPackage);
13858                    }
13859                    dumper.dumpWithClient();
13860                } else {
13861                    synchronized (this) {
13862                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13863                                dumpPackage).dumpLocked();
13864                    }
13865                }
13866            } else if ("locks".equals(cmd)) {
13867                LockGuard.dump(fd, pw, args);
13868            } else {
13869                // Dumping a single activity?
13870                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13871                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13872                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13873                    if (res < 0) {
13874                        pw.println("Bad activity command, or no activities match: " + cmd);
13875                        pw.println("Use -h for help.");
13876                    }
13877                }
13878            }
13879            if (!more) {
13880                Binder.restoreCallingIdentity(origId);
13881                return;
13882            }
13883        }
13884
13885        // No piece of data specified, dump everything.
13886        if (dumpClient) {
13887            ActiveServices.ServiceDumper sdumper;
13888            synchronized (this) {
13889                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13890                pw.println();
13891                if (dumpAll) {
13892                    pw.println("-------------------------------------------------------------------------------");
13893                }
13894                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13895                pw.println();
13896                if (dumpAll) {
13897                    pw.println("-------------------------------------------------------------------------------");
13898                }
13899                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13900                pw.println();
13901                if (dumpAll) {
13902                    pw.println("-------------------------------------------------------------------------------");
13903                }
13904                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13905                pw.println();
13906                if (dumpAll) {
13907                    pw.println("-------------------------------------------------------------------------------");
13908                }
13909                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13910                        dumpPackage);
13911            }
13912            sdumper.dumpWithClient();
13913            pw.println();
13914            synchronized (this) {
13915                if (dumpAll) {
13916                    pw.println("-------------------------------------------------------------------------------");
13917                }
13918                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13919                pw.println();
13920                if (dumpAll) {
13921                    pw.println("-------------------------------------------------------------------------------");
13922                }
13923                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13924                if (mAssociations.size() > 0) {
13925                    pw.println();
13926                    if (dumpAll) {
13927                        pw.println("-------------------------------------------------------------------------------");
13928                    }
13929                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13930                }
13931                pw.println();
13932                if (dumpAll) {
13933                    pw.println("-------------------------------------------------------------------------------");
13934                }
13935                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13936            }
13937
13938        } else {
13939            synchronized (this) {
13940                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13941                pw.println();
13942                if (dumpAll) {
13943                    pw.println("-------------------------------------------------------------------------------");
13944                }
13945                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13946                pw.println();
13947                if (dumpAll) {
13948                    pw.println("-------------------------------------------------------------------------------");
13949                }
13950                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13951                pw.println();
13952                if (dumpAll) {
13953                    pw.println("-------------------------------------------------------------------------------");
13954                }
13955                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13956                pw.println();
13957                if (dumpAll) {
13958                    pw.println("-------------------------------------------------------------------------------");
13959                }
13960                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13961                        .dumpLocked();
13962                pw.println();
13963                if (dumpAll) {
13964                    pw.println("-------------------------------------------------------------------------------");
13965                }
13966                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13967                pw.println();
13968                if (dumpAll) {
13969                    pw.println("-------------------------------------------------------------------------------");
13970                }
13971                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13972                if (mAssociations.size() > 0) {
13973                    pw.println();
13974                    if (dumpAll) {
13975                        pw.println("-------------------------------------------------------------------------------");
13976                    }
13977                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13978                }
13979                pw.println();
13980                if (dumpAll) {
13981                    pw.println("-------------------------------------------------------------------------------");
13982                }
13983                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13984            }
13985        }
13986        Binder.restoreCallingIdentity(origId);
13987    }
13988
13989    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13990            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13991        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13992
13993        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13994                dumpPackage);
13995        boolean needSep = printedAnything;
13996
13997        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13998                dumpPackage, needSep, "  mFocusedActivity: ");
13999        if (printed) {
14000            printedAnything = true;
14001            needSep = false;
14002        }
14003
14004        if (dumpPackage == null) {
14005            if (needSep) {
14006                pw.println();
14007            }
14008            needSep = true;
14009            printedAnything = true;
14010            mStackSupervisor.dump(pw, "  ");
14011        }
14012
14013        if (!printedAnything) {
14014            pw.println("  (nothing)");
14015        }
14016    }
14017
14018    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14019            int opti, boolean dumpAll, String dumpPackage) {
14020        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14021
14022        boolean printedAnything = false;
14023
14024        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14025            boolean printedHeader = false;
14026
14027            final int N = mRecentTasks.size();
14028            for (int i=0; i<N; i++) {
14029                TaskRecord tr = mRecentTasks.get(i);
14030                if (dumpPackage != null) {
14031                    if (tr.realActivity == null ||
14032                            !dumpPackage.equals(tr.realActivity)) {
14033                        continue;
14034                    }
14035                }
14036                if (!printedHeader) {
14037                    pw.println("  Recent tasks:");
14038                    printedHeader = true;
14039                    printedAnything = true;
14040                }
14041                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14042                        pw.println(tr);
14043                if (dumpAll) {
14044                    mRecentTasks.get(i).dump(pw, "    ");
14045                }
14046            }
14047        }
14048
14049        if (!printedAnything) {
14050            pw.println("  (nothing)");
14051        }
14052    }
14053
14054    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14055            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14056        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14057
14058        int dumpUid = 0;
14059        if (dumpPackage != null) {
14060            IPackageManager pm = AppGlobals.getPackageManager();
14061            try {
14062                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14063            } catch (RemoteException e) {
14064            }
14065        }
14066
14067        boolean printedAnything = false;
14068
14069        final long now = SystemClock.uptimeMillis();
14070
14071        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14072            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14073                    = mAssociations.valueAt(i1);
14074            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14075                SparseArray<ArrayMap<String, Association>> sourceUids
14076                        = targetComponents.valueAt(i2);
14077                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14078                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14079                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14080                        Association ass = sourceProcesses.valueAt(i4);
14081                        if (dumpPackage != null) {
14082                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14083                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14084                                continue;
14085                            }
14086                        }
14087                        printedAnything = true;
14088                        pw.print("  ");
14089                        pw.print(ass.mTargetProcess);
14090                        pw.print("/");
14091                        UserHandle.formatUid(pw, ass.mTargetUid);
14092                        pw.print(" <- ");
14093                        pw.print(ass.mSourceProcess);
14094                        pw.print("/");
14095                        UserHandle.formatUid(pw, ass.mSourceUid);
14096                        pw.println();
14097                        pw.print("    via ");
14098                        pw.print(ass.mTargetComponent.flattenToShortString());
14099                        pw.println();
14100                        pw.print("    ");
14101                        long dur = ass.mTime;
14102                        if (ass.mNesting > 0) {
14103                            dur += now - ass.mStartTime;
14104                        }
14105                        TimeUtils.formatDuration(dur, pw);
14106                        pw.print(" (");
14107                        pw.print(ass.mCount);
14108                        pw.print(" times)");
14109                        pw.print("  ");
14110                        for (int i=0; i<ass.mStateTimes.length; i++) {
14111                            long amt = ass.mStateTimes[i];
14112                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14113                                amt += now - ass.mLastStateUptime;
14114                            }
14115                            if (amt != 0) {
14116                                pw.print(" ");
14117                                pw.print(ProcessList.makeProcStateString(
14118                                            i + ActivityManager.MIN_PROCESS_STATE));
14119                                pw.print("=");
14120                                TimeUtils.formatDuration(amt, pw);
14121                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14122                                    pw.print("*");
14123                                }
14124                            }
14125                        }
14126                        pw.println();
14127                        if (ass.mNesting > 0) {
14128                            pw.print("    Currently active: ");
14129                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14130                            pw.println();
14131                        }
14132                    }
14133                }
14134            }
14135
14136        }
14137
14138        if (!printedAnything) {
14139            pw.println("  (nothing)");
14140        }
14141    }
14142
14143    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14144            String header, boolean needSep) {
14145        boolean printed = false;
14146        int whichAppId = -1;
14147        if (dumpPackage != null) {
14148            try {
14149                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14150                        dumpPackage, 0);
14151                whichAppId = UserHandle.getAppId(info.uid);
14152            } catch (NameNotFoundException e) {
14153                e.printStackTrace();
14154            }
14155        }
14156        for (int i=0; i<uids.size(); i++) {
14157            UidRecord uidRec = uids.valueAt(i);
14158            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14159                continue;
14160            }
14161            if (!printed) {
14162                printed = true;
14163                if (needSep) {
14164                    pw.println();
14165                }
14166                pw.print("  ");
14167                pw.println(header);
14168                needSep = true;
14169            }
14170            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14171            pw.print(": "); pw.println(uidRec);
14172        }
14173        return printed;
14174    }
14175
14176    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14177            int opti, boolean dumpAll, String dumpPackage) {
14178        boolean needSep = false;
14179        boolean printedAnything = false;
14180        int numPers = 0;
14181
14182        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14183
14184        if (dumpAll) {
14185            final int NP = mProcessNames.getMap().size();
14186            for (int ip=0; ip<NP; ip++) {
14187                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14188                final int NA = procs.size();
14189                for (int ia=0; ia<NA; ia++) {
14190                    ProcessRecord r = procs.valueAt(ia);
14191                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14192                        continue;
14193                    }
14194                    if (!needSep) {
14195                        pw.println("  All known processes:");
14196                        needSep = true;
14197                        printedAnything = true;
14198                    }
14199                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14200                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14201                        pw.print(" "); pw.println(r);
14202                    r.dump(pw, "    ");
14203                    if (r.persistent) {
14204                        numPers++;
14205                    }
14206                }
14207            }
14208        }
14209
14210        if (mIsolatedProcesses.size() > 0) {
14211            boolean printed = false;
14212            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14213                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14214                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14215                    continue;
14216                }
14217                if (!printed) {
14218                    if (needSep) {
14219                        pw.println();
14220                    }
14221                    pw.println("  Isolated process list (sorted by uid):");
14222                    printedAnything = true;
14223                    printed = true;
14224                    needSep = true;
14225                }
14226                pw.println(String.format("%sIsolated #%2d: %s",
14227                        "    ", i, r.toString()));
14228            }
14229        }
14230
14231        if (mActiveUids.size() > 0) {
14232            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14233                printedAnything = needSep = true;
14234            }
14235        }
14236        if (mValidateUids.size() > 0) {
14237            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14238                printedAnything = needSep = true;
14239            }
14240        }
14241
14242        if (mLruProcesses.size() > 0) {
14243            if (needSep) {
14244                pw.println();
14245            }
14246            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14247                    pw.print(" total, non-act at ");
14248                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14249                    pw.print(", non-svc at ");
14250                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14251                    pw.println("):");
14252            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14253            needSep = true;
14254            printedAnything = true;
14255        }
14256
14257        if (dumpAll || dumpPackage != null) {
14258            synchronized (mPidsSelfLocked) {
14259                boolean printed = false;
14260                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14261                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14262                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14263                        continue;
14264                    }
14265                    if (!printed) {
14266                        if (needSep) pw.println();
14267                        needSep = true;
14268                        pw.println("  PID mappings:");
14269                        printed = true;
14270                        printedAnything = true;
14271                    }
14272                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14273                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14274                }
14275            }
14276        }
14277
14278        if (mForegroundProcesses.size() > 0) {
14279            synchronized (mPidsSelfLocked) {
14280                boolean printed = false;
14281                for (int i=0; i<mForegroundProcesses.size(); i++) {
14282                    ProcessRecord r = mPidsSelfLocked.get(
14283                            mForegroundProcesses.valueAt(i).pid);
14284                    if (dumpPackage != null && (r == null
14285                            || !r.pkgList.containsKey(dumpPackage))) {
14286                        continue;
14287                    }
14288                    if (!printed) {
14289                        if (needSep) pw.println();
14290                        needSep = true;
14291                        pw.println("  Foreground Processes:");
14292                        printed = true;
14293                        printedAnything = true;
14294                    }
14295                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14296                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14297                }
14298            }
14299        }
14300
14301        if (mPersistentStartingProcesses.size() > 0) {
14302            if (needSep) pw.println();
14303            needSep = true;
14304            printedAnything = true;
14305            pw.println("  Persisent processes that are starting:");
14306            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14307                    "Starting Norm", "Restarting PERS", dumpPackage);
14308        }
14309
14310        if (mRemovedProcesses.size() > 0) {
14311            if (needSep) pw.println();
14312            needSep = true;
14313            printedAnything = true;
14314            pw.println("  Processes that are being removed:");
14315            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14316                    "Removed Norm", "Removed PERS", dumpPackage);
14317        }
14318
14319        if (mProcessesOnHold.size() > 0) {
14320            if (needSep) pw.println();
14321            needSep = true;
14322            printedAnything = true;
14323            pw.println("  Processes that are on old until the system is ready:");
14324            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14325                    "OnHold Norm", "OnHold PERS", dumpPackage);
14326        }
14327
14328        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14329
14330        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14331        if (needSep) {
14332            printedAnything = true;
14333        }
14334
14335        if (dumpPackage == null) {
14336            pw.println();
14337            needSep = false;
14338            mUserController.dump(pw, dumpAll);
14339        }
14340        if (mHomeProcess != null && (dumpPackage == null
14341                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14342            if (needSep) {
14343                pw.println();
14344                needSep = false;
14345            }
14346            pw.println("  mHomeProcess: " + mHomeProcess);
14347        }
14348        if (mPreviousProcess != null && (dumpPackage == null
14349                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14350            if (needSep) {
14351                pw.println();
14352                needSep = false;
14353            }
14354            pw.println("  mPreviousProcess: " + mPreviousProcess);
14355        }
14356        if (dumpAll) {
14357            StringBuilder sb = new StringBuilder(128);
14358            sb.append("  mPreviousProcessVisibleTime: ");
14359            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14360            pw.println(sb);
14361        }
14362        if (mHeavyWeightProcess != null && (dumpPackage == null
14363                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14364            if (needSep) {
14365                pw.println();
14366                needSep = false;
14367            }
14368            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14369        }
14370        if (dumpPackage == null) {
14371            pw.println("  mConfiguration: " + mConfiguration);
14372        }
14373        if (dumpAll) {
14374            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14375            if (mCompatModePackages.getPackages().size() > 0) {
14376                boolean printed = false;
14377                for (Map.Entry<String, Integer> entry
14378                        : mCompatModePackages.getPackages().entrySet()) {
14379                    String pkg = entry.getKey();
14380                    int mode = entry.getValue();
14381                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14382                        continue;
14383                    }
14384                    if (!printed) {
14385                        pw.println("  mScreenCompatPackages:");
14386                        printed = true;
14387                    }
14388                    pw.print("    "); pw.print(pkg); pw.print(": ");
14389                            pw.print(mode); pw.println();
14390                }
14391            }
14392        }
14393        if (dumpPackage == null) {
14394            pw.println("  mWakefulness="
14395                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14396            pw.println("  mSleepTokens=" + mSleepTokens);
14397            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14398                    + lockScreenShownToString());
14399            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14400            if (mRunningVoice != null) {
14401                pw.println("  mRunningVoice=" + mRunningVoice);
14402                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14403            }
14404        }
14405        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14406                || mOrigWaitForDebugger) {
14407            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14408                    || dumpPackage.equals(mOrigDebugApp)) {
14409                if (needSep) {
14410                    pw.println();
14411                    needSep = false;
14412                }
14413                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14414                        + " mDebugTransient=" + mDebugTransient
14415                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14416            }
14417        }
14418        if (mCurAppTimeTracker != null) {
14419            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14420        }
14421        if (mMemWatchProcesses.getMap().size() > 0) {
14422            pw.println("  Mem watch processes:");
14423            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14424                    = mMemWatchProcesses.getMap();
14425            for (int i=0; i<procs.size(); i++) {
14426                final String proc = procs.keyAt(i);
14427                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14428                for (int j=0; j<uids.size(); j++) {
14429                    if (needSep) {
14430                        pw.println();
14431                        needSep = false;
14432                    }
14433                    StringBuilder sb = new StringBuilder();
14434                    sb.append("    ").append(proc).append('/');
14435                    UserHandle.formatUid(sb, uids.keyAt(j));
14436                    Pair<Long, String> val = uids.valueAt(j);
14437                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14438                    if (val.second != null) {
14439                        sb.append(", report to ").append(val.second);
14440                    }
14441                    pw.println(sb.toString());
14442                }
14443            }
14444            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14445            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14446            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14447                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14448        }
14449        if (mTrackAllocationApp != null) {
14450            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14451                if (needSep) {
14452                    pw.println();
14453                    needSep = false;
14454                }
14455                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14456            }
14457        }
14458        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14459                || mProfileFd != null) {
14460            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14461                if (needSep) {
14462                    pw.println();
14463                    needSep = false;
14464                }
14465                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14466                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14467                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14468                        + mAutoStopProfiler);
14469                pw.println("  mProfileType=" + mProfileType);
14470            }
14471        }
14472        if (mNativeDebuggingApp != null) {
14473            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14474                if (needSep) {
14475                    pw.println();
14476                    needSep = false;
14477                }
14478                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14479            }
14480        }
14481        if (dumpPackage == null) {
14482            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14483                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14484                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14485            }
14486            if (mController != null) {
14487                pw.println("  mController=" + mController
14488                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14489            }
14490            if (dumpAll) {
14491                pw.println("  Total persistent processes: " + numPers);
14492                pw.println("  mProcessesReady=" + mProcessesReady
14493                        + " mSystemReady=" + mSystemReady
14494                        + " mBooted=" + mBooted
14495                        + " mFactoryTest=" + mFactoryTest);
14496                pw.println("  mBooting=" + mBooting
14497                        + " mCallFinishBooting=" + mCallFinishBooting
14498                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14499                pw.print("  mLastPowerCheckRealtime=");
14500                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14501                        pw.println("");
14502                pw.print("  mLastPowerCheckUptime=");
14503                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14504                        pw.println("");
14505                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14506                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14507                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14508                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14509                        + " (" + mLruProcesses.size() + " total)"
14510                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14511                        + " mNumServiceProcs=" + mNumServiceProcs
14512                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14513                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14514                        + " mLastMemoryLevel=" + mLastMemoryLevel
14515                        + " mLastNumProcesses=" + mLastNumProcesses);
14516                long now = SystemClock.uptimeMillis();
14517                pw.print("  mLastIdleTime=");
14518                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14519                        pw.print(" mLowRamSinceLastIdle=");
14520                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14521                        pw.println();
14522            }
14523        }
14524
14525        if (!printedAnything) {
14526            pw.println("  (nothing)");
14527        }
14528    }
14529
14530    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14531            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14532        if (mProcessesToGc.size() > 0) {
14533            boolean printed = false;
14534            long now = SystemClock.uptimeMillis();
14535            for (int i=0; i<mProcessesToGc.size(); i++) {
14536                ProcessRecord proc = mProcessesToGc.get(i);
14537                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14538                    continue;
14539                }
14540                if (!printed) {
14541                    if (needSep) pw.println();
14542                    needSep = true;
14543                    pw.println("  Processes that are waiting to GC:");
14544                    printed = true;
14545                }
14546                pw.print("    Process "); pw.println(proc);
14547                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14548                        pw.print(", last gced=");
14549                        pw.print(now-proc.lastRequestedGc);
14550                        pw.print(" ms ago, last lowMem=");
14551                        pw.print(now-proc.lastLowMemory);
14552                        pw.println(" ms ago");
14553
14554            }
14555        }
14556        return needSep;
14557    }
14558
14559    void printOomLevel(PrintWriter pw, String name, int adj) {
14560        pw.print("    ");
14561        if (adj >= 0) {
14562            pw.print(' ');
14563            if (adj < 10) pw.print(' ');
14564        } else {
14565            if (adj > -10) pw.print(' ');
14566        }
14567        pw.print(adj);
14568        pw.print(": ");
14569        pw.print(name);
14570        pw.print(" (");
14571        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14572        pw.println(")");
14573    }
14574
14575    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14576            int opti, boolean dumpAll) {
14577        boolean needSep = false;
14578
14579        if (mLruProcesses.size() > 0) {
14580            if (needSep) pw.println();
14581            needSep = true;
14582            pw.println("  OOM levels:");
14583            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14584            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14585            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14586            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14587            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14588            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14589            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14590            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14591            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14592            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14593            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14594            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14595            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14596            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14597
14598            if (needSep) pw.println();
14599            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14600                    pw.print(" total, non-act at ");
14601                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14602                    pw.print(", non-svc at ");
14603                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14604                    pw.println("):");
14605            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14606            needSep = true;
14607        }
14608
14609        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14610
14611        pw.println();
14612        pw.println("  mHomeProcess: " + mHomeProcess);
14613        pw.println("  mPreviousProcess: " + mPreviousProcess);
14614        if (mHeavyWeightProcess != null) {
14615            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14616        }
14617
14618        return true;
14619    }
14620
14621    /**
14622     * There are three ways to call this:
14623     *  - no provider specified: dump all the providers
14624     *  - a flattened component name that matched an existing provider was specified as the
14625     *    first arg: dump that one provider
14626     *  - the first arg isn't the flattened component name of an existing provider:
14627     *    dump all providers whose component contains the first arg as a substring
14628     */
14629    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14630            int opti, boolean dumpAll) {
14631        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14632    }
14633
14634    static class ItemMatcher {
14635        ArrayList<ComponentName> components;
14636        ArrayList<String> strings;
14637        ArrayList<Integer> objects;
14638        boolean all;
14639
14640        ItemMatcher() {
14641            all = true;
14642        }
14643
14644        void build(String name) {
14645            ComponentName componentName = ComponentName.unflattenFromString(name);
14646            if (componentName != null) {
14647                if (components == null) {
14648                    components = new ArrayList<ComponentName>();
14649                }
14650                components.add(componentName);
14651                all = false;
14652            } else {
14653                int objectId = 0;
14654                // Not a '/' separated full component name; maybe an object ID?
14655                try {
14656                    objectId = Integer.parseInt(name, 16);
14657                    if (objects == null) {
14658                        objects = new ArrayList<Integer>();
14659                    }
14660                    objects.add(objectId);
14661                    all = false;
14662                } catch (RuntimeException e) {
14663                    // Not an integer; just do string match.
14664                    if (strings == null) {
14665                        strings = new ArrayList<String>();
14666                    }
14667                    strings.add(name);
14668                    all = false;
14669                }
14670            }
14671        }
14672
14673        int build(String[] args, int opti) {
14674            for (; opti<args.length; opti++) {
14675                String name = args[opti];
14676                if ("--".equals(name)) {
14677                    return opti+1;
14678                }
14679                build(name);
14680            }
14681            return opti;
14682        }
14683
14684        boolean match(Object object, ComponentName comp) {
14685            if (all) {
14686                return true;
14687            }
14688            if (components != null) {
14689                for (int i=0; i<components.size(); i++) {
14690                    if (components.get(i).equals(comp)) {
14691                        return true;
14692                    }
14693                }
14694            }
14695            if (objects != null) {
14696                for (int i=0; i<objects.size(); i++) {
14697                    if (System.identityHashCode(object) == objects.get(i)) {
14698                        return true;
14699                    }
14700                }
14701            }
14702            if (strings != null) {
14703                String flat = comp.flattenToString();
14704                for (int i=0; i<strings.size(); i++) {
14705                    if (flat.contains(strings.get(i))) {
14706                        return true;
14707                    }
14708                }
14709            }
14710            return false;
14711        }
14712    }
14713
14714    /**
14715     * There are three things that cmd can be:
14716     *  - a flattened component name that matches an existing activity
14717     *  - the cmd arg isn't the flattened component name of an existing activity:
14718     *    dump all activity whose component contains the cmd as a substring
14719     *  - A hex number of the ActivityRecord object instance.
14720     */
14721    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14722            int opti, boolean dumpAll) {
14723        ArrayList<ActivityRecord> activities;
14724
14725        synchronized (this) {
14726            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14727        }
14728
14729        if (activities.size() <= 0) {
14730            return false;
14731        }
14732
14733        String[] newArgs = new String[args.length - opti];
14734        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14735
14736        TaskRecord lastTask = null;
14737        boolean needSep = false;
14738        for (int i=activities.size()-1; i>=0; i--) {
14739            ActivityRecord r = activities.get(i);
14740            if (needSep) {
14741                pw.println();
14742            }
14743            needSep = true;
14744            synchronized (this) {
14745                if (lastTask != r.task) {
14746                    lastTask = r.task;
14747                    pw.print("TASK "); pw.print(lastTask.affinity);
14748                            pw.print(" id="); pw.println(lastTask.taskId);
14749                    if (dumpAll) {
14750                        lastTask.dump(pw, "  ");
14751                    }
14752                }
14753            }
14754            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14755        }
14756        return true;
14757    }
14758
14759    /**
14760     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14761     * there is a thread associated with the activity.
14762     */
14763    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14764            final ActivityRecord r, String[] args, boolean dumpAll) {
14765        String innerPrefix = prefix + "  ";
14766        synchronized (this) {
14767            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14768                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14769                    pw.print(" pid=");
14770                    if (r.app != null) pw.println(r.app.pid);
14771                    else pw.println("(not running)");
14772            if (dumpAll) {
14773                r.dump(pw, innerPrefix);
14774            }
14775        }
14776        if (r.app != null && r.app.thread != null) {
14777            // flush anything that is already in the PrintWriter since the thread is going
14778            // to write to the file descriptor directly
14779            pw.flush();
14780            try {
14781                TransferPipe tp = new TransferPipe();
14782                try {
14783                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14784                            r.appToken, innerPrefix, args);
14785                    tp.go(fd);
14786                } finally {
14787                    tp.kill();
14788                }
14789            } catch (IOException e) {
14790                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14791            } catch (RemoteException e) {
14792                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14793            }
14794        }
14795    }
14796
14797    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14798            int opti, boolean dumpAll, String dumpPackage) {
14799        boolean needSep = false;
14800        boolean onlyHistory = false;
14801        boolean printedAnything = false;
14802
14803        if ("history".equals(dumpPackage)) {
14804            if (opti < args.length && "-s".equals(args[opti])) {
14805                dumpAll = false;
14806            }
14807            onlyHistory = true;
14808            dumpPackage = null;
14809        }
14810
14811        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14812        if (!onlyHistory && dumpAll) {
14813            if (mRegisteredReceivers.size() > 0) {
14814                boolean printed = false;
14815                Iterator it = mRegisteredReceivers.values().iterator();
14816                while (it.hasNext()) {
14817                    ReceiverList r = (ReceiverList)it.next();
14818                    if (dumpPackage != null && (r.app == null ||
14819                            !dumpPackage.equals(r.app.info.packageName))) {
14820                        continue;
14821                    }
14822                    if (!printed) {
14823                        pw.println("  Registered Receivers:");
14824                        needSep = true;
14825                        printed = true;
14826                        printedAnything = true;
14827                    }
14828                    pw.print("  * "); pw.println(r);
14829                    r.dump(pw, "    ");
14830                }
14831            }
14832
14833            if (mReceiverResolver.dump(pw, needSep ?
14834                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14835                    "    ", dumpPackage, false, false)) {
14836                needSep = true;
14837                printedAnything = true;
14838            }
14839        }
14840
14841        for (BroadcastQueue q : mBroadcastQueues) {
14842            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14843            printedAnything |= needSep;
14844        }
14845
14846        needSep = true;
14847
14848        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14849            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14850                if (needSep) {
14851                    pw.println();
14852                }
14853                needSep = true;
14854                printedAnything = true;
14855                pw.print("  Sticky broadcasts for user ");
14856                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14857                StringBuilder sb = new StringBuilder(128);
14858                for (Map.Entry<String, ArrayList<Intent>> ent
14859                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14860                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14861                    if (dumpAll) {
14862                        pw.println(":");
14863                        ArrayList<Intent> intents = ent.getValue();
14864                        final int N = intents.size();
14865                        for (int i=0; i<N; i++) {
14866                            sb.setLength(0);
14867                            sb.append("    Intent: ");
14868                            intents.get(i).toShortString(sb, false, true, false, false);
14869                            pw.println(sb.toString());
14870                            Bundle bundle = intents.get(i).getExtras();
14871                            if (bundle != null) {
14872                                pw.print("      ");
14873                                pw.println(bundle.toString());
14874                            }
14875                        }
14876                    } else {
14877                        pw.println("");
14878                    }
14879                }
14880            }
14881        }
14882
14883        if (!onlyHistory && dumpAll) {
14884            pw.println();
14885            for (BroadcastQueue queue : mBroadcastQueues) {
14886                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14887                        + queue.mBroadcastsScheduled);
14888            }
14889            pw.println("  mHandler:");
14890            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14891            needSep = true;
14892            printedAnything = true;
14893        }
14894
14895        if (!printedAnything) {
14896            pw.println("  (nothing)");
14897        }
14898    }
14899
14900    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14901            int opti, boolean dumpAll, String dumpPackage) {
14902        boolean needSep;
14903        boolean printedAnything = false;
14904
14905        ItemMatcher matcher = new ItemMatcher();
14906        matcher.build(args, opti);
14907
14908        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14909
14910        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14911        printedAnything |= needSep;
14912
14913        if (mLaunchingProviders.size() > 0) {
14914            boolean printed = false;
14915            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14916                ContentProviderRecord r = mLaunchingProviders.get(i);
14917                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14918                    continue;
14919                }
14920                if (!printed) {
14921                    if (needSep) pw.println();
14922                    needSep = true;
14923                    pw.println("  Launching content providers:");
14924                    printed = true;
14925                    printedAnything = true;
14926                }
14927                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14928                        pw.println(r);
14929            }
14930        }
14931
14932        if (!printedAnything) {
14933            pw.println("  (nothing)");
14934        }
14935    }
14936
14937    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14938            int opti, boolean dumpAll, String dumpPackage) {
14939        boolean needSep = false;
14940        boolean printedAnything = false;
14941
14942        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14943
14944        if (mGrantedUriPermissions.size() > 0) {
14945            boolean printed = false;
14946            int dumpUid = -2;
14947            if (dumpPackage != null) {
14948                try {
14949                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14950                            MATCH_UNINSTALLED_PACKAGES, 0);
14951                } catch (NameNotFoundException e) {
14952                    dumpUid = -1;
14953                }
14954            }
14955            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14956                int uid = mGrantedUriPermissions.keyAt(i);
14957                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14958                    continue;
14959                }
14960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14961                if (!printed) {
14962                    if (needSep) pw.println();
14963                    needSep = true;
14964                    pw.println("  Granted Uri Permissions:");
14965                    printed = true;
14966                    printedAnything = true;
14967                }
14968                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14969                for (UriPermission perm : perms.values()) {
14970                    pw.print("    "); pw.println(perm);
14971                    if (dumpAll) {
14972                        perm.dump(pw, "      ");
14973                    }
14974                }
14975            }
14976        }
14977
14978        if (!printedAnything) {
14979            pw.println("  (nothing)");
14980        }
14981    }
14982
14983    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14984            int opti, boolean dumpAll, String dumpPackage) {
14985        boolean printed = false;
14986
14987        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14988
14989        if (mIntentSenderRecords.size() > 0) {
14990            Iterator<WeakReference<PendingIntentRecord>> it
14991                    = mIntentSenderRecords.values().iterator();
14992            while (it.hasNext()) {
14993                WeakReference<PendingIntentRecord> ref = it.next();
14994                PendingIntentRecord rec = ref != null ? ref.get(): null;
14995                if (dumpPackage != null && (rec == null
14996                        || !dumpPackage.equals(rec.key.packageName))) {
14997                    continue;
14998                }
14999                printed = true;
15000                if (rec != null) {
15001                    pw.print("  * "); pw.println(rec);
15002                    if (dumpAll) {
15003                        rec.dump(pw, "    ");
15004                    }
15005                } else {
15006                    pw.print("  * "); pw.println(ref);
15007                }
15008            }
15009        }
15010
15011        if (!printed) {
15012            pw.println("  (nothing)");
15013        }
15014    }
15015
15016    private static final int dumpProcessList(PrintWriter pw,
15017            ActivityManagerService service, List list,
15018            String prefix, String normalLabel, String persistentLabel,
15019            String dumpPackage) {
15020        int numPers = 0;
15021        final int N = list.size()-1;
15022        for (int i=N; i>=0; i--) {
15023            ProcessRecord r = (ProcessRecord)list.get(i);
15024            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15025                continue;
15026            }
15027            pw.println(String.format("%s%s #%2d: %s",
15028                    prefix, (r.persistent ? persistentLabel : normalLabel),
15029                    i, r.toString()));
15030            if (r.persistent) {
15031                numPers++;
15032            }
15033        }
15034        return numPers;
15035    }
15036
15037    private static final boolean dumpProcessOomList(PrintWriter pw,
15038            ActivityManagerService service, List<ProcessRecord> origList,
15039            String prefix, String normalLabel, String persistentLabel,
15040            boolean inclDetails, String dumpPackage) {
15041
15042        ArrayList<Pair<ProcessRecord, Integer>> list
15043                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15044        for (int i=0; i<origList.size(); i++) {
15045            ProcessRecord r = origList.get(i);
15046            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15047                continue;
15048            }
15049            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15050        }
15051
15052        if (list.size() <= 0) {
15053            return false;
15054        }
15055
15056        Comparator<Pair<ProcessRecord, Integer>> comparator
15057                = new Comparator<Pair<ProcessRecord, Integer>>() {
15058            @Override
15059            public int compare(Pair<ProcessRecord, Integer> object1,
15060                    Pair<ProcessRecord, Integer> object2) {
15061                if (object1.first.setAdj != object2.first.setAdj) {
15062                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15063                }
15064                if (object1.first.setProcState != object2.first.setProcState) {
15065                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15066                }
15067                if (object1.second.intValue() != object2.second.intValue()) {
15068                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15069                }
15070                return 0;
15071            }
15072        };
15073
15074        Collections.sort(list, comparator);
15075
15076        final long curRealtime = SystemClock.elapsedRealtime();
15077        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15078        final long curUptime = SystemClock.uptimeMillis();
15079        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15080
15081        for (int i=list.size()-1; i>=0; i--) {
15082            ProcessRecord r = list.get(i).first;
15083            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15084            char schedGroup;
15085            switch (r.setSchedGroup) {
15086                case ProcessList.SCHED_GROUP_BACKGROUND:
15087                    schedGroup = 'B';
15088                    break;
15089                case ProcessList.SCHED_GROUP_DEFAULT:
15090                    schedGroup = 'F';
15091                    break;
15092                case ProcessList.SCHED_GROUP_TOP_APP:
15093                    schedGroup = 'T';
15094                    break;
15095                default:
15096                    schedGroup = '?';
15097                    break;
15098            }
15099            char foreground;
15100            if (r.foregroundActivities) {
15101                foreground = 'A';
15102            } else if (r.foregroundServices) {
15103                foreground = 'S';
15104            } else {
15105                foreground = ' ';
15106            }
15107            String procState = ProcessList.makeProcStateString(r.curProcState);
15108            pw.print(prefix);
15109            pw.print(r.persistent ? persistentLabel : normalLabel);
15110            pw.print(" #");
15111            int num = (origList.size()-1)-list.get(i).second;
15112            if (num < 10) pw.print(' ');
15113            pw.print(num);
15114            pw.print(": ");
15115            pw.print(oomAdj);
15116            pw.print(' ');
15117            pw.print(schedGroup);
15118            pw.print('/');
15119            pw.print(foreground);
15120            pw.print('/');
15121            pw.print(procState);
15122            pw.print(" trm:");
15123            if (r.trimMemoryLevel < 10) pw.print(' ');
15124            pw.print(r.trimMemoryLevel);
15125            pw.print(' ');
15126            pw.print(r.toShortString());
15127            pw.print(" (");
15128            pw.print(r.adjType);
15129            pw.println(')');
15130            if (r.adjSource != null || r.adjTarget != null) {
15131                pw.print(prefix);
15132                pw.print("    ");
15133                if (r.adjTarget instanceof ComponentName) {
15134                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15135                } else if (r.adjTarget != null) {
15136                    pw.print(r.adjTarget.toString());
15137                } else {
15138                    pw.print("{null}");
15139                }
15140                pw.print("<=");
15141                if (r.adjSource instanceof ProcessRecord) {
15142                    pw.print("Proc{");
15143                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15144                    pw.println("}");
15145                } else if (r.adjSource != null) {
15146                    pw.println(r.adjSource.toString());
15147                } else {
15148                    pw.println("{null}");
15149                }
15150            }
15151            if (inclDetails) {
15152                pw.print(prefix);
15153                pw.print("    ");
15154                pw.print("oom: max="); pw.print(r.maxAdj);
15155                pw.print(" curRaw="); pw.print(r.curRawAdj);
15156                pw.print(" setRaw="); pw.print(r.setRawAdj);
15157                pw.print(" cur="); pw.print(r.curAdj);
15158                pw.print(" set="); pw.println(r.setAdj);
15159                pw.print(prefix);
15160                pw.print("    ");
15161                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15162                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15163                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15164                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15165                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15166                pw.println();
15167                pw.print(prefix);
15168                pw.print("    ");
15169                pw.print("cached="); pw.print(r.cached);
15170                pw.print(" empty="); pw.print(r.empty);
15171                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15172
15173                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15174                    if (r.lastWakeTime != 0) {
15175                        long wtime;
15176                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15177                        synchronized (stats) {
15178                            wtime = stats.getProcessWakeTime(r.info.uid,
15179                                    r.pid, curRealtime);
15180                        }
15181                        long timeUsed = wtime - r.lastWakeTime;
15182                        pw.print(prefix);
15183                        pw.print("    ");
15184                        pw.print("keep awake over ");
15185                        TimeUtils.formatDuration(realtimeSince, pw);
15186                        pw.print(" used ");
15187                        TimeUtils.formatDuration(timeUsed, pw);
15188                        pw.print(" (");
15189                        pw.print((timeUsed*100)/realtimeSince);
15190                        pw.println("%)");
15191                    }
15192                    if (r.lastCpuTime != 0) {
15193                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15194                        pw.print(prefix);
15195                        pw.print("    ");
15196                        pw.print("run cpu over ");
15197                        TimeUtils.formatDuration(uptimeSince, pw);
15198                        pw.print(" used ");
15199                        TimeUtils.formatDuration(timeUsed, pw);
15200                        pw.print(" (");
15201                        pw.print((timeUsed*100)/uptimeSince);
15202                        pw.println("%)");
15203                    }
15204                }
15205            }
15206        }
15207        return true;
15208    }
15209
15210    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15211            String[] args) {
15212        ArrayList<ProcessRecord> procs;
15213        synchronized (this) {
15214            if (args != null && args.length > start
15215                    && args[start].charAt(0) != '-') {
15216                procs = new ArrayList<ProcessRecord>();
15217                int pid = -1;
15218                try {
15219                    pid = Integer.parseInt(args[start]);
15220                } catch (NumberFormatException e) {
15221                }
15222                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15223                    ProcessRecord proc = mLruProcesses.get(i);
15224                    if (proc.pid == pid) {
15225                        procs.add(proc);
15226                    } else if (allPkgs && proc.pkgList != null
15227                            && proc.pkgList.containsKey(args[start])) {
15228                        procs.add(proc);
15229                    } else if (proc.processName.equals(args[start])) {
15230                        procs.add(proc);
15231                    }
15232                }
15233                if (procs.size() <= 0) {
15234                    return null;
15235                }
15236            } else {
15237                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15238            }
15239        }
15240        return procs;
15241    }
15242
15243    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15244            PrintWriter pw, String[] args) {
15245        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15246        if (procs == null) {
15247            pw.println("No process found for: " + args[0]);
15248            return;
15249        }
15250
15251        long uptime = SystemClock.uptimeMillis();
15252        long realtime = SystemClock.elapsedRealtime();
15253        pw.println("Applications Graphics Acceleration Info:");
15254        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15255
15256        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15257            ProcessRecord r = procs.get(i);
15258            if (r.thread != null) {
15259                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15260                pw.flush();
15261                try {
15262                    TransferPipe tp = new TransferPipe();
15263                    try {
15264                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15265                        tp.go(fd);
15266                    } finally {
15267                        tp.kill();
15268                    }
15269                } catch (IOException e) {
15270                    pw.println("Failure while dumping the app: " + r);
15271                    pw.flush();
15272                } catch (RemoteException e) {
15273                    pw.println("Got a RemoteException while dumping the app " + r);
15274                    pw.flush();
15275                }
15276            }
15277        }
15278    }
15279
15280    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15281        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15282        if (procs == null) {
15283            pw.println("No process found for: " + args[0]);
15284            return;
15285        }
15286
15287        pw.println("Applications Database Info:");
15288
15289        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15290            ProcessRecord r = procs.get(i);
15291            if (r.thread != null) {
15292                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15293                pw.flush();
15294                try {
15295                    TransferPipe tp = new TransferPipe();
15296                    try {
15297                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15298                        tp.go(fd);
15299                    } finally {
15300                        tp.kill();
15301                    }
15302                } catch (IOException e) {
15303                    pw.println("Failure while dumping the app: " + r);
15304                    pw.flush();
15305                } catch (RemoteException e) {
15306                    pw.println("Got a RemoteException while dumping the app " + r);
15307                    pw.flush();
15308                }
15309            }
15310        }
15311    }
15312
15313    final static class MemItem {
15314        final boolean isProc;
15315        final String label;
15316        final String shortLabel;
15317        final long pss;
15318        final long swapPss;
15319        final int id;
15320        final boolean hasActivities;
15321        ArrayList<MemItem> subitems;
15322
15323        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15324                boolean _hasActivities) {
15325            isProc = true;
15326            label = _label;
15327            shortLabel = _shortLabel;
15328            pss = _pss;
15329            swapPss = _swapPss;
15330            id = _id;
15331            hasActivities = _hasActivities;
15332        }
15333
15334        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15335            isProc = false;
15336            label = _label;
15337            shortLabel = _shortLabel;
15338            pss = _pss;
15339            swapPss = _swapPss;
15340            id = _id;
15341            hasActivities = false;
15342        }
15343    }
15344
15345    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15346            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15347        if (sort && !isCompact) {
15348            Collections.sort(items, new Comparator<MemItem>() {
15349                @Override
15350                public int compare(MemItem lhs, MemItem rhs) {
15351                    if (lhs.pss < rhs.pss) {
15352                        return 1;
15353                    } else if (lhs.pss > rhs.pss) {
15354                        return -1;
15355                    }
15356                    return 0;
15357                }
15358            });
15359        }
15360
15361        for (int i=0; i<items.size(); i++) {
15362            MemItem mi = items.get(i);
15363            if (!isCompact) {
15364                if (dumpSwapPss) {
15365                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15366                            mi.label, stringifyKBSize(mi.swapPss));
15367                } else {
15368                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15369                }
15370            } else if (mi.isProc) {
15371                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15372                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15373                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15374                pw.println(mi.hasActivities ? ",a" : ",e");
15375            } else {
15376                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15377                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15378            }
15379            if (mi.subitems != null) {
15380                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15381                        true, isCompact, dumpSwapPss);
15382            }
15383        }
15384    }
15385
15386    // These are in KB.
15387    static final long[] DUMP_MEM_BUCKETS = new long[] {
15388        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15389        120*1024, 160*1024, 200*1024,
15390        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15391        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15392    };
15393
15394    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15395            boolean stackLike) {
15396        int start = label.lastIndexOf('.');
15397        if (start >= 0) start++;
15398        else start = 0;
15399        int end = label.length();
15400        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15401            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15402                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15403                out.append(bucket);
15404                out.append(stackLike ? "MB." : "MB ");
15405                out.append(label, start, end);
15406                return;
15407            }
15408        }
15409        out.append(memKB/1024);
15410        out.append(stackLike ? "MB." : "MB ");
15411        out.append(label, start, end);
15412    }
15413
15414    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15415            ProcessList.NATIVE_ADJ,
15416            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15417            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15418            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15419            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15420            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15421            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15422    };
15423    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15424            "Native",
15425            "System", "Persistent", "Persistent Service", "Foreground",
15426            "Visible", "Perceptible",
15427            "Heavy Weight", "Backup",
15428            "A Services", "Home",
15429            "Previous", "B Services", "Cached"
15430    };
15431    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15432            "native",
15433            "sys", "pers", "persvc", "fore",
15434            "vis", "percept",
15435            "heavy", "backup",
15436            "servicea", "home",
15437            "prev", "serviceb", "cached"
15438    };
15439
15440    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15441            long realtime, boolean isCheckinRequest, boolean isCompact) {
15442        if (isCompact) {
15443            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15444        }
15445        if (isCheckinRequest || isCompact) {
15446            // short checkin version
15447            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15448        } else {
15449            pw.println("Applications Memory Usage (in Kilobytes):");
15450            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15451        }
15452    }
15453
15454    private static final int KSM_SHARED = 0;
15455    private static final int KSM_SHARING = 1;
15456    private static final int KSM_UNSHARED = 2;
15457    private static final int KSM_VOLATILE = 3;
15458
15459    private final long[] getKsmInfo() {
15460        long[] longOut = new long[4];
15461        final int[] SINGLE_LONG_FORMAT = new int[] {
15462            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15463        };
15464        long[] longTmp = new long[1];
15465        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15466                SINGLE_LONG_FORMAT, null, longTmp, null);
15467        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15468        longTmp[0] = 0;
15469        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15470                SINGLE_LONG_FORMAT, null, longTmp, null);
15471        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15472        longTmp[0] = 0;
15473        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15474                SINGLE_LONG_FORMAT, null, longTmp, null);
15475        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15476        longTmp[0] = 0;
15477        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15478                SINGLE_LONG_FORMAT, null, longTmp, null);
15479        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15480        return longOut;
15481    }
15482
15483    private static String stringifySize(long size, int order) {
15484        Locale locale = Locale.US;
15485        switch (order) {
15486            case 1:
15487                return String.format(locale, "%,13d", size);
15488            case 1024:
15489                return String.format(locale, "%,9dK", size / 1024);
15490            case 1024 * 1024:
15491                return String.format(locale, "%,5dM", size / 1024 / 1024);
15492            case 1024 * 1024 * 1024:
15493                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15494            default:
15495                throw new IllegalArgumentException("Invalid size order");
15496        }
15497    }
15498
15499    private static String stringifyKBSize(long size) {
15500        return stringifySize(size * 1024, 1024);
15501    }
15502
15503    // Update this version number in case you change the 'compact' format
15504    private static final int MEMINFO_COMPACT_VERSION = 1;
15505
15506    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15507            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15508        boolean dumpDetails = false;
15509        boolean dumpFullDetails = false;
15510        boolean dumpDalvik = false;
15511        boolean dumpSummaryOnly = false;
15512        boolean dumpUnreachable = false;
15513        boolean oomOnly = false;
15514        boolean isCompact = false;
15515        boolean localOnly = false;
15516        boolean packages = false;
15517        boolean isCheckinRequest = false;
15518        boolean dumpSwapPss = false;
15519
15520        int opti = 0;
15521        while (opti < args.length) {
15522            String opt = args[opti];
15523            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15524                break;
15525            }
15526            opti++;
15527            if ("-a".equals(opt)) {
15528                dumpDetails = true;
15529                dumpFullDetails = true;
15530                dumpDalvik = true;
15531                dumpSwapPss = true;
15532            } else if ("-d".equals(opt)) {
15533                dumpDalvik = true;
15534            } else if ("-c".equals(opt)) {
15535                isCompact = true;
15536            } else if ("-s".equals(opt)) {
15537                dumpDetails = true;
15538                dumpSummaryOnly = true;
15539            } else if ("-S".equals(opt)) {
15540                dumpSwapPss = true;
15541            } else if ("--unreachable".equals(opt)) {
15542                dumpUnreachable = true;
15543            } else if ("--oom".equals(opt)) {
15544                oomOnly = true;
15545            } else if ("--local".equals(opt)) {
15546                localOnly = true;
15547            } else if ("--package".equals(opt)) {
15548                packages = true;
15549            } else if ("--checkin".equals(opt)) {
15550                isCheckinRequest = true;
15551
15552            } else if ("-h".equals(opt)) {
15553                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15554                pw.println("  -a: include all available information for each process.");
15555                pw.println("  -d: include dalvik details.");
15556                pw.println("  -c: dump in a compact machine-parseable representation.");
15557                pw.println("  -s: dump only summary of application memory usage.");
15558                pw.println("  -S: dump also SwapPss.");
15559                pw.println("  --oom: only show processes organized by oom adj.");
15560                pw.println("  --local: only collect details locally, don't call process.");
15561                pw.println("  --package: interpret process arg as package, dumping all");
15562                pw.println("             processes that have loaded that package.");
15563                pw.println("  --checkin: dump data for a checkin");
15564                pw.println("If [process] is specified it can be the name or ");
15565                pw.println("pid of a specific process to dump.");
15566                return;
15567            } else {
15568                pw.println("Unknown argument: " + opt + "; use -h for help");
15569            }
15570        }
15571
15572        long uptime = SystemClock.uptimeMillis();
15573        long realtime = SystemClock.elapsedRealtime();
15574        final long[] tmpLong = new long[1];
15575
15576        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15577        if (procs == null) {
15578            // No Java processes.  Maybe they want to print a native process.
15579            if (args != null && args.length > opti
15580                    && args[opti].charAt(0) != '-') {
15581                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15582                        = new ArrayList<ProcessCpuTracker.Stats>();
15583                updateCpuStatsNow();
15584                int findPid = -1;
15585                try {
15586                    findPid = Integer.parseInt(args[opti]);
15587                } catch (NumberFormatException e) {
15588                }
15589                synchronized (mProcessCpuTracker) {
15590                    final int N = mProcessCpuTracker.countStats();
15591                    for (int i=0; i<N; i++) {
15592                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15593                        if (st.pid == findPid || (st.baseName != null
15594                                && st.baseName.equals(args[opti]))) {
15595                            nativeProcs.add(st);
15596                        }
15597                    }
15598                }
15599                if (nativeProcs.size() > 0) {
15600                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15601                            isCompact);
15602                    Debug.MemoryInfo mi = null;
15603                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15604                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15605                        final int pid = r.pid;
15606                        if (!isCheckinRequest && dumpDetails) {
15607                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15608                        }
15609                        if (mi == null) {
15610                            mi = new Debug.MemoryInfo();
15611                        }
15612                        if (dumpDetails || (!brief && !oomOnly)) {
15613                            Debug.getMemoryInfo(pid, mi);
15614                        } else {
15615                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15616                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15617                        }
15618                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15619                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15620                        if (isCheckinRequest) {
15621                            pw.println();
15622                        }
15623                    }
15624                    return;
15625                }
15626            }
15627            pw.println("No process found for: " + args[opti]);
15628            return;
15629        }
15630
15631        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15632            dumpDetails = true;
15633        }
15634
15635        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15636
15637        String[] innerArgs = new String[args.length-opti];
15638        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15639
15640        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15641        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15642        long nativePss = 0;
15643        long nativeSwapPss = 0;
15644        long dalvikPss = 0;
15645        long dalvikSwapPss = 0;
15646        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15647                EmptyArray.LONG;
15648        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15649                EmptyArray.LONG;
15650        long otherPss = 0;
15651        long otherSwapPss = 0;
15652        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15653        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15654
15655        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15656        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15657        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15658                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15659
15660        long totalPss = 0;
15661        long totalSwapPss = 0;
15662        long cachedPss = 0;
15663        long cachedSwapPss = 0;
15664        boolean hasSwapPss = false;
15665
15666        Debug.MemoryInfo mi = null;
15667        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15668            final ProcessRecord r = procs.get(i);
15669            final IApplicationThread thread;
15670            final int pid;
15671            final int oomAdj;
15672            final boolean hasActivities;
15673            synchronized (this) {
15674                thread = r.thread;
15675                pid = r.pid;
15676                oomAdj = r.getSetAdjWithServices();
15677                hasActivities = r.activities.size() > 0;
15678            }
15679            if (thread != null) {
15680                if (!isCheckinRequest && dumpDetails) {
15681                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15682                }
15683                if (mi == null) {
15684                    mi = new Debug.MemoryInfo();
15685                }
15686                if (dumpDetails || (!brief && !oomOnly)) {
15687                    Debug.getMemoryInfo(pid, mi);
15688                    hasSwapPss = mi.hasSwappedOutPss;
15689                } else {
15690                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15691                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15692                }
15693                if (dumpDetails) {
15694                    if (localOnly) {
15695                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15696                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15697                        if (isCheckinRequest) {
15698                            pw.println();
15699                        }
15700                    } else {
15701                        try {
15702                            pw.flush();
15703                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15704                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15705                        } catch (RemoteException e) {
15706                            if (!isCheckinRequest) {
15707                                pw.println("Got RemoteException!");
15708                                pw.flush();
15709                            }
15710                        }
15711                    }
15712                }
15713
15714                final long myTotalPss = mi.getTotalPss();
15715                final long myTotalUss = mi.getTotalUss();
15716                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15717
15718                synchronized (this) {
15719                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15720                        // Record this for posterity if the process has been stable.
15721                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15722                    }
15723                }
15724
15725                if (!isCheckinRequest && mi != null) {
15726                    totalPss += myTotalPss;
15727                    totalSwapPss += myTotalSwapPss;
15728                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15729                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15730                            myTotalSwapPss, pid, hasActivities);
15731                    procMems.add(pssItem);
15732                    procMemsMap.put(pid, pssItem);
15733
15734                    nativePss += mi.nativePss;
15735                    nativeSwapPss += mi.nativeSwappedOutPss;
15736                    dalvikPss += mi.dalvikPss;
15737                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15738                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15739                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15740                        dalvikSubitemSwapPss[j] +=
15741                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15742                    }
15743                    otherPss += mi.otherPss;
15744                    otherSwapPss += mi.otherSwappedOutPss;
15745                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15746                        long mem = mi.getOtherPss(j);
15747                        miscPss[j] += mem;
15748                        otherPss -= mem;
15749                        mem = mi.getOtherSwappedOutPss(j);
15750                        miscSwapPss[j] += mem;
15751                        otherSwapPss -= mem;
15752                    }
15753
15754                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15755                        cachedPss += myTotalPss;
15756                        cachedSwapPss += myTotalSwapPss;
15757                    }
15758
15759                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15760                        if (oomIndex == (oomPss.length - 1)
15761                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15762                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15763                            oomPss[oomIndex] += myTotalPss;
15764                            oomSwapPss[oomIndex] += myTotalSwapPss;
15765                            if (oomProcs[oomIndex] == null) {
15766                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15767                            }
15768                            oomProcs[oomIndex].add(pssItem);
15769                            break;
15770                        }
15771                    }
15772                }
15773            }
15774        }
15775
15776        long nativeProcTotalPss = 0;
15777
15778        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15779            // If we are showing aggregations, also look for native processes to
15780            // include so that our aggregations are more accurate.
15781            updateCpuStatsNow();
15782            mi = null;
15783            synchronized (mProcessCpuTracker) {
15784                final int N = mProcessCpuTracker.countStats();
15785                for (int i=0; i<N; i++) {
15786                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15787                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15788                        if (mi == null) {
15789                            mi = new Debug.MemoryInfo();
15790                        }
15791                        if (!brief && !oomOnly) {
15792                            Debug.getMemoryInfo(st.pid, mi);
15793                        } else {
15794                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15795                            mi.nativePrivateDirty = (int)tmpLong[0];
15796                        }
15797
15798                        final long myTotalPss = mi.getTotalPss();
15799                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15800                        totalPss += myTotalPss;
15801                        nativeProcTotalPss += myTotalPss;
15802
15803                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15804                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15805                        procMems.add(pssItem);
15806
15807                        nativePss += mi.nativePss;
15808                        nativeSwapPss += mi.nativeSwappedOutPss;
15809                        dalvikPss += mi.dalvikPss;
15810                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15811                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15812                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15813                            dalvikSubitemSwapPss[j] +=
15814                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15815                        }
15816                        otherPss += mi.otherPss;
15817                        otherSwapPss += mi.otherSwappedOutPss;
15818                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15819                            long mem = mi.getOtherPss(j);
15820                            miscPss[j] += mem;
15821                            otherPss -= mem;
15822                            mem = mi.getOtherSwappedOutPss(j);
15823                            miscSwapPss[j] += mem;
15824                            otherSwapPss -= mem;
15825                        }
15826                        oomPss[0] += myTotalPss;
15827                        oomSwapPss[0] += myTotalSwapPss;
15828                        if (oomProcs[0] == null) {
15829                            oomProcs[0] = new ArrayList<MemItem>();
15830                        }
15831                        oomProcs[0].add(pssItem);
15832                    }
15833                }
15834            }
15835
15836            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15837
15838            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15839            final MemItem dalvikItem =
15840                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15841            if (dalvikSubitemPss.length > 0) {
15842                dalvikItem.subitems = new ArrayList<MemItem>();
15843                for (int j=0; j<dalvikSubitemPss.length; j++) {
15844                    final String name = Debug.MemoryInfo.getOtherLabel(
15845                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15846                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15847                                    dalvikSubitemSwapPss[j], j));
15848                }
15849            }
15850            catMems.add(dalvikItem);
15851            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15852            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15853                String label = Debug.MemoryInfo.getOtherLabel(j);
15854                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15855            }
15856
15857            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15858            for (int j=0; j<oomPss.length; j++) {
15859                if (oomPss[j] != 0) {
15860                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15861                            : DUMP_MEM_OOM_LABEL[j];
15862                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15863                            DUMP_MEM_OOM_ADJ[j]);
15864                    item.subitems = oomProcs[j];
15865                    oomMems.add(item);
15866                }
15867            }
15868
15869            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15870            if (!brief && !oomOnly && !isCompact) {
15871                pw.println();
15872                pw.println("Total PSS by process:");
15873                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15874                pw.println();
15875            }
15876            if (!isCompact) {
15877                pw.println("Total PSS by OOM adjustment:");
15878            }
15879            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15880            if (!brief && !oomOnly) {
15881                PrintWriter out = categoryPw != null ? categoryPw : pw;
15882                if (!isCompact) {
15883                    out.println();
15884                    out.println("Total PSS by category:");
15885                }
15886                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15887            }
15888            if (!isCompact) {
15889                pw.println();
15890            }
15891            MemInfoReader memInfo = new MemInfoReader();
15892            memInfo.readMemInfo();
15893            if (nativeProcTotalPss > 0) {
15894                synchronized (this) {
15895                    final long cachedKb = memInfo.getCachedSizeKb();
15896                    final long freeKb = memInfo.getFreeSizeKb();
15897                    final long zramKb = memInfo.getZramTotalSizeKb();
15898                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15899                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15900                            kernelKb*1024, nativeProcTotalPss*1024);
15901                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15902                            nativeProcTotalPss);
15903                }
15904            }
15905            if (!brief) {
15906                if (!isCompact) {
15907                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15908                    pw.print(" (status ");
15909                    switch (mLastMemoryLevel) {
15910                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15911                            pw.println("normal)");
15912                            break;
15913                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15914                            pw.println("moderate)");
15915                            break;
15916                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15917                            pw.println("low)");
15918                            break;
15919                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15920                            pw.println("critical)");
15921                            break;
15922                        default:
15923                            pw.print(mLastMemoryLevel);
15924                            pw.println(")");
15925                            break;
15926                    }
15927                    pw.print(" Free RAM: ");
15928                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15929                            + memInfo.getFreeSizeKb()));
15930                    pw.print(" (");
15931                    pw.print(stringifyKBSize(cachedPss));
15932                    pw.print(" cached pss + ");
15933                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15934                    pw.print(" cached kernel + ");
15935                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15936                    pw.println(" free)");
15937                } else {
15938                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15939                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15940                            + memInfo.getFreeSizeKb()); pw.print(",");
15941                    pw.println(totalPss - cachedPss);
15942                }
15943            }
15944            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15945                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15946                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15947            if (!isCompact) {
15948                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15949                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15950                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15951                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15952                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15953            } else {
15954                pw.print("lostram,"); pw.println(lostRAM);
15955            }
15956            if (!brief) {
15957                if (memInfo.getZramTotalSizeKb() != 0) {
15958                    if (!isCompact) {
15959                        pw.print("     ZRAM: ");
15960                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15961                                pw.print(" physical used for ");
15962                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15963                                        - memInfo.getSwapFreeSizeKb()));
15964                                pw.print(" in swap (");
15965                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15966                                pw.println(" total swap)");
15967                    } else {
15968                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15969                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15970                                pw.println(memInfo.getSwapFreeSizeKb());
15971                    }
15972                }
15973                final long[] ksm = getKsmInfo();
15974                if (!isCompact) {
15975                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15976                            || ksm[KSM_VOLATILE] != 0) {
15977                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15978                                pw.print(" saved from shared ");
15979                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15980                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15981                                pw.print(" unshared; ");
15982                                pw.print(stringifyKBSize(
15983                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15984                    }
15985                    pw.print("   Tuning: ");
15986                    pw.print(ActivityManager.staticGetMemoryClass());
15987                    pw.print(" (large ");
15988                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15989                    pw.print("), oom ");
15990                    pw.print(stringifySize(
15991                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15992                    pw.print(", restore limit ");
15993                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15994                    if (ActivityManager.isLowRamDeviceStatic()) {
15995                        pw.print(" (low-ram)");
15996                    }
15997                    if (ActivityManager.isHighEndGfx()) {
15998                        pw.print(" (high-end-gfx)");
15999                    }
16000                    pw.println();
16001                } else {
16002                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16003                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16004                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16005                    pw.print("tuning,");
16006                    pw.print(ActivityManager.staticGetMemoryClass());
16007                    pw.print(',');
16008                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16009                    pw.print(',');
16010                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16011                    if (ActivityManager.isLowRamDeviceStatic()) {
16012                        pw.print(",low-ram");
16013                    }
16014                    if (ActivityManager.isHighEndGfx()) {
16015                        pw.print(",high-end-gfx");
16016                    }
16017                    pw.println();
16018                }
16019            }
16020        }
16021    }
16022
16023    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16024            long memtrack, String name) {
16025        sb.append("  ");
16026        sb.append(ProcessList.makeOomAdjString(oomAdj));
16027        sb.append(' ');
16028        sb.append(ProcessList.makeProcStateString(procState));
16029        sb.append(' ');
16030        ProcessList.appendRamKb(sb, pss);
16031        sb.append(": ");
16032        sb.append(name);
16033        if (memtrack > 0) {
16034            sb.append(" (");
16035            sb.append(stringifyKBSize(memtrack));
16036            sb.append(" memtrack)");
16037        }
16038    }
16039
16040    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16041        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16042        sb.append(" (pid ");
16043        sb.append(mi.pid);
16044        sb.append(") ");
16045        sb.append(mi.adjType);
16046        sb.append('\n');
16047        if (mi.adjReason != null) {
16048            sb.append("                      ");
16049            sb.append(mi.adjReason);
16050            sb.append('\n');
16051        }
16052    }
16053
16054    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16055        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16056        for (int i=0, N=memInfos.size(); i<N; i++) {
16057            ProcessMemInfo mi = memInfos.get(i);
16058            infoMap.put(mi.pid, mi);
16059        }
16060        updateCpuStatsNow();
16061        long[] memtrackTmp = new long[1];
16062        synchronized (mProcessCpuTracker) {
16063            final int N = mProcessCpuTracker.countStats();
16064            for (int i=0; i<N; i++) {
16065                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16066                if (st.vsize > 0) {
16067                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16068                    if (pss > 0) {
16069                        if (infoMap.indexOfKey(st.pid) < 0) {
16070                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16071                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16072                            mi.pss = pss;
16073                            mi.memtrack = memtrackTmp[0];
16074                            memInfos.add(mi);
16075                        }
16076                    }
16077                }
16078            }
16079        }
16080
16081        long totalPss = 0;
16082        long totalMemtrack = 0;
16083        for (int i=0, N=memInfos.size(); i<N; i++) {
16084            ProcessMemInfo mi = memInfos.get(i);
16085            if (mi.pss == 0) {
16086                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16087                mi.memtrack = memtrackTmp[0];
16088            }
16089            totalPss += mi.pss;
16090            totalMemtrack += mi.memtrack;
16091        }
16092        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16093            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16094                if (lhs.oomAdj != rhs.oomAdj) {
16095                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16096                }
16097                if (lhs.pss != rhs.pss) {
16098                    return lhs.pss < rhs.pss ? 1 : -1;
16099                }
16100                return 0;
16101            }
16102        });
16103
16104        StringBuilder tag = new StringBuilder(128);
16105        StringBuilder stack = new StringBuilder(128);
16106        tag.append("Low on memory -- ");
16107        appendMemBucket(tag, totalPss, "total", false);
16108        appendMemBucket(stack, totalPss, "total", true);
16109
16110        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16111        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16112        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16113
16114        boolean firstLine = true;
16115        int lastOomAdj = Integer.MIN_VALUE;
16116        long extraNativeRam = 0;
16117        long extraNativeMemtrack = 0;
16118        long cachedPss = 0;
16119        for (int i=0, N=memInfos.size(); i<N; i++) {
16120            ProcessMemInfo mi = memInfos.get(i);
16121
16122            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16123                cachedPss += mi.pss;
16124            }
16125
16126            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16127                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16128                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16129                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16130                if (lastOomAdj != mi.oomAdj) {
16131                    lastOomAdj = mi.oomAdj;
16132                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16133                        tag.append(" / ");
16134                    }
16135                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16136                        if (firstLine) {
16137                            stack.append(":");
16138                            firstLine = false;
16139                        }
16140                        stack.append("\n\t at ");
16141                    } else {
16142                        stack.append("$");
16143                    }
16144                } else {
16145                    tag.append(" ");
16146                    stack.append("$");
16147                }
16148                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16149                    appendMemBucket(tag, mi.pss, mi.name, false);
16150                }
16151                appendMemBucket(stack, mi.pss, mi.name, true);
16152                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16153                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16154                    stack.append("(");
16155                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16156                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16157                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16158                            stack.append(":");
16159                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16160                        }
16161                    }
16162                    stack.append(")");
16163                }
16164            }
16165
16166            appendMemInfo(fullNativeBuilder, mi);
16167            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16168                // The short form only has native processes that are >= 512K.
16169                if (mi.pss >= 512) {
16170                    appendMemInfo(shortNativeBuilder, mi);
16171                } else {
16172                    extraNativeRam += mi.pss;
16173                    extraNativeMemtrack += mi.memtrack;
16174                }
16175            } else {
16176                // Short form has all other details, but if we have collected RAM
16177                // from smaller native processes let's dump a summary of that.
16178                if (extraNativeRam > 0) {
16179                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16180                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16181                    shortNativeBuilder.append('\n');
16182                    extraNativeRam = 0;
16183                }
16184                appendMemInfo(fullJavaBuilder, mi);
16185            }
16186        }
16187
16188        fullJavaBuilder.append("           ");
16189        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16190        fullJavaBuilder.append(": TOTAL");
16191        if (totalMemtrack > 0) {
16192            fullJavaBuilder.append(" (");
16193            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16194            fullJavaBuilder.append(" memtrack)");
16195        } else {
16196        }
16197        fullJavaBuilder.append("\n");
16198
16199        MemInfoReader memInfo = new MemInfoReader();
16200        memInfo.readMemInfo();
16201        final long[] infos = memInfo.getRawInfo();
16202
16203        StringBuilder memInfoBuilder = new StringBuilder(1024);
16204        Debug.getMemInfo(infos);
16205        memInfoBuilder.append("  MemInfo: ");
16206        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16207        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16208        memInfoBuilder.append(stringifyKBSize(
16209                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16210        memInfoBuilder.append(stringifyKBSize(
16211                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16212        memInfoBuilder.append(stringifyKBSize(
16213                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16214        memInfoBuilder.append("           ");
16215        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16216        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16217        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16218        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16219        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16220            memInfoBuilder.append("  ZRAM: ");
16221            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16222            memInfoBuilder.append(" RAM, ");
16223            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16224            memInfoBuilder.append(" swap total, ");
16225            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16226            memInfoBuilder.append(" swap free\n");
16227        }
16228        final long[] ksm = getKsmInfo();
16229        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16230                || ksm[KSM_VOLATILE] != 0) {
16231            memInfoBuilder.append("  KSM: ");
16232            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16233            memInfoBuilder.append(" saved from shared ");
16234            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16235            memInfoBuilder.append("\n       ");
16236            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16237            memInfoBuilder.append(" unshared; ");
16238            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16239            memInfoBuilder.append(" volatile\n");
16240        }
16241        memInfoBuilder.append("  Free RAM: ");
16242        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16243                + memInfo.getFreeSizeKb()));
16244        memInfoBuilder.append("\n");
16245        memInfoBuilder.append("  Used RAM: ");
16246        memInfoBuilder.append(stringifyKBSize(
16247                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16248        memInfoBuilder.append("\n");
16249        memInfoBuilder.append("  Lost RAM: ");
16250        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16251                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16252                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16253        memInfoBuilder.append("\n");
16254        Slog.i(TAG, "Low on memory:");
16255        Slog.i(TAG, shortNativeBuilder.toString());
16256        Slog.i(TAG, fullJavaBuilder.toString());
16257        Slog.i(TAG, memInfoBuilder.toString());
16258
16259        StringBuilder dropBuilder = new StringBuilder(1024);
16260        /*
16261        StringWriter oomSw = new StringWriter();
16262        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16263        StringWriter catSw = new StringWriter();
16264        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16265        String[] emptyArgs = new String[] { };
16266        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16267        oomPw.flush();
16268        String oomString = oomSw.toString();
16269        */
16270        dropBuilder.append("Low on memory:");
16271        dropBuilder.append(stack);
16272        dropBuilder.append('\n');
16273        dropBuilder.append(fullNativeBuilder);
16274        dropBuilder.append(fullJavaBuilder);
16275        dropBuilder.append('\n');
16276        dropBuilder.append(memInfoBuilder);
16277        dropBuilder.append('\n');
16278        /*
16279        dropBuilder.append(oomString);
16280        dropBuilder.append('\n');
16281        */
16282        StringWriter catSw = new StringWriter();
16283        synchronized (ActivityManagerService.this) {
16284            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16285            String[] emptyArgs = new String[] { };
16286            catPw.println();
16287            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16288            catPw.println();
16289            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16290                    false, null).dumpLocked();
16291            catPw.println();
16292            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16293            catPw.flush();
16294        }
16295        dropBuilder.append(catSw.toString());
16296        addErrorToDropBox("lowmem", null, "system_server", null,
16297                null, tag.toString(), dropBuilder.toString(), null, null);
16298        //Slog.i(TAG, "Sent to dropbox:");
16299        //Slog.i(TAG, dropBuilder.toString());
16300        synchronized (ActivityManagerService.this) {
16301            long now = SystemClock.uptimeMillis();
16302            if (mLastMemUsageReportTime < now) {
16303                mLastMemUsageReportTime = now;
16304            }
16305        }
16306    }
16307
16308    /**
16309     * Searches array of arguments for the specified string
16310     * @param args array of argument strings
16311     * @param value value to search for
16312     * @return true if the value is contained in the array
16313     */
16314    private static boolean scanArgs(String[] args, String value) {
16315        if (args != null) {
16316            for (String arg : args) {
16317                if (value.equals(arg)) {
16318                    return true;
16319                }
16320            }
16321        }
16322        return false;
16323    }
16324
16325    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16326            ContentProviderRecord cpr, boolean always) {
16327        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16328
16329        if (!inLaunching || always) {
16330            synchronized (cpr) {
16331                cpr.launchingApp = null;
16332                cpr.notifyAll();
16333            }
16334            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16335            String names[] = cpr.info.authority.split(";");
16336            for (int j = 0; j < names.length; j++) {
16337                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16338            }
16339        }
16340
16341        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16342            ContentProviderConnection conn = cpr.connections.get(i);
16343            if (conn.waiting) {
16344                // If this connection is waiting for the provider, then we don't
16345                // need to mess with its process unless we are always removing
16346                // or for some reason the provider is not currently launching.
16347                if (inLaunching && !always) {
16348                    continue;
16349                }
16350            }
16351            ProcessRecord capp = conn.client;
16352            conn.dead = true;
16353            if (conn.stableCount > 0) {
16354                if (!capp.persistent && capp.thread != null
16355                        && capp.pid != 0
16356                        && capp.pid != MY_PID) {
16357                    capp.kill("depends on provider "
16358                            + cpr.name.flattenToShortString()
16359                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16360                }
16361            } else if (capp.thread != null && conn.provider.provider != null) {
16362                try {
16363                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16364                } catch (RemoteException e) {
16365                }
16366                // In the protocol here, we don't expect the client to correctly
16367                // clean up this connection, we'll just remove it.
16368                cpr.connections.remove(i);
16369                if (conn.client.conProviders.remove(conn)) {
16370                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16371                }
16372            }
16373        }
16374
16375        if (inLaunching && always) {
16376            mLaunchingProviders.remove(cpr);
16377        }
16378        return inLaunching;
16379    }
16380
16381    /**
16382     * Main code for cleaning up a process when it has gone away.  This is
16383     * called both as a result of the process dying, or directly when stopping
16384     * a process when running in single process mode.
16385     *
16386     * @return Returns true if the given process has been restarted, so the
16387     * app that was passed in must remain on the process lists.
16388     */
16389    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16390            boolean restarting, boolean allowRestart, int index) {
16391        if (index >= 0) {
16392            removeLruProcessLocked(app);
16393            ProcessList.remove(app.pid);
16394        }
16395
16396        mProcessesToGc.remove(app);
16397        mPendingPssProcesses.remove(app);
16398
16399        // Dismiss any open dialogs.
16400        if (app.crashDialog != null && !app.forceCrashReport) {
16401            app.crashDialog.dismiss();
16402            app.crashDialog = null;
16403        }
16404        if (app.anrDialog != null) {
16405            app.anrDialog.dismiss();
16406            app.anrDialog = null;
16407        }
16408        if (app.waitDialog != null) {
16409            app.waitDialog.dismiss();
16410            app.waitDialog = null;
16411        }
16412
16413        app.crashing = false;
16414        app.notResponding = false;
16415
16416        app.resetPackageList(mProcessStats);
16417        app.unlinkDeathRecipient();
16418        app.makeInactive(mProcessStats);
16419        app.waitingToKill = null;
16420        app.forcingToForeground = null;
16421        updateProcessForegroundLocked(app, false, false);
16422        app.foregroundActivities = false;
16423        app.hasShownUi = false;
16424        app.treatLikeActivity = false;
16425        app.hasAboveClient = false;
16426        app.hasClientActivities = false;
16427
16428        mServices.killServicesLocked(app, allowRestart);
16429
16430        boolean restart = false;
16431
16432        // Remove published content providers.
16433        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16434            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16435            final boolean always = app.bad || !allowRestart;
16436            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16437            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16438                // We left the provider in the launching list, need to
16439                // restart it.
16440                restart = true;
16441            }
16442
16443            cpr.provider = null;
16444            cpr.proc = null;
16445        }
16446        app.pubProviders.clear();
16447
16448        // Take care of any launching providers waiting for this process.
16449        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16450            restart = true;
16451        }
16452
16453        // Unregister from connected content providers.
16454        if (!app.conProviders.isEmpty()) {
16455            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16456                ContentProviderConnection conn = app.conProviders.get(i);
16457                conn.provider.connections.remove(conn);
16458                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16459                        conn.provider.name);
16460            }
16461            app.conProviders.clear();
16462        }
16463
16464        // At this point there may be remaining entries in mLaunchingProviders
16465        // where we were the only one waiting, so they are no longer of use.
16466        // Look for these and clean up if found.
16467        // XXX Commented out for now.  Trying to figure out a way to reproduce
16468        // the actual situation to identify what is actually going on.
16469        if (false) {
16470            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16471                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16472                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16473                    synchronized (cpr) {
16474                        cpr.launchingApp = null;
16475                        cpr.notifyAll();
16476                    }
16477                }
16478            }
16479        }
16480
16481        skipCurrentReceiverLocked(app);
16482
16483        // Unregister any receivers.
16484        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16485            removeReceiverLocked(app.receivers.valueAt(i));
16486        }
16487        app.receivers.clear();
16488
16489        // If the app is undergoing backup, tell the backup manager about it
16490        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16491            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16492                    + mBackupTarget.appInfo + " died during backup");
16493            try {
16494                IBackupManager bm = IBackupManager.Stub.asInterface(
16495                        ServiceManager.getService(Context.BACKUP_SERVICE));
16496                bm.agentDisconnected(app.info.packageName);
16497            } catch (RemoteException e) {
16498                // can't happen; backup manager is local
16499            }
16500        }
16501
16502        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16503            ProcessChangeItem item = mPendingProcessChanges.get(i);
16504            if (item.pid == app.pid) {
16505                mPendingProcessChanges.remove(i);
16506                mAvailProcessChanges.add(item);
16507            }
16508        }
16509        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16510                null).sendToTarget();
16511
16512        // If the caller is restarting this app, then leave it in its
16513        // current lists and let the caller take care of it.
16514        if (restarting) {
16515            return false;
16516        }
16517
16518        if (!app.persistent || app.isolated) {
16519            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16520                    "Removing non-persistent process during cleanup: " + app);
16521            removeProcessNameLocked(app.processName, app.uid);
16522            if (mHeavyWeightProcess == app) {
16523                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16524                        mHeavyWeightProcess.userId, 0));
16525                mHeavyWeightProcess = null;
16526            }
16527        } else if (!app.removed) {
16528            // This app is persistent, so we need to keep its record around.
16529            // If it is not already on the pending app list, add it there
16530            // and start a new process for it.
16531            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16532                mPersistentStartingProcesses.add(app);
16533                restart = true;
16534            }
16535        }
16536        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16537                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16538        mProcessesOnHold.remove(app);
16539
16540        if (app == mHomeProcess) {
16541            mHomeProcess = null;
16542        }
16543        if (app == mPreviousProcess) {
16544            mPreviousProcess = null;
16545        }
16546
16547        if (restart && !app.isolated) {
16548            // We have components that still need to be running in the
16549            // process, so re-launch it.
16550            if (index < 0) {
16551                ProcessList.remove(app.pid);
16552            }
16553            addProcessNameLocked(app);
16554            startProcessLocked(app, "restart", app.processName);
16555            return true;
16556        } else if (app.pid > 0 && app.pid != MY_PID) {
16557            // Goodbye!
16558            boolean removed;
16559            synchronized (mPidsSelfLocked) {
16560                mPidsSelfLocked.remove(app.pid);
16561                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16562            }
16563            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16564            if (app.isolated) {
16565                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16566            }
16567            app.setPid(0);
16568        }
16569        return false;
16570    }
16571
16572    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16573        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16574            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16575            if (cpr.launchingApp == app) {
16576                return true;
16577            }
16578        }
16579        return false;
16580    }
16581
16582    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16583        // Look through the content providers we are waiting to have launched,
16584        // and if any run in this process then either schedule a restart of
16585        // the process or kill the client waiting for it if this process has
16586        // gone bad.
16587        boolean restart = false;
16588        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16589            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16590            if (cpr.launchingApp == app) {
16591                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16592                    restart = true;
16593                } else {
16594                    removeDyingProviderLocked(app, cpr, true);
16595                }
16596            }
16597        }
16598        return restart;
16599    }
16600
16601    // =========================================================
16602    // SERVICES
16603    // =========================================================
16604
16605    @Override
16606    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16607            int flags) {
16608        enforceNotIsolatedCaller("getServices");
16609        synchronized (this) {
16610            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16611        }
16612    }
16613
16614    @Override
16615    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16616        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16617        synchronized (this) {
16618            return mServices.getRunningServiceControlPanelLocked(name);
16619        }
16620    }
16621
16622    @Override
16623    public ComponentName startService(IApplicationThread caller, Intent service,
16624            String resolvedType, String callingPackage, int userId)
16625            throws TransactionTooLargeException {
16626        enforceNotIsolatedCaller("startService");
16627        // Refuse possible leaked file descriptors
16628        if (service != null && service.hasFileDescriptors() == true) {
16629            throw new IllegalArgumentException("File descriptors passed in Intent");
16630        }
16631
16632        if (callingPackage == null) {
16633            throw new IllegalArgumentException("callingPackage cannot be null");
16634        }
16635
16636        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16637                "startService: " + service + " type=" + resolvedType);
16638        synchronized(this) {
16639            final int callingPid = Binder.getCallingPid();
16640            final int callingUid = Binder.getCallingUid();
16641            final long origId = Binder.clearCallingIdentity();
16642            ComponentName res = mServices.startServiceLocked(caller, service,
16643                    resolvedType, callingPid, callingUid, callingPackage, userId);
16644            Binder.restoreCallingIdentity(origId);
16645            return res;
16646        }
16647    }
16648
16649    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16650            String callingPackage, int userId)
16651            throws TransactionTooLargeException {
16652        synchronized(this) {
16653            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16654                    "startServiceInPackage: " + service + " type=" + resolvedType);
16655            final long origId = Binder.clearCallingIdentity();
16656            ComponentName res = mServices.startServiceLocked(null, service,
16657                    resolvedType, -1, uid, callingPackage, userId);
16658            Binder.restoreCallingIdentity(origId);
16659            return res;
16660        }
16661    }
16662
16663    @Override
16664    public int stopService(IApplicationThread caller, Intent service,
16665            String resolvedType, int userId) {
16666        enforceNotIsolatedCaller("stopService");
16667        // Refuse possible leaked file descriptors
16668        if (service != null && service.hasFileDescriptors() == true) {
16669            throw new IllegalArgumentException("File descriptors passed in Intent");
16670        }
16671
16672        synchronized(this) {
16673            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16674        }
16675    }
16676
16677    @Override
16678    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16679        enforceNotIsolatedCaller("peekService");
16680        // Refuse possible leaked file descriptors
16681        if (service != null && service.hasFileDescriptors() == true) {
16682            throw new IllegalArgumentException("File descriptors passed in Intent");
16683        }
16684
16685        if (callingPackage == null) {
16686            throw new IllegalArgumentException("callingPackage cannot be null");
16687        }
16688
16689        synchronized(this) {
16690            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16691        }
16692    }
16693
16694    @Override
16695    public boolean stopServiceToken(ComponentName className, IBinder token,
16696            int startId) {
16697        synchronized(this) {
16698            return mServices.stopServiceTokenLocked(className, token, startId);
16699        }
16700    }
16701
16702    @Override
16703    public void setServiceForeground(ComponentName className, IBinder token,
16704            int id, Notification notification, int flags) {
16705        synchronized(this) {
16706            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16707        }
16708    }
16709
16710    @Override
16711    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16712            boolean requireFull, String name, String callerPackage) {
16713        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16714                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16715    }
16716
16717    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16718            String className, int flags) {
16719        boolean result = false;
16720        // For apps that don't have pre-defined UIDs, check for permission
16721        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16722            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16723                if (ActivityManager.checkUidPermission(
16724                        INTERACT_ACROSS_USERS,
16725                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16726                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16727                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16728                            + " requests FLAG_SINGLE_USER, but app does not hold "
16729                            + INTERACT_ACROSS_USERS;
16730                    Slog.w(TAG, msg);
16731                    throw new SecurityException(msg);
16732                }
16733                // Permission passed
16734                result = true;
16735            }
16736        } else if ("system".equals(componentProcessName)) {
16737            result = true;
16738        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16739            // Phone app and persistent apps are allowed to export singleuser providers.
16740            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16741                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16742        }
16743        if (DEBUG_MU) Slog.v(TAG_MU,
16744                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16745                + Integer.toHexString(flags) + ") = " + result);
16746        return result;
16747    }
16748
16749    /**
16750     * Checks to see if the caller is in the same app as the singleton
16751     * component, or the component is in a special app. It allows special apps
16752     * to export singleton components but prevents exporting singleton
16753     * components for regular apps.
16754     */
16755    boolean isValidSingletonCall(int callingUid, int componentUid) {
16756        int componentAppId = UserHandle.getAppId(componentUid);
16757        return UserHandle.isSameApp(callingUid, componentUid)
16758                || componentAppId == Process.SYSTEM_UID
16759                || componentAppId == Process.PHONE_UID
16760                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16761                        == PackageManager.PERMISSION_GRANTED;
16762    }
16763
16764    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16765            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16766            int userId) throws TransactionTooLargeException {
16767        enforceNotIsolatedCaller("bindService");
16768
16769        // Refuse possible leaked file descriptors
16770        if (service != null && service.hasFileDescriptors() == true) {
16771            throw new IllegalArgumentException("File descriptors passed in Intent");
16772        }
16773
16774        if (callingPackage == null) {
16775            throw new IllegalArgumentException("callingPackage cannot be null");
16776        }
16777
16778        synchronized(this) {
16779            return mServices.bindServiceLocked(caller, token, service,
16780                    resolvedType, connection, flags, callingPackage, userId);
16781        }
16782    }
16783
16784    public boolean unbindService(IServiceConnection connection) {
16785        synchronized (this) {
16786            return mServices.unbindServiceLocked(connection);
16787        }
16788    }
16789
16790    public void publishService(IBinder token, Intent intent, IBinder service) {
16791        // Refuse possible leaked file descriptors
16792        if (intent != null && intent.hasFileDescriptors() == true) {
16793            throw new IllegalArgumentException("File descriptors passed in Intent");
16794        }
16795
16796        synchronized(this) {
16797            if (!(token instanceof ServiceRecord)) {
16798                throw new IllegalArgumentException("Invalid service token");
16799            }
16800            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16801        }
16802    }
16803
16804    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16805        // Refuse possible leaked file descriptors
16806        if (intent != null && intent.hasFileDescriptors() == true) {
16807            throw new IllegalArgumentException("File descriptors passed in Intent");
16808        }
16809
16810        synchronized(this) {
16811            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16812        }
16813    }
16814
16815    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16816        synchronized(this) {
16817            if (!(token instanceof ServiceRecord)) {
16818                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16819                throw new IllegalArgumentException("Invalid service token");
16820            }
16821            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16822        }
16823    }
16824
16825    // =========================================================
16826    // BACKUP AND RESTORE
16827    // =========================================================
16828
16829    // Cause the target app to be launched if necessary and its backup agent
16830    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16831    // activity manager to announce its creation.
16832    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16833        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16834                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16835        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16836
16837        synchronized(this) {
16838            // !!! TODO: currently no check here that we're already bound
16839            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16840            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16841            synchronized (stats) {
16842                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16843            }
16844
16845            // Backup agent is now in use, its package can't be stopped.
16846            try {
16847                AppGlobals.getPackageManager().setPackageStoppedState(
16848                        app.packageName, false, UserHandle.getUserId(app.uid));
16849            } catch (RemoteException e) {
16850            } catch (IllegalArgumentException e) {
16851                Slog.w(TAG, "Failed trying to unstop package "
16852                        + app.packageName + ": " + e);
16853            }
16854
16855            BackupRecord r = new BackupRecord(ss, app, backupMode);
16856            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16857                    ? new ComponentName(app.packageName, app.backupAgentName)
16858                    : new ComponentName("android", "FullBackupAgent");
16859            // startProcessLocked() returns existing proc's record if it's already running
16860            ProcessRecord proc = startProcessLocked(app.processName, app,
16861                    false, 0, "backup", hostingName, false, false, false);
16862            if (proc == null) {
16863                Slog.e(TAG, "Unable to start backup agent process " + r);
16864                return false;
16865            }
16866
16867            r.app = proc;
16868            mBackupTarget = r;
16869            mBackupAppName = app.packageName;
16870
16871            // Try not to kill the process during backup
16872            updateOomAdjLocked(proc);
16873
16874            // If the process is already attached, schedule the creation of the backup agent now.
16875            // If it is not yet live, this will be done when it attaches to the framework.
16876            if (proc.thread != null) {
16877                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16878                try {
16879                    proc.thread.scheduleCreateBackupAgent(app,
16880                            compatibilityInfoForPackageLocked(app), backupMode);
16881                } catch (RemoteException e) {
16882                    // Will time out on the backup manager side
16883                }
16884            } else {
16885                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16886            }
16887            // Invariants: at this point, the target app process exists and the application
16888            // is either already running or in the process of coming up.  mBackupTarget and
16889            // mBackupAppName describe the app, so that when it binds back to the AM we
16890            // know that it's scheduled for a backup-agent operation.
16891        }
16892
16893        return true;
16894    }
16895
16896    @Override
16897    public void clearPendingBackup() {
16898        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16899        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16900
16901        synchronized (this) {
16902            mBackupTarget = null;
16903            mBackupAppName = null;
16904        }
16905    }
16906
16907    // A backup agent has just come up
16908    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16909        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16910                + " = " + agent);
16911
16912        synchronized(this) {
16913            if (!agentPackageName.equals(mBackupAppName)) {
16914                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16915                return;
16916            }
16917        }
16918
16919        long oldIdent = Binder.clearCallingIdentity();
16920        try {
16921            IBackupManager bm = IBackupManager.Stub.asInterface(
16922                    ServiceManager.getService(Context.BACKUP_SERVICE));
16923            bm.agentConnected(agentPackageName, agent);
16924        } catch (RemoteException e) {
16925            // can't happen; the backup manager service is local
16926        } catch (Exception e) {
16927            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16928            e.printStackTrace();
16929        } finally {
16930            Binder.restoreCallingIdentity(oldIdent);
16931        }
16932    }
16933
16934    // done with this agent
16935    public void unbindBackupAgent(ApplicationInfo appInfo) {
16936        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16937        if (appInfo == null) {
16938            Slog.w(TAG, "unbind backup agent for null app");
16939            return;
16940        }
16941
16942        synchronized(this) {
16943            try {
16944                if (mBackupAppName == null) {
16945                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16946                    return;
16947                }
16948
16949                if (!mBackupAppName.equals(appInfo.packageName)) {
16950                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16951                    return;
16952                }
16953
16954                // Not backing this app up any more; reset its OOM adjustment
16955                final ProcessRecord proc = mBackupTarget.app;
16956                updateOomAdjLocked(proc);
16957
16958                // If the app crashed during backup, 'thread' will be null here
16959                if (proc.thread != null) {
16960                    try {
16961                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16962                                compatibilityInfoForPackageLocked(appInfo));
16963                    } catch (Exception e) {
16964                        Slog.e(TAG, "Exception when unbinding backup agent:");
16965                        e.printStackTrace();
16966                    }
16967                }
16968            } finally {
16969                mBackupTarget = null;
16970                mBackupAppName = null;
16971            }
16972        }
16973    }
16974    // =========================================================
16975    // BROADCASTS
16976    // =========================================================
16977
16978    boolean isPendingBroadcastProcessLocked(int pid) {
16979        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16980                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16981    }
16982
16983    void skipPendingBroadcastLocked(int pid) {
16984            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16985            for (BroadcastQueue queue : mBroadcastQueues) {
16986                queue.skipPendingBroadcastLocked(pid);
16987            }
16988    }
16989
16990    // The app just attached; send any pending broadcasts that it should receive
16991    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16992        boolean didSomething = false;
16993        for (BroadcastQueue queue : mBroadcastQueues) {
16994            didSomething |= queue.sendPendingBroadcastsLocked(app);
16995        }
16996        return didSomething;
16997    }
16998
16999    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17000            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17001        enforceNotIsolatedCaller("registerReceiver");
17002        ArrayList<Intent> stickyIntents = null;
17003        ProcessRecord callerApp = null;
17004        int callingUid;
17005        int callingPid;
17006        synchronized(this) {
17007            if (caller != null) {
17008                callerApp = getRecordForAppLocked(caller);
17009                if (callerApp == null) {
17010                    throw new SecurityException(
17011                            "Unable to find app for caller " + caller
17012                            + " (pid=" + Binder.getCallingPid()
17013                            + ") when registering receiver " + receiver);
17014                }
17015                if (callerApp.info.uid != Process.SYSTEM_UID &&
17016                        !callerApp.pkgList.containsKey(callerPackage) &&
17017                        !"android".equals(callerPackage)) {
17018                    throw new SecurityException("Given caller package " + callerPackage
17019                            + " is not running in process " + callerApp);
17020                }
17021                callingUid = callerApp.info.uid;
17022                callingPid = callerApp.pid;
17023            } else {
17024                callerPackage = null;
17025                callingUid = Binder.getCallingUid();
17026                callingPid = Binder.getCallingPid();
17027            }
17028
17029            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17030                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17031
17032            Iterator<String> actions = filter.actionsIterator();
17033            if (actions == null) {
17034                ArrayList<String> noAction = new ArrayList<String>(1);
17035                noAction.add(null);
17036                actions = noAction.iterator();
17037            }
17038
17039            // Collect stickies of users
17040            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17041            while (actions.hasNext()) {
17042                String action = actions.next();
17043                for (int id : userIds) {
17044                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17045                    if (stickies != null) {
17046                        ArrayList<Intent> intents = stickies.get(action);
17047                        if (intents != null) {
17048                            if (stickyIntents == null) {
17049                                stickyIntents = new ArrayList<Intent>();
17050                            }
17051                            stickyIntents.addAll(intents);
17052                        }
17053                    }
17054                }
17055            }
17056        }
17057
17058        ArrayList<Intent> allSticky = null;
17059        if (stickyIntents != null) {
17060            final ContentResolver resolver = mContext.getContentResolver();
17061            // Look for any matching sticky broadcasts...
17062            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17063                Intent intent = stickyIntents.get(i);
17064                // If intent has scheme "content", it will need to acccess
17065                // provider that needs to lock mProviderMap in ActivityThread
17066                // and also it may need to wait application response, so we
17067                // cannot lock ActivityManagerService here.
17068                if (filter.match(resolver, intent, true, TAG) >= 0) {
17069                    if (allSticky == null) {
17070                        allSticky = new ArrayList<Intent>();
17071                    }
17072                    allSticky.add(intent);
17073                }
17074            }
17075        }
17076
17077        // The first sticky in the list is returned directly back to the client.
17078        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17079        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17080        if (receiver == null) {
17081            return sticky;
17082        }
17083
17084        synchronized (this) {
17085            if (callerApp != null && (callerApp.thread == null
17086                    || callerApp.thread.asBinder() != caller.asBinder())) {
17087                // Original caller already died
17088                return null;
17089            }
17090            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17091            if (rl == null) {
17092                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17093                        userId, receiver);
17094                if (rl.app != null) {
17095                    rl.app.receivers.add(rl);
17096                } else {
17097                    try {
17098                        receiver.asBinder().linkToDeath(rl, 0);
17099                    } catch (RemoteException e) {
17100                        return sticky;
17101                    }
17102                    rl.linkedToDeath = true;
17103                }
17104                mRegisteredReceivers.put(receiver.asBinder(), rl);
17105            } else if (rl.uid != callingUid) {
17106                throw new IllegalArgumentException(
17107                        "Receiver requested to register for uid " + callingUid
17108                        + " was previously registered for uid " + rl.uid);
17109            } else if (rl.pid != callingPid) {
17110                throw new IllegalArgumentException(
17111                        "Receiver requested to register for pid " + callingPid
17112                        + " was previously registered for pid " + rl.pid);
17113            } else if (rl.userId != userId) {
17114                throw new IllegalArgumentException(
17115                        "Receiver requested to register for user " + userId
17116                        + " was previously registered for user " + rl.userId);
17117            }
17118            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17119                    permission, callingUid, userId);
17120            rl.add(bf);
17121            if (!bf.debugCheck()) {
17122                Slog.w(TAG, "==> For Dynamic broadcast");
17123            }
17124            mReceiverResolver.addFilter(bf);
17125
17126            // Enqueue broadcasts for all existing stickies that match
17127            // this filter.
17128            if (allSticky != null) {
17129                ArrayList receivers = new ArrayList();
17130                receivers.add(bf);
17131
17132                final int stickyCount = allSticky.size();
17133                for (int i = 0; i < stickyCount; i++) {
17134                    Intent intent = allSticky.get(i);
17135                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17136                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17137                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17138                            null, 0, null, null, false, true, true, -1);
17139                    queue.enqueueParallelBroadcastLocked(r);
17140                    queue.scheduleBroadcastsLocked();
17141                }
17142            }
17143
17144            return sticky;
17145        }
17146    }
17147
17148    public void unregisterReceiver(IIntentReceiver receiver) {
17149        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17150
17151        final long origId = Binder.clearCallingIdentity();
17152        try {
17153            boolean doTrim = false;
17154
17155            synchronized(this) {
17156                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17157                if (rl != null) {
17158                    final BroadcastRecord r = rl.curBroadcast;
17159                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17160                        final boolean doNext = r.queue.finishReceiverLocked(
17161                                r, r.resultCode, r.resultData, r.resultExtras,
17162                                r.resultAbort, false);
17163                        if (doNext) {
17164                            doTrim = true;
17165                            r.queue.processNextBroadcast(false);
17166                        }
17167                    }
17168
17169                    if (rl.app != null) {
17170                        rl.app.receivers.remove(rl);
17171                    }
17172                    removeReceiverLocked(rl);
17173                    if (rl.linkedToDeath) {
17174                        rl.linkedToDeath = false;
17175                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17176                    }
17177                }
17178            }
17179
17180            // If we actually concluded any broadcasts, we might now be able
17181            // to trim the recipients' apps from our working set
17182            if (doTrim) {
17183                trimApplications();
17184                return;
17185            }
17186
17187        } finally {
17188            Binder.restoreCallingIdentity(origId);
17189        }
17190    }
17191
17192    void removeReceiverLocked(ReceiverList rl) {
17193        mRegisteredReceivers.remove(rl.receiver.asBinder());
17194        for (int i = rl.size() - 1; i >= 0; i--) {
17195            mReceiverResolver.removeFilter(rl.get(i));
17196        }
17197    }
17198
17199    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17200        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17201            ProcessRecord r = mLruProcesses.get(i);
17202            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17203                try {
17204                    r.thread.dispatchPackageBroadcast(cmd, packages);
17205                } catch (RemoteException ex) {
17206                }
17207            }
17208        }
17209    }
17210
17211    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17212            int callingUid, int[] users) {
17213        // TODO: come back and remove this assumption to triage all broadcasts
17214        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17215
17216        List<ResolveInfo> receivers = null;
17217        try {
17218            HashSet<ComponentName> singleUserReceivers = null;
17219            boolean scannedFirstReceivers = false;
17220            for (int user : users) {
17221                // Skip users that have Shell restrictions, with exception of always permitted
17222                // Shell broadcasts
17223                if (callingUid == Process.SHELL_UID
17224                        && mUserController.hasUserRestriction(
17225                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17226                        && !isPermittedShellBroadcast(intent)) {
17227                    continue;
17228                }
17229                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17230                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17231                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17232                    // If this is not the system user, we need to check for
17233                    // any receivers that should be filtered out.
17234                    for (int i=0; i<newReceivers.size(); i++) {
17235                        ResolveInfo ri = newReceivers.get(i);
17236                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17237                            newReceivers.remove(i);
17238                            i--;
17239                        }
17240                    }
17241                }
17242                if (newReceivers != null && newReceivers.size() == 0) {
17243                    newReceivers = null;
17244                }
17245                if (receivers == null) {
17246                    receivers = newReceivers;
17247                } else if (newReceivers != null) {
17248                    // We need to concatenate the additional receivers
17249                    // found with what we have do far.  This would be easy,
17250                    // but we also need to de-dup any receivers that are
17251                    // singleUser.
17252                    if (!scannedFirstReceivers) {
17253                        // Collect any single user receivers we had already retrieved.
17254                        scannedFirstReceivers = true;
17255                        for (int i=0; i<receivers.size(); i++) {
17256                            ResolveInfo ri = receivers.get(i);
17257                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17258                                ComponentName cn = new ComponentName(
17259                                        ri.activityInfo.packageName, ri.activityInfo.name);
17260                                if (singleUserReceivers == null) {
17261                                    singleUserReceivers = new HashSet<ComponentName>();
17262                                }
17263                                singleUserReceivers.add(cn);
17264                            }
17265                        }
17266                    }
17267                    // Add the new results to the existing results, tracking
17268                    // and de-dupping single user receivers.
17269                    for (int i=0; i<newReceivers.size(); i++) {
17270                        ResolveInfo ri = newReceivers.get(i);
17271                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17272                            ComponentName cn = new ComponentName(
17273                                    ri.activityInfo.packageName, ri.activityInfo.name);
17274                            if (singleUserReceivers == null) {
17275                                singleUserReceivers = new HashSet<ComponentName>();
17276                            }
17277                            if (!singleUserReceivers.contains(cn)) {
17278                                singleUserReceivers.add(cn);
17279                                receivers.add(ri);
17280                            }
17281                        } else {
17282                            receivers.add(ri);
17283                        }
17284                    }
17285                }
17286            }
17287        } catch (RemoteException ex) {
17288            // pm is in same process, this will never happen.
17289        }
17290        return receivers;
17291    }
17292
17293    private boolean isPermittedShellBroadcast(Intent intent) {
17294        // remote bugreport should always be allowed to be taken
17295        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17296    }
17297
17298    final int broadcastIntentLocked(ProcessRecord callerApp,
17299            String callerPackage, Intent intent, String resolvedType,
17300            IIntentReceiver resultTo, int resultCode, String resultData,
17301            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17302            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17303        intent = new Intent(intent);
17304
17305        // By default broadcasts do not go to stopped apps.
17306        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17307
17308        // If we have not finished booting, don't allow this to launch new processes.
17309        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17310            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17311        }
17312
17313        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17314                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17315                + " ordered=" + ordered + " userid=" + userId);
17316        if ((resultTo != null) && !ordered) {
17317            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17318        }
17319
17320        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17321                ALLOW_NON_FULL, "broadcast", callerPackage);
17322
17323        // Make sure that the user who is receiving this broadcast is running.
17324        // If not, we will just skip it. Make an exception for shutdown broadcasts
17325        // and upgrade steps.
17326
17327        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17328            if ((callingUid != Process.SYSTEM_UID
17329                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17330                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17331                Slog.w(TAG, "Skipping broadcast of " + intent
17332                        + ": user " + userId + " is stopped");
17333                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17334            }
17335        }
17336
17337        BroadcastOptions brOptions = null;
17338        if (bOptions != null) {
17339            brOptions = new BroadcastOptions(bOptions);
17340            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17341                // See if the caller is allowed to do this.  Note we are checking against
17342                // the actual real caller (not whoever provided the operation as say a
17343                // PendingIntent), because that who is actually supplied the arguments.
17344                if (checkComponentPermission(
17345                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17346                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17347                        != PackageManager.PERMISSION_GRANTED) {
17348                    String msg = "Permission Denial: " + intent.getAction()
17349                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17350                            + ", uid=" + callingUid + ")"
17351                            + " requires "
17352                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17353                    Slog.w(TAG, msg);
17354                    throw new SecurityException(msg);
17355                }
17356            }
17357        }
17358
17359        // Verify that protected broadcasts are only being sent by system code,
17360        // and that system code is only sending protected broadcasts.
17361        final String action = intent.getAction();
17362        final boolean isProtectedBroadcast;
17363        try {
17364            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17365        } catch (RemoteException e) {
17366            Slog.w(TAG, "Remote exception", e);
17367            return ActivityManager.BROADCAST_SUCCESS;
17368        }
17369
17370        final boolean isCallerSystem;
17371        switch (UserHandle.getAppId(callingUid)) {
17372            case Process.ROOT_UID:
17373            case Process.SYSTEM_UID:
17374            case Process.PHONE_UID:
17375            case Process.BLUETOOTH_UID:
17376            case Process.NFC_UID:
17377                isCallerSystem = true;
17378                break;
17379            default:
17380                isCallerSystem = (callerApp != null) && callerApp.persistent;
17381                break;
17382        }
17383
17384        if (isCallerSystem) {
17385            if (isProtectedBroadcast
17386                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17387                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17388                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17389                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17390                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17391                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17392                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17393                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17394                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17395                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17396                // Broadcast is either protected, or it's a public action that
17397                // we've relaxed, so it's fine for system internals to send.
17398            } else {
17399                // The vast majority of broadcasts sent from system internals
17400                // should be protected to avoid security holes, so yell loudly
17401                // to ensure we examine these cases.
17402                if (callerApp != null) {
17403                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17404                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17405                            new Throwable());
17406                } else {
17407                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17408                            + " from system uid " + UserHandle.formatUid(callingUid)
17409                            + " pkg " + callerPackage,
17410                            new Throwable());
17411                }
17412            }
17413
17414        } else {
17415            if (isProtectedBroadcast) {
17416                String msg = "Permission Denial: not allowed to send broadcast "
17417                        + action + " from pid="
17418                        + callingPid + ", uid=" + callingUid;
17419                Slog.w(TAG, msg);
17420                throw new SecurityException(msg);
17421
17422            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17423                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17424                // Special case for compatibility: we don't want apps to send this,
17425                // but historically it has not been protected and apps may be using it
17426                // to poke their own app widget.  So, instead of making it protected,
17427                // just limit it to the caller.
17428                if (callerPackage == null) {
17429                    String msg = "Permission Denial: not allowed to send broadcast "
17430                            + action + " from unknown caller.";
17431                    Slog.w(TAG, msg);
17432                    throw new SecurityException(msg);
17433                } else if (intent.getComponent() != null) {
17434                    // They are good enough to send to an explicit component...  verify
17435                    // it is being sent to the calling app.
17436                    if (!intent.getComponent().getPackageName().equals(
17437                            callerPackage)) {
17438                        String msg = "Permission Denial: not allowed to send broadcast "
17439                                + action + " to "
17440                                + intent.getComponent().getPackageName() + " from "
17441                                + callerPackage;
17442                        Slog.w(TAG, msg);
17443                        throw new SecurityException(msg);
17444                    }
17445                } else {
17446                    // Limit broadcast to their own package.
17447                    intent.setPackage(callerPackage);
17448                }
17449            }
17450        }
17451
17452        if (action != null) {
17453            switch (action) {
17454                case Intent.ACTION_UID_REMOVED:
17455                case Intent.ACTION_PACKAGE_REMOVED:
17456                case Intent.ACTION_PACKAGE_CHANGED:
17457                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17458                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17459                case Intent.ACTION_PACKAGES_SUSPENDED:
17460                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17461                    // Handle special intents: if this broadcast is from the package
17462                    // manager about a package being removed, we need to remove all of
17463                    // its activities from the history stack.
17464                    if (checkComponentPermission(
17465                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17466                            callingPid, callingUid, -1, true)
17467                            != PackageManager.PERMISSION_GRANTED) {
17468                        String msg = "Permission Denial: " + intent.getAction()
17469                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17470                                + ", uid=" + callingUid + ")"
17471                                + " requires "
17472                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17473                        Slog.w(TAG, msg);
17474                        throw new SecurityException(msg);
17475                    }
17476                    switch (action) {
17477                        case Intent.ACTION_UID_REMOVED:
17478                            final Bundle intentExtras = intent.getExtras();
17479                            final int uid = intentExtras != null
17480                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17481                            if (uid >= 0) {
17482                                mBatteryStatsService.removeUid(uid);
17483                                mAppOpsService.uidRemoved(uid);
17484                            }
17485                            break;
17486                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17487                            // If resources are unavailable just force stop all those packages
17488                            // and flush the attribute cache as well.
17489                            String list[] =
17490                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17491                            if (list != null && list.length > 0) {
17492                                for (int i = 0; i < list.length; i++) {
17493                                    forceStopPackageLocked(list[i], -1, false, true, true,
17494                                            false, false, userId, "storage unmount");
17495                                }
17496                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17497                                sendPackageBroadcastLocked(
17498                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17499                                        userId);
17500                            }
17501                            break;
17502                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17503                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17504                            break;
17505                        case Intent.ACTION_PACKAGE_REMOVED:
17506                        case Intent.ACTION_PACKAGE_CHANGED:
17507                            Uri data = intent.getData();
17508                            String ssp;
17509                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17510                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17511                                final boolean replacing =
17512                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17513                                final boolean killProcess =
17514                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17515                                final boolean fullUninstall = removed && !replacing;
17516                                if (killProcess) {
17517                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17518                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17519                                            false, true, true, false, fullUninstall, userId,
17520                                            removed ? "pkg removed" : "pkg changed");
17521                                }
17522                                if (removed) {
17523                                    final int cmd = killProcess
17524                                            ? IApplicationThread.PACKAGE_REMOVED
17525                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17526                                    sendPackageBroadcastLocked(cmd,
17527                                            new String[] {ssp}, userId);
17528                                    if (fullUninstall) {
17529                                        mAppOpsService.packageRemoved(
17530                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17531
17532                                        // Remove all permissions granted from/to this package
17533                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17534
17535                                        removeTasksByPackageNameLocked(ssp, userId);
17536                                        mBatteryStatsService.notePackageUninstalled(ssp);
17537                                    }
17538                                } else {
17539                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17540                                            intent.getStringArrayExtra(
17541                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17542                                }
17543                            }
17544                            break;
17545                        case Intent.ACTION_PACKAGES_SUSPENDED:
17546                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17547                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17548                                    intent.getAction());
17549                            final String[] packageNames = intent.getStringArrayExtra(
17550                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17551                            final int userHandle = intent.getIntExtra(
17552                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17553
17554                            synchronized(ActivityManagerService.this) {
17555                                mRecentTasks.onPackagesSuspendedChanged(
17556                                        packageNames, suspended, userHandle);
17557                            }
17558                            break;
17559                    }
17560                    break;
17561                case Intent.ACTION_PACKAGE_REPLACED:
17562                {
17563                    final Uri data = intent.getData();
17564                    final String ssp;
17565                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17566                        final ApplicationInfo aInfo =
17567                                getPackageManagerInternalLocked().getApplicationInfo(
17568                                        ssp,
17569                                        userId);
17570                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17571                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17572                                new String[] {ssp}, userId);
17573                    }
17574                    break;
17575                }
17576                case Intent.ACTION_PACKAGE_ADDED:
17577                {
17578                    // Special case for adding a package: by default turn on compatibility mode.
17579                    Uri data = intent.getData();
17580                    String ssp;
17581                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17582                        final boolean replacing =
17583                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17584                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17585
17586                        try {
17587                            ApplicationInfo ai = AppGlobals.getPackageManager().
17588                                    getApplicationInfo(ssp, 0, 0);
17589                            mBatteryStatsService.notePackageInstalled(ssp,
17590                                    ai != null ? ai.versionCode : 0);
17591                        } catch (RemoteException e) {
17592                        }
17593                    }
17594                    break;
17595                }
17596                case Intent.ACTION_TIMEZONE_CHANGED:
17597                    // If this is the time zone changed action, queue up a message that will reset
17598                    // the timezone of all currently running processes. This message will get
17599                    // queued up before the broadcast happens.
17600                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17601                    break;
17602                case Intent.ACTION_TIME_CHANGED:
17603                    // If the user set the time, let all running processes know.
17604                    final int is24Hour =
17605                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17606                                    : 0;
17607                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17608                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17609                    synchronized (stats) {
17610                        stats.noteCurrentTimeChangedLocked();
17611                    }
17612                    break;
17613                case Intent.ACTION_CLEAR_DNS_CACHE:
17614                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17615                    break;
17616                case Proxy.PROXY_CHANGE_ACTION:
17617                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17618                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17619                    break;
17620                case android.hardware.Camera.ACTION_NEW_PICTURE:
17621                case android.hardware.Camera.ACTION_NEW_VIDEO:
17622                    // These broadcasts are no longer allowed by the system, since they can
17623                    // cause significant thrashing at a crictical point (using the camera).
17624                    // Apps should use JobScehduler to monitor for media provider changes.
17625                    Slog.w(TAG, action + " no longer allowed; dropping from "
17626                            + UserHandle.formatUid(callingUid));
17627                    // Lie; we don't want to crash the app.
17628                    return ActivityManager.BROADCAST_SUCCESS;
17629            }
17630        }
17631
17632        // Add to the sticky list if requested.
17633        if (sticky) {
17634            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17635                    callingPid, callingUid)
17636                    != PackageManager.PERMISSION_GRANTED) {
17637                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17638                        + callingPid + ", uid=" + callingUid
17639                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17640                Slog.w(TAG, msg);
17641                throw new SecurityException(msg);
17642            }
17643            if (requiredPermissions != null && requiredPermissions.length > 0) {
17644                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17645                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17646                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17647            }
17648            if (intent.getComponent() != null) {
17649                throw new SecurityException(
17650                        "Sticky broadcasts can't target a specific component");
17651            }
17652            // We use userId directly here, since the "all" target is maintained
17653            // as a separate set of sticky broadcasts.
17654            if (userId != UserHandle.USER_ALL) {
17655                // But first, if this is not a broadcast to all users, then
17656                // make sure it doesn't conflict with an existing broadcast to
17657                // all users.
17658                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17659                        UserHandle.USER_ALL);
17660                if (stickies != null) {
17661                    ArrayList<Intent> list = stickies.get(intent.getAction());
17662                    if (list != null) {
17663                        int N = list.size();
17664                        int i;
17665                        for (i=0; i<N; i++) {
17666                            if (intent.filterEquals(list.get(i))) {
17667                                throw new IllegalArgumentException(
17668                                        "Sticky broadcast " + intent + " for user "
17669                                        + userId + " conflicts with existing global broadcast");
17670                            }
17671                        }
17672                    }
17673                }
17674            }
17675            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17676            if (stickies == null) {
17677                stickies = new ArrayMap<>();
17678                mStickyBroadcasts.put(userId, stickies);
17679            }
17680            ArrayList<Intent> list = stickies.get(intent.getAction());
17681            if (list == null) {
17682                list = new ArrayList<>();
17683                stickies.put(intent.getAction(), list);
17684            }
17685            final int stickiesCount = list.size();
17686            int i;
17687            for (i = 0; i < stickiesCount; i++) {
17688                if (intent.filterEquals(list.get(i))) {
17689                    // This sticky already exists, replace it.
17690                    list.set(i, new Intent(intent));
17691                    break;
17692                }
17693            }
17694            if (i >= stickiesCount) {
17695                list.add(new Intent(intent));
17696            }
17697        }
17698
17699        int[] users;
17700        if (userId == UserHandle.USER_ALL) {
17701            // Caller wants broadcast to go to all started users.
17702            users = mUserController.getStartedUserArrayLocked();
17703        } else {
17704            // Caller wants broadcast to go to one specific user.
17705            users = new int[] {userId};
17706        }
17707
17708        // Figure out who all will receive this broadcast.
17709        List receivers = null;
17710        List<BroadcastFilter> registeredReceivers = null;
17711        // Need to resolve the intent to interested receivers...
17712        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17713                 == 0) {
17714            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17715        }
17716        if (intent.getComponent() == null) {
17717            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17718                // Query one target user at a time, excluding shell-restricted users
17719                for (int i = 0; i < users.length; i++) {
17720                    if (mUserController.hasUserRestriction(
17721                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17722                        continue;
17723                    }
17724                    List<BroadcastFilter> registeredReceiversForUser =
17725                            mReceiverResolver.queryIntent(intent,
17726                                    resolvedType, false, users[i]);
17727                    if (registeredReceivers == null) {
17728                        registeredReceivers = registeredReceiversForUser;
17729                    } else if (registeredReceiversForUser != null) {
17730                        registeredReceivers.addAll(registeredReceiversForUser);
17731                    }
17732                }
17733            } else {
17734                registeredReceivers = mReceiverResolver.queryIntent(intent,
17735                        resolvedType, false, userId);
17736            }
17737        }
17738
17739        final boolean replacePending =
17740                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17741
17742        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17743                + " replacePending=" + replacePending);
17744
17745        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17746        if (!ordered && NR > 0) {
17747            // If we are not serializing this broadcast, then send the
17748            // registered receivers separately so they don't wait for the
17749            // components to be launched.
17750            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17751            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17752                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17753                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17754                    resultExtras, ordered, sticky, false, userId);
17755            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17756            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17757            if (!replaced) {
17758                queue.enqueueParallelBroadcastLocked(r);
17759                queue.scheduleBroadcastsLocked();
17760            }
17761            registeredReceivers = null;
17762            NR = 0;
17763        }
17764
17765        // Merge into one list.
17766        int ir = 0;
17767        if (receivers != null) {
17768            // A special case for PACKAGE_ADDED: do not allow the package
17769            // being added to see this broadcast.  This prevents them from
17770            // using this as a back door to get run as soon as they are
17771            // installed.  Maybe in the future we want to have a special install
17772            // broadcast or such for apps, but we'd like to deliberately make
17773            // this decision.
17774            String skipPackages[] = null;
17775            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17776                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17777                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17778                Uri data = intent.getData();
17779                if (data != null) {
17780                    String pkgName = data.getSchemeSpecificPart();
17781                    if (pkgName != null) {
17782                        skipPackages = new String[] { pkgName };
17783                    }
17784                }
17785            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17786                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17787            }
17788            if (skipPackages != null && (skipPackages.length > 0)) {
17789                for (String skipPackage : skipPackages) {
17790                    if (skipPackage != null) {
17791                        int NT = receivers.size();
17792                        for (int it=0; it<NT; it++) {
17793                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17794                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17795                                receivers.remove(it);
17796                                it--;
17797                                NT--;
17798                            }
17799                        }
17800                    }
17801                }
17802            }
17803
17804            int NT = receivers != null ? receivers.size() : 0;
17805            int it = 0;
17806            ResolveInfo curt = null;
17807            BroadcastFilter curr = null;
17808            while (it < NT && ir < NR) {
17809                if (curt == null) {
17810                    curt = (ResolveInfo)receivers.get(it);
17811                }
17812                if (curr == null) {
17813                    curr = registeredReceivers.get(ir);
17814                }
17815                if (curr.getPriority() >= curt.priority) {
17816                    // Insert this broadcast record into the final list.
17817                    receivers.add(it, curr);
17818                    ir++;
17819                    curr = null;
17820                    it++;
17821                    NT++;
17822                } else {
17823                    // Skip to the next ResolveInfo in the final list.
17824                    it++;
17825                    curt = null;
17826                }
17827            }
17828        }
17829        while (ir < NR) {
17830            if (receivers == null) {
17831                receivers = new ArrayList();
17832            }
17833            receivers.add(registeredReceivers.get(ir));
17834            ir++;
17835        }
17836
17837        if ((receivers != null && receivers.size() > 0)
17838                || resultTo != null) {
17839            BroadcastQueue queue = broadcastQueueForIntent(intent);
17840            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17841                    callerPackage, callingPid, callingUid, resolvedType,
17842                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17843                    resultData, resultExtras, ordered, sticky, false, userId);
17844
17845            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17846                    + ": prev had " + queue.mOrderedBroadcasts.size());
17847            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17848                    "Enqueueing broadcast " + r.intent.getAction());
17849
17850            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17851            if (!replaced) {
17852                queue.enqueueOrderedBroadcastLocked(r);
17853                queue.scheduleBroadcastsLocked();
17854            }
17855        }
17856
17857        return ActivityManager.BROADCAST_SUCCESS;
17858    }
17859
17860    final Intent verifyBroadcastLocked(Intent intent) {
17861        // Refuse possible leaked file descriptors
17862        if (intent != null && intent.hasFileDescriptors() == true) {
17863            throw new IllegalArgumentException("File descriptors passed in Intent");
17864        }
17865
17866        int flags = intent.getFlags();
17867
17868        if (!mProcessesReady) {
17869            // if the caller really truly claims to know what they're doing, go
17870            // ahead and allow the broadcast without launching any receivers
17871            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17872                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17873            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17874                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17875                        + " before boot completion");
17876                throw new IllegalStateException("Cannot broadcast before boot completed");
17877            }
17878        }
17879
17880        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17881            throw new IllegalArgumentException(
17882                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17883        }
17884
17885        return intent;
17886    }
17887
17888    public final int broadcastIntent(IApplicationThread caller,
17889            Intent intent, String resolvedType, IIntentReceiver resultTo,
17890            int resultCode, String resultData, Bundle resultExtras,
17891            String[] requiredPermissions, int appOp, Bundle bOptions,
17892            boolean serialized, boolean sticky, int userId) {
17893        enforceNotIsolatedCaller("broadcastIntent");
17894        synchronized(this) {
17895            intent = verifyBroadcastLocked(intent);
17896
17897            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17898            final int callingPid = Binder.getCallingPid();
17899            final int callingUid = Binder.getCallingUid();
17900            final long origId = Binder.clearCallingIdentity();
17901            int res = broadcastIntentLocked(callerApp,
17902                    callerApp != null ? callerApp.info.packageName : null,
17903                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17904                    requiredPermissions, appOp, bOptions, serialized, sticky,
17905                    callingPid, callingUid, userId);
17906            Binder.restoreCallingIdentity(origId);
17907            return res;
17908        }
17909    }
17910
17911
17912    int broadcastIntentInPackage(String packageName, int uid,
17913            Intent intent, String resolvedType, IIntentReceiver resultTo,
17914            int resultCode, String resultData, Bundle resultExtras,
17915            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17916            int userId) {
17917        synchronized(this) {
17918            intent = verifyBroadcastLocked(intent);
17919
17920            final long origId = Binder.clearCallingIdentity();
17921            String[] requiredPermissions = requiredPermission == null ? null
17922                    : new String[] {requiredPermission};
17923            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17924                    resultTo, resultCode, resultData, resultExtras,
17925                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17926                    sticky, -1, uid, userId);
17927            Binder.restoreCallingIdentity(origId);
17928            return res;
17929        }
17930    }
17931
17932    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17933        // Refuse possible leaked file descriptors
17934        if (intent != null && intent.hasFileDescriptors() == true) {
17935            throw new IllegalArgumentException("File descriptors passed in Intent");
17936        }
17937
17938        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17939                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17940
17941        synchronized(this) {
17942            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17943                    != PackageManager.PERMISSION_GRANTED) {
17944                String msg = "Permission Denial: unbroadcastIntent() from pid="
17945                        + Binder.getCallingPid()
17946                        + ", uid=" + Binder.getCallingUid()
17947                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17948                Slog.w(TAG, msg);
17949                throw new SecurityException(msg);
17950            }
17951            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17952            if (stickies != null) {
17953                ArrayList<Intent> list = stickies.get(intent.getAction());
17954                if (list != null) {
17955                    int N = list.size();
17956                    int i;
17957                    for (i=0; i<N; i++) {
17958                        if (intent.filterEquals(list.get(i))) {
17959                            list.remove(i);
17960                            break;
17961                        }
17962                    }
17963                    if (list.size() <= 0) {
17964                        stickies.remove(intent.getAction());
17965                    }
17966                }
17967                if (stickies.size() <= 0) {
17968                    mStickyBroadcasts.remove(userId);
17969                }
17970            }
17971        }
17972    }
17973
17974    void backgroundServicesFinishedLocked(int userId) {
17975        for (BroadcastQueue queue : mBroadcastQueues) {
17976            queue.backgroundServicesFinishedLocked(userId);
17977        }
17978    }
17979
17980    public void finishReceiver(IBinder who, int resultCode, String resultData,
17981            Bundle resultExtras, boolean resultAbort, int flags) {
17982        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17983
17984        // Refuse possible leaked file descriptors
17985        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17986            throw new IllegalArgumentException("File descriptors passed in Bundle");
17987        }
17988
17989        final long origId = Binder.clearCallingIdentity();
17990        try {
17991            boolean doNext = false;
17992            BroadcastRecord r;
17993
17994            synchronized(this) {
17995                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17996                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17997                r = queue.getMatchingOrderedReceiver(who);
17998                if (r != null) {
17999                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18000                        resultData, resultExtras, resultAbort, true);
18001                }
18002            }
18003
18004            if (doNext) {
18005                r.queue.processNextBroadcast(false);
18006            }
18007            trimApplications();
18008        } finally {
18009            Binder.restoreCallingIdentity(origId);
18010        }
18011    }
18012
18013    // =========================================================
18014    // INSTRUMENTATION
18015    // =========================================================
18016
18017    public boolean startInstrumentation(ComponentName className,
18018            String profileFile, int flags, Bundle arguments,
18019            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18020            int userId, String abiOverride) {
18021        enforceNotIsolatedCaller("startInstrumentation");
18022        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18023                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18024        // Refuse possible leaked file descriptors
18025        if (arguments != null && arguments.hasFileDescriptors()) {
18026            throw new IllegalArgumentException("File descriptors passed in Bundle");
18027        }
18028
18029        synchronized(this) {
18030            InstrumentationInfo ii = null;
18031            ApplicationInfo ai = null;
18032            try {
18033                ii = mContext.getPackageManager().getInstrumentationInfo(
18034                    className, STOCK_PM_FLAGS);
18035                ai = AppGlobals.getPackageManager().getApplicationInfo(
18036                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18037            } catch (PackageManager.NameNotFoundException e) {
18038            } catch (RemoteException e) {
18039            }
18040            if (ii == null) {
18041                reportStartInstrumentationFailureLocked(watcher, className,
18042                        "Unable to find instrumentation info for: " + className);
18043                return false;
18044            }
18045            if (ai == null) {
18046                reportStartInstrumentationFailureLocked(watcher, className,
18047                        "Unable to find instrumentation target package: " + ii.targetPackage);
18048                return false;
18049            }
18050            if (!ai.hasCode()) {
18051                reportStartInstrumentationFailureLocked(watcher, className,
18052                        "Instrumentation target has no code: " + ii.targetPackage);
18053                return false;
18054            }
18055
18056            int match = mContext.getPackageManager().checkSignatures(
18057                    ii.targetPackage, ii.packageName);
18058            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18059                String msg = "Permission Denial: starting instrumentation "
18060                        + className + " from pid="
18061                        + Binder.getCallingPid()
18062                        + ", uid=" + Binder.getCallingPid()
18063                        + " not allowed because package " + ii.packageName
18064                        + " does not have a signature matching the target "
18065                        + ii.targetPackage;
18066                reportStartInstrumentationFailureLocked(watcher, className, msg);
18067                throw new SecurityException(msg);
18068            }
18069
18070            final long origId = Binder.clearCallingIdentity();
18071            // Instrumentation can kill and relaunch even persistent processes
18072            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18073                    "start instr");
18074            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18075            app.instrumentationClass = className;
18076            app.instrumentationInfo = ai;
18077            app.instrumentationProfileFile = profileFile;
18078            app.instrumentationArguments = arguments;
18079            app.instrumentationWatcher = watcher;
18080            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18081            app.instrumentationResultClass = className;
18082            Binder.restoreCallingIdentity(origId);
18083        }
18084
18085        return true;
18086    }
18087
18088    /**
18089     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18090     * error to the logs, but if somebody is watching, send the report there too.  This enables
18091     * the "am" command to report errors with more information.
18092     *
18093     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18094     * @param cn The component name of the instrumentation.
18095     * @param report The error report.
18096     */
18097    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18098            ComponentName cn, String report) {
18099        Slog.w(TAG, report);
18100        if (watcher != null) {
18101            Bundle results = new Bundle();
18102            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18103            results.putString("Error", report);
18104            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18105        }
18106    }
18107
18108    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18109        if (app.instrumentationWatcher != null) {
18110            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18111                    app.instrumentationClass, resultCode, results);
18112        }
18113
18114        // Can't call out of the system process with a lock held, so post a message.
18115        if (app.instrumentationUiAutomationConnection != null) {
18116            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18117                    app.instrumentationUiAutomationConnection).sendToTarget();
18118        }
18119
18120        app.instrumentationWatcher = null;
18121        app.instrumentationUiAutomationConnection = null;
18122        app.instrumentationClass = null;
18123        app.instrumentationInfo = null;
18124        app.instrumentationProfileFile = null;
18125        app.instrumentationArguments = null;
18126
18127        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18128                "finished inst");
18129    }
18130
18131    public void finishInstrumentation(IApplicationThread target,
18132            int resultCode, Bundle results) {
18133        int userId = UserHandle.getCallingUserId();
18134        // Refuse possible leaked file descriptors
18135        if (results != null && results.hasFileDescriptors()) {
18136            throw new IllegalArgumentException("File descriptors passed in Intent");
18137        }
18138
18139        synchronized(this) {
18140            ProcessRecord app = getRecordForAppLocked(target);
18141            if (app == null) {
18142                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18143                return;
18144            }
18145            final long origId = Binder.clearCallingIdentity();
18146            finishInstrumentationLocked(app, resultCode, results);
18147            Binder.restoreCallingIdentity(origId);
18148        }
18149    }
18150
18151    // =========================================================
18152    // CONFIGURATION
18153    // =========================================================
18154
18155    public ConfigurationInfo getDeviceConfigurationInfo() {
18156        ConfigurationInfo config = new ConfigurationInfo();
18157        synchronized (this) {
18158            config.reqTouchScreen = mConfiguration.touchscreen;
18159            config.reqKeyboardType = mConfiguration.keyboard;
18160            config.reqNavigation = mConfiguration.navigation;
18161            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18162                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18163                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18164            }
18165            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18166                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18167                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18168            }
18169            config.reqGlEsVersion = GL_ES_VERSION;
18170        }
18171        return config;
18172    }
18173
18174    ActivityStack getFocusedStack() {
18175        return mStackSupervisor.getFocusedStack();
18176    }
18177
18178    @Override
18179    public int getFocusedStackId() throws RemoteException {
18180        ActivityStack focusedStack = getFocusedStack();
18181        if (focusedStack != null) {
18182            return focusedStack.getStackId();
18183        }
18184        return -1;
18185    }
18186
18187    public Configuration getConfiguration() {
18188        Configuration ci;
18189        synchronized(this) {
18190            ci = new Configuration(mConfiguration);
18191            ci.userSetLocale = false;
18192        }
18193        return ci;
18194    }
18195
18196    @Override
18197    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18198        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18199        synchronized (this) {
18200            mSuppressResizeConfigChanges = suppress;
18201        }
18202    }
18203
18204    @Override
18205    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18206        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18207        if (fromStackId == HOME_STACK_ID) {
18208            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18209        }
18210        synchronized (this) {
18211            final long origId = Binder.clearCallingIdentity();
18212            try {
18213                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18214            } finally {
18215                Binder.restoreCallingIdentity(origId);
18216            }
18217        }
18218    }
18219
18220    @Override
18221    public void updatePersistentConfiguration(Configuration values) {
18222        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18223                "updateConfiguration()");
18224        enforceWriteSettingsPermission("updateConfiguration()");
18225        if (values == null) {
18226            throw new NullPointerException("Configuration must not be null");
18227        }
18228
18229        int userId = UserHandle.getCallingUserId();
18230
18231        synchronized(this) {
18232            final long origId = Binder.clearCallingIdentity();
18233            updateConfigurationLocked(values, null, false, true, userId);
18234            Binder.restoreCallingIdentity(origId);
18235        }
18236    }
18237
18238    private void updateFontScaleIfNeeded() {
18239        final int currentUserId;
18240        synchronized(this) {
18241            currentUserId = mUserController.getCurrentUserIdLocked();
18242        }
18243        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18244                FONT_SCALE, 1.0f, currentUserId);
18245        if (mConfiguration.fontScale != scaleFactor) {
18246            final Configuration configuration = mWindowManager.computeNewConfiguration();
18247            configuration.fontScale = scaleFactor;
18248            updatePersistentConfiguration(configuration);
18249        }
18250    }
18251
18252    private void enforceWriteSettingsPermission(String func) {
18253        int uid = Binder.getCallingUid();
18254        if (uid == Process.ROOT_UID) {
18255            return;
18256        }
18257
18258        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18259                Settings.getPackageNameForUid(mContext, uid), false)) {
18260            return;
18261        }
18262
18263        String msg = "Permission Denial: " + func + " from pid="
18264                + Binder.getCallingPid()
18265                + ", uid=" + uid
18266                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18267        Slog.w(TAG, msg);
18268        throw new SecurityException(msg);
18269    }
18270
18271    public void updateConfiguration(Configuration values) {
18272        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18273                "updateConfiguration()");
18274
18275        synchronized(this) {
18276            if (values == null && mWindowManager != null) {
18277                // sentinel: fetch the current configuration from the window manager
18278                values = mWindowManager.computeNewConfiguration();
18279            }
18280
18281            if (mWindowManager != null) {
18282                mProcessList.applyDisplaySize(mWindowManager);
18283            }
18284
18285            final long origId = Binder.clearCallingIdentity();
18286            if (values != null) {
18287                Settings.System.clearConfiguration(values);
18288            }
18289            updateConfigurationLocked(values, null, false);
18290            Binder.restoreCallingIdentity(origId);
18291        }
18292    }
18293
18294    void updateUserConfigurationLocked() {
18295        Configuration configuration = new Configuration(mConfiguration);
18296        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18297                mUserController.getCurrentUserIdLocked());
18298        updateConfigurationLocked(configuration, null, false);
18299    }
18300
18301    boolean updateConfigurationLocked(Configuration values,
18302            ActivityRecord starting, boolean initLocale) {
18303        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18304        return updateConfigurationLocked(values, starting, initLocale, false,
18305                UserHandle.USER_NULL);
18306    }
18307
18308    // To cache the list of supported system locales
18309    private String[] mSupportedSystemLocales = null;
18310
18311    /**
18312     * Do either or both things: (1) change the current configuration, and (2)
18313     * make sure the given activity is running with the (now) current
18314     * configuration.  Returns true if the activity has been left running, or
18315     * false if <var>starting</var> is being destroyed to match the new
18316     * configuration.
18317     *
18318     * @param userId is only used when persistent parameter is set to true to persist configuration
18319     *               for that particular user
18320     */
18321    private boolean updateConfigurationLocked(Configuration values,
18322            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18323        int changes = 0;
18324
18325        if (mWindowManager != null) {
18326            mWindowManager.deferSurfaceLayout();
18327        }
18328        if (values != null) {
18329            Configuration newConfig = new Configuration(mConfiguration);
18330            changes = newConfig.updateFrom(values);
18331            if (changes != 0) {
18332                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18333                        "Updating configuration to: " + values);
18334
18335                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18336
18337                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18338                    final Locale locale;
18339                    if (values.getLocales().size() == 1) {
18340                        // This is an optimization to avoid the JNI call when the result of
18341                        // getFirstMatch() does not depend on the supported locales.
18342                        locale = values.getLocales().get(0);
18343                    } else {
18344                        if (mSupportedSystemLocales == null) {
18345                            mSupportedSystemLocales =
18346                                    Resources.getSystem().getAssets().getLocales();
18347                        }
18348                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18349                    }
18350                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18351                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18352                            locale));
18353                }
18354
18355                mConfigurationSeq++;
18356                if (mConfigurationSeq <= 0) {
18357                    mConfigurationSeq = 1;
18358                }
18359                newConfig.seq = mConfigurationSeq;
18360                mConfiguration = newConfig;
18361                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18362                mUsageStatsService.reportConfigurationChange(newConfig,
18363                        mUserController.getCurrentUserIdLocked());
18364                //mUsageStatsService.noteStartConfig(newConfig);
18365
18366                final Configuration configCopy = new Configuration(mConfiguration);
18367
18368                // TODO: If our config changes, should we auto dismiss any currently
18369                // showing dialogs?
18370                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18371
18372                AttributeCache ac = AttributeCache.instance();
18373                if (ac != null) {
18374                    ac.updateConfiguration(configCopy);
18375                }
18376
18377                // Make sure all resources in our process are updated
18378                // right now, so that anyone who is going to retrieve
18379                // resource values after we return will be sure to get
18380                // the new ones.  This is especially important during
18381                // boot, where the first config change needs to guarantee
18382                // all resources have that config before following boot
18383                // code is executed.
18384                mSystemThread.applyConfigurationToResources(configCopy);
18385
18386                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18387                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18388                    msg.obj = new Configuration(configCopy);
18389                    msg.arg1 = userId;
18390                    mHandler.sendMessage(msg);
18391                }
18392
18393                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18394                if (isDensityChange) {
18395                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18396                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18397                }
18398
18399                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18400                    ProcessRecord app = mLruProcesses.get(i);
18401                    try {
18402                        if (app.thread != null) {
18403                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18404                                    + app.processName + " new config " + mConfiguration);
18405                            app.thread.scheduleConfigurationChanged(configCopy);
18406                        }
18407                    } catch (Exception e) {
18408                    }
18409                }
18410                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18411                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18412                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18413                        | Intent.FLAG_RECEIVER_FOREGROUND);
18414                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18415                        null, AppOpsManager.OP_NONE, null, false, false,
18416                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18417                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18418                    // Tell the shortcut manager that the system locale changed.  It needs to know
18419                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18420                    // we "push" from here, rather than having the service listen to the broadcast.
18421                    final ShortcutServiceInternal shortcutService =
18422                            LocalServices.getService(ShortcutServiceInternal.class);
18423                    if (shortcutService != null) {
18424                        shortcutService.onSystemLocaleChangedNoLock();
18425                    }
18426
18427                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18428                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18429                    if (!mProcessesReady) {
18430                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18431                    }
18432                    broadcastIntentLocked(null, null, intent,
18433                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18434                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18435                }
18436            }
18437            // Update the configuration with WM first and check if any of the stacks need to be
18438            // resized due to the configuration change. If so, resize the stacks now and do any
18439            // relaunches if necessary. This way we don't need to relaunch again below in
18440            // ensureActivityConfigurationLocked().
18441            if (mWindowManager != null) {
18442                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18443                if (resizedStacks != null) {
18444                    for (int stackId : resizedStacks) {
18445                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18446                        mStackSupervisor.resizeStackLocked(
18447                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18448                    }
18449                }
18450            }
18451        }
18452
18453        boolean kept = true;
18454        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18455        // mainStack is null during startup.
18456        if (mainStack != null) {
18457            if (changes != 0 && starting == null) {
18458                // If the configuration changed, and the caller is not already
18459                // in the process of starting an activity, then find the top
18460                // activity to check if its configuration needs to change.
18461                starting = mainStack.topRunningActivityLocked();
18462            }
18463
18464            if (starting != null) {
18465                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18466                // And we need to make sure at this point that all other activities
18467                // are made visible with the correct configuration.
18468                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18469                        !PRESERVE_WINDOWS);
18470            }
18471        }
18472        if (mWindowManager != null) {
18473            mWindowManager.continueSurfaceLayout();
18474        }
18475        return kept;
18476    }
18477
18478    /**
18479     * Decide based on the configuration whether we should shouw the ANR,
18480     * crash, etc dialogs.  The idea is that if there is no affordnace to
18481     * press the on-screen buttons, we shouldn't show the dialog.
18482     *
18483     * A thought: SystemUI might also want to get told about this, the Power
18484     * dialog / global actions also might want different behaviors.
18485     */
18486    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18487        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18488                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18489                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18490        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18491                                    == Configuration.UI_MODE_TYPE_CAR);
18492        return inputMethodExists && uiIsNotCarType && !inVrMode;
18493    }
18494
18495    @Override
18496    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18497        synchronized (this) {
18498            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18499            if (srec != null) {
18500                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18501            }
18502        }
18503        return false;
18504    }
18505
18506    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18507            Intent resultData) {
18508
18509        synchronized (this) {
18510            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18511            if (r != null) {
18512                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18513            }
18514            return false;
18515        }
18516    }
18517
18518    public int getLaunchedFromUid(IBinder activityToken) {
18519        ActivityRecord srec;
18520        synchronized (this) {
18521            srec = ActivityRecord.forTokenLocked(activityToken);
18522        }
18523        if (srec == null) {
18524            return -1;
18525        }
18526        return srec.launchedFromUid;
18527    }
18528
18529    public String getLaunchedFromPackage(IBinder activityToken) {
18530        ActivityRecord srec;
18531        synchronized (this) {
18532            srec = ActivityRecord.forTokenLocked(activityToken);
18533        }
18534        if (srec == null) {
18535            return null;
18536        }
18537        return srec.launchedFromPackage;
18538    }
18539
18540    // =========================================================
18541    // LIFETIME MANAGEMENT
18542    // =========================================================
18543
18544    // Returns which broadcast queue the app is the current [or imminent] receiver
18545    // on, or 'null' if the app is not an active broadcast recipient.
18546    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18547        BroadcastRecord r = app.curReceiver;
18548        if (r != null) {
18549            return r.queue;
18550        }
18551
18552        // It's not the current receiver, but it might be starting up to become one
18553        synchronized (this) {
18554            for (BroadcastQueue queue : mBroadcastQueues) {
18555                r = queue.mPendingBroadcast;
18556                if (r != null && r.curApp == app) {
18557                    // found it; report which queue it's in
18558                    return queue;
18559                }
18560            }
18561        }
18562
18563        return null;
18564    }
18565
18566    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18567            int targetUid, ComponentName targetComponent, String targetProcess) {
18568        if (!mTrackingAssociations) {
18569            return null;
18570        }
18571        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18572                = mAssociations.get(targetUid);
18573        if (components == null) {
18574            components = new ArrayMap<>();
18575            mAssociations.put(targetUid, components);
18576        }
18577        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18578        if (sourceUids == null) {
18579            sourceUids = new SparseArray<>();
18580            components.put(targetComponent, sourceUids);
18581        }
18582        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18583        if (sourceProcesses == null) {
18584            sourceProcesses = new ArrayMap<>();
18585            sourceUids.put(sourceUid, sourceProcesses);
18586        }
18587        Association ass = sourceProcesses.get(sourceProcess);
18588        if (ass == null) {
18589            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18590                    targetProcess);
18591            sourceProcesses.put(sourceProcess, ass);
18592        }
18593        ass.mCount++;
18594        ass.mNesting++;
18595        if (ass.mNesting == 1) {
18596            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18597            ass.mLastState = sourceState;
18598        }
18599        return ass;
18600    }
18601
18602    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18603            ComponentName targetComponent) {
18604        if (!mTrackingAssociations) {
18605            return;
18606        }
18607        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18608                = mAssociations.get(targetUid);
18609        if (components == null) {
18610            return;
18611        }
18612        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18613        if (sourceUids == null) {
18614            return;
18615        }
18616        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18617        if (sourceProcesses == null) {
18618            return;
18619        }
18620        Association ass = sourceProcesses.get(sourceProcess);
18621        if (ass == null || ass.mNesting <= 0) {
18622            return;
18623        }
18624        ass.mNesting--;
18625        if (ass.mNesting == 0) {
18626            long uptime = SystemClock.uptimeMillis();
18627            ass.mTime += uptime - ass.mStartTime;
18628            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18629                    += uptime - ass.mLastStateUptime;
18630            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18631        }
18632    }
18633
18634    private void noteUidProcessState(final int uid, final int state) {
18635        mBatteryStatsService.noteUidProcessState(uid, state);
18636        if (mTrackingAssociations) {
18637            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18638                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18639                        = mAssociations.valueAt(i1);
18640                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18641                    SparseArray<ArrayMap<String, Association>> sourceUids
18642                            = targetComponents.valueAt(i2);
18643                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18644                    if (sourceProcesses != null) {
18645                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18646                            Association ass = sourceProcesses.valueAt(i4);
18647                            if (ass.mNesting >= 1) {
18648                                // currently associated
18649                                long uptime = SystemClock.uptimeMillis();
18650                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18651                                        += uptime - ass.mLastStateUptime;
18652                                ass.mLastState = state;
18653                                ass.mLastStateUptime = uptime;
18654                            }
18655                        }
18656                    }
18657                }
18658            }
18659        }
18660    }
18661
18662    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18663            boolean doingAll, long now) {
18664        if (mAdjSeq == app.adjSeq) {
18665            // This adjustment has already been computed.
18666            return app.curRawAdj;
18667        }
18668
18669        if (app.thread == null) {
18670            app.adjSeq = mAdjSeq;
18671            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18672            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18673            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18674        }
18675
18676        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18677        app.adjSource = null;
18678        app.adjTarget = null;
18679        app.empty = false;
18680        app.cached = false;
18681
18682        final int activitiesSize = app.activities.size();
18683
18684        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18685            // The max adjustment doesn't allow this app to be anything
18686            // below foreground, so it is not worth doing work for it.
18687            app.adjType = "fixed";
18688            app.adjSeq = mAdjSeq;
18689            app.curRawAdj = app.maxAdj;
18690            app.foregroundActivities = false;
18691            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18692            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18693            // System processes can do UI, and when they do we want to have
18694            // them trim their memory after the user leaves the UI.  To
18695            // facilitate this, here we need to determine whether or not it
18696            // is currently showing UI.
18697            app.systemNoUi = true;
18698            if (app == TOP_APP) {
18699                app.systemNoUi = false;
18700                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18701                app.adjType = "pers-top-activity";
18702            } else if (activitiesSize > 0) {
18703                for (int j = 0; j < activitiesSize; j++) {
18704                    final ActivityRecord r = app.activities.get(j);
18705                    if (r.visible) {
18706                        app.systemNoUi = false;
18707                    }
18708                }
18709            }
18710            if (!app.systemNoUi) {
18711                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18712            }
18713            return (app.curAdj=app.maxAdj);
18714        }
18715
18716        app.systemNoUi = false;
18717
18718        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18719
18720        // Determine the importance of the process, starting with most
18721        // important to least, and assign an appropriate OOM adjustment.
18722        int adj;
18723        int schedGroup;
18724        int procState;
18725        boolean foregroundActivities = false;
18726        BroadcastQueue queue;
18727        if (app == TOP_APP) {
18728            // The last app on the list is the foreground app.
18729            adj = ProcessList.FOREGROUND_APP_ADJ;
18730            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18731            app.adjType = "top-activity";
18732            foregroundActivities = true;
18733            procState = PROCESS_STATE_CUR_TOP;
18734        } else if (app.instrumentationClass != null) {
18735            // Don't want to kill running instrumentation.
18736            adj = ProcessList.FOREGROUND_APP_ADJ;
18737            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18738            app.adjType = "instrumentation";
18739            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18740        } else if ((queue = isReceivingBroadcast(app)) != null) {
18741            // An app that is currently receiving a broadcast also
18742            // counts as being in the foreground for OOM killer purposes.
18743            // It's placed in a sched group based on the nature of the
18744            // broadcast as reflected by which queue it's active in.
18745            adj = ProcessList.FOREGROUND_APP_ADJ;
18746            schedGroup = (queue == mFgBroadcastQueue)
18747                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18748            app.adjType = "broadcast";
18749            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18750        } else if (app.executingServices.size() > 0) {
18751            // An app that is currently executing a service callback also
18752            // counts as being in the foreground.
18753            adj = ProcessList.FOREGROUND_APP_ADJ;
18754            schedGroup = app.execServicesFg ?
18755                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18756            app.adjType = "exec-service";
18757            procState = ActivityManager.PROCESS_STATE_SERVICE;
18758            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18759        } else {
18760            // As far as we know the process is empty.  We may change our mind later.
18761            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18762            // At this point we don't actually know the adjustment.  Use the cached adj
18763            // value that the caller wants us to.
18764            adj = cachedAdj;
18765            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18766            app.cached = true;
18767            app.empty = true;
18768            app.adjType = "cch-empty";
18769        }
18770
18771        // Examine all activities if not already foreground.
18772        if (!foregroundActivities && activitiesSize > 0) {
18773            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18774            for (int j = 0; j < activitiesSize; j++) {
18775                final ActivityRecord r = app.activities.get(j);
18776                if (r.app != app) {
18777                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18778                            + " instead of expected " + app);
18779                    if (r.app == null || (r.app.uid == app.uid)) {
18780                        // Only fix things up when they look sane
18781                        r.app = app;
18782                    } else {
18783                        continue;
18784                    }
18785                }
18786                if (r.visible) {
18787                    // App has a visible activity; only upgrade adjustment.
18788                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18789                        adj = ProcessList.VISIBLE_APP_ADJ;
18790                        app.adjType = "visible";
18791                    }
18792                    if (procState > PROCESS_STATE_CUR_TOP) {
18793                        procState = PROCESS_STATE_CUR_TOP;
18794                    }
18795                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18796                    app.cached = false;
18797                    app.empty = false;
18798                    foregroundActivities = true;
18799                    if (r.task != null && minLayer > 0) {
18800                        final int layer = r.task.mLayerRank;
18801                        if (layer >= 0 && minLayer > layer) {
18802                            minLayer = layer;
18803                        }
18804                    }
18805                    break;
18806                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18807                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18808                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18809                        app.adjType = "pausing";
18810                    }
18811                    if (procState > PROCESS_STATE_CUR_TOP) {
18812                        procState = PROCESS_STATE_CUR_TOP;
18813                    }
18814                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18815                    app.cached = false;
18816                    app.empty = false;
18817                    foregroundActivities = true;
18818                } else if (r.state == ActivityState.STOPPING) {
18819                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18820                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18821                        app.adjType = "stopping";
18822                    }
18823                    // For the process state, we will at this point consider the
18824                    // process to be cached.  It will be cached either as an activity
18825                    // or empty depending on whether the activity is finishing.  We do
18826                    // this so that we can treat the process as cached for purposes of
18827                    // memory trimming (determing current memory level, trim command to
18828                    // send to process) since there can be an arbitrary number of stopping
18829                    // processes and they should soon all go into the cached state.
18830                    if (!r.finishing) {
18831                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18832                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18833                        }
18834                    }
18835                    app.cached = false;
18836                    app.empty = false;
18837                    foregroundActivities = true;
18838                } else {
18839                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18840                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18841                        app.adjType = "cch-act";
18842                    }
18843                }
18844            }
18845            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18846                adj += minLayer;
18847            }
18848        }
18849
18850        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18851                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18852            if (app.foregroundServices) {
18853                // The user is aware of this app, so make it visible.
18854                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18855                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18856                app.cached = false;
18857                app.adjType = "fg-service";
18858                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18859            } else if (app.forcingToForeground != null) {
18860                // The user is aware of this app, so make it visible.
18861                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18862                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18863                app.cached = false;
18864                app.adjType = "force-fg";
18865                app.adjSource = app.forcingToForeground;
18866                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18867            }
18868        }
18869
18870        if (app == mHeavyWeightProcess) {
18871            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18872                // We don't want to kill the current heavy-weight process.
18873                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18874                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18875                app.cached = false;
18876                app.adjType = "heavy";
18877            }
18878            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18879                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18880            }
18881        }
18882
18883        if (app == mHomeProcess) {
18884            if (adj > ProcessList.HOME_APP_ADJ) {
18885                // This process is hosting what we currently consider to be the
18886                // home app, so we don't want to let it go into the background.
18887                adj = ProcessList.HOME_APP_ADJ;
18888                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18889                app.cached = false;
18890                app.adjType = "home";
18891            }
18892            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18893                procState = ActivityManager.PROCESS_STATE_HOME;
18894            }
18895        }
18896
18897        if (app == mPreviousProcess && app.activities.size() > 0) {
18898            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18899                // This was the previous process that showed UI to the user.
18900                // We want to try to keep it around more aggressively, to give
18901                // a good experience around switching between two apps.
18902                adj = ProcessList.PREVIOUS_APP_ADJ;
18903                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18904                app.cached = false;
18905                app.adjType = "previous";
18906            }
18907            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18908                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18909            }
18910        }
18911
18912        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18913                + " reason=" + app.adjType);
18914
18915        // By default, we use the computed adjustment.  It may be changed if
18916        // there are applications dependent on our services or providers, but
18917        // this gives us a baseline and makes sure we don't get into an
18918        // infinite recursion.
18919        app.adjSeq = mAdjSeq;
18920        app.curRawAdj = adj;
18921        app.hasStartedServices = false;
18922
18923        if (mBackupTarget != null && app == mBackupTarget.app) {
18924            // If possible we want to avoid killing apps while they're being backed up
18925            if (adj > ProcessList.BACKUP_APP_ADJ) {
18926                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18927                adj = ProcessList.BACKUP_APP_ADJ;
18928                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18929                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18930                }
18931                app.adjType = "backup";
18932                app.cached = false;
18933            }
18934            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18935                procState = ActivityManager.PROCESS_STATE_BACKUP;
18936            }
18937        }
18938
18939        boolean mayBeTop = false;
18940
18941        for (int is = app.services.size()-1;
18942                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18943                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18944                        || procState > ActivityManager.PROCESS_STATE_TOP);
18945                is--) {
18946            ServiceRecord s = app.services.valueAt(is);
18947            if (s.startRequested) {
18948                app.hasStartedServices = true;
18949                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18950                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18951                }
18952                if (app.hasShownUi && app != mHomeProcess) {
18953                    // If this process has shown some UI, let it immediately
18954                    // go to the LRU list because it may be pretty heavy with
18955                    // UI stuff.  We'll tag it with a label just to help
18956                    // debug and understand what is going on.
18957                    if (adj > ProcessList.SERVICE_ADJ) {
18958                        app.adjType = "cch-started-ui-services";
18959                    }
18960                } else {
18961                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18962                        // This service has seen some activity within
18963                        // recent memory, so we will keep its process ahead
18964                        // of the background processes.
18965                        if (adj > ProcessList.SERVICE_ADJ) {
18966                            adj = ProcessList.SERVICE_ADJ;
18967                            app.adjType = "started-services";
18968                            app.cached = false;
18969                        }
18970                    }
18971                    // If we have let the service slide into the background
18972                    // state, still have some text describing what it is doing
18973                    // even though the service no longer has an impact.
18974                    if (adj > ProcessList.SERVICE_ADJ) {
18975                        app.adjType = "cch-started-services";
18976                    }
18977                }
18978            }
18979            for (int conni = s.connections.size()-1;
18980                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18981                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18982                            || procState > ActivityManager.PROCESS_STATE_TOP);
18983                    conni--) {
18984                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18985                for (int i = 0;
18986                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18987                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18988                                || procState > ActivityManager.PROCESS_STATE_TOP);
18989                        i++) {
18990                    // XXX should compute this based on the max of
18991                    // all connected clients.
18992                    ConnectionRecord cr = clist.get(i);
18993                    if (cr.binding.client == app) {
18994                        // Binding to ourself is not interesting.
18995                        continue;
18996                    }
18997                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18998                        ProcessRecord client = cr.binding.client;
18999                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19000                                TOP_APP, doingAll, now);
19001                        int clientProcState = client.curProcState;
19002                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19003                            // If the other app is cached for any reason, for purposes here
19004                            // we are going to consider it empty.  The specific cached state
19005                            // doesn't propagate except under certain conditions.
19006                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19007                        }
19008                        String adjType = null;
19009                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19010                            // Not doing bind OOM management, so treat
19011                            // this guy more like a started service.
19012                            if (app.hasShownUi && app != mHomeProcess) {
19013                                // If this process has shown some UI, let it immediately
19014                                // go to the LRU list because it may be pretty heavy with
19015                                // UI stuff.  We'll tag it with a label just to help
19016                                // debug and understand what is going on.
19017                                if (adj > clientAdj) {
19018                                    adjType = "cch-bound-ui-services";
19019                                }
19020                                app.cached = false;
19021                                clientAdj = adj;
19022                                clientProcState = procState;
19023                            } else {
19024                                if (now >= (s.lastActivity
19025                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19026                                    // This service has not seen activity within
19027                                    // recent memory, so allow it to drop to the
19028                                    // LRU list if there is no other reason to keep
19029                                    // it around.  We'll also tag it with a label just
19030                                    // to help debug and undertand what is going on.
19031                                    if (adj > clientAdj) {
19032                                        adjType = "cch-bound-services";
19033                                    }
19034                                    clientAdj = adj;
19035                                }
19036                            }
19037                        }
19038                        if (adj > clientAdj) {
19039                            // If this process has recently shown UI, and
19040                            // the process that is binding to it is less
19041                            // important than being visible, then we don't
19042                            // care about the binding as much as we care
19043                            // about letting this process get into the LRU
19044                            // list to be killed and restarted if needed for
19045                            // memory.
19046                            if (app.hasShownUi && app != mHomeProcess
19047                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19048                                adjType = "cch-bound-ui-services";
19049                            } else {
19050                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19051                                        |Context.BIND_IMPORTANT)) != 0) {
19052                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19053                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19054                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19055                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19056                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19057                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19058                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19059                                    adj = clientAdj;
19060                                } else {
19061                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19062                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19063                                    }
19064                                }
19065                                if (!client.cached) {
19066                                    app.cached = false;
19067                                }
19068                                adjType = "service";
19069                            }
19070                        }
19071                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19072                            // This will treat important bound services identically to
19073                            // the top app, which may behave differently than generic
19074                            // foreground work.
19075                            if (client.curSchedGroup > schedGroup) {
19076                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19077                                    schedGroup = client.curSchedGroup;
19078                                } else {
19079                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19080                                }
19081                            }
19082                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19083                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19084                                    // Special handling of clients who are in the top state.
19085                                    // We *may* want to consider this process to be in the
19086                                    // top state as well, but only if there is not another
19087                                    // reason for it to be running.  Being on the top is a
19088                                    // special state, meaning you are specifically running
19089                                    // for the current top app.  If the process is already
19090                                    // running in the background for some other reason, it
19091                                    // is more important to continue considering it to be
19092                                    // in the background state.
19093                                    mayBeTop = true;
19094                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19095                                } else {
19096                                    // Special handling for above-top states (persistent
19097                                    // processes).  These should not bring the current process
19098                                    // into the top state, since they are not on top.  Instead
19099                                    // give them the best state after that.
19100                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19101                                        clientProcState =
19102                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19103                                    } else if (mWakefulness
19104                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19105                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19106                                                    != 0) {
19107                                        clientProcState =
19108                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19109                                    } else {
19110                                        clientProcState =
19111                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19112                                    }
19113                                }
19114                            }
19115                        } else {
19116                            if (clientProcState <
19117                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19118                                clientProcState =
19119                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19120                            }
19121                        }
19122                        if (procState > clientProcState) {
19123                            procState = clientProcState;
19124                        }
19125                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19126                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19127                            app.pendingUiClean = true;
19128                        }
19129                        if (adjType != null) {
19130                            app.adjType = adjType;
19131                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19132                                    .REASON_SERVICE_IN_USE;
19133                            app.adjSource = cr.binding.client;
19134                            app.adjSourceProcState = clientProcState;
19135                            app.adjTarget = s.name;
19136                        }
19137                    }
19138                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19139                        app.treatLikeActivity = true;
19140                    }
19141                    final ActivityRecord a = cr.activity;
19142                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19143                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19144                            (a.visible || a.state == ActivityState.RESUMED ||
19145                             a.state == ActivityState.PAUSING)) {
19146                            adj = ProcessList.FOREGROUND_APP_ADJ;
19147                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19148                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19149                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19150                                } else {
19151                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19152                                }
19153                            }
19154                            app.cached = false;
19155                            app.adjType = "service";
19156                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19157                                    .REASON_SERVICE_IN_USE;
19158                            app.adjSource = a;
19159                            app.adjSourceProcState = procState;
19160                            app.adjTarget = s.name;
19161                        }
19162                    }
19163                }
19164            }
19165        }
19166
19167        for (int provi = app.pubProviders.size()-1;
19168                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19169                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19170                        || procState > ActivityManager.PROCESS_STATE_TOP);
19171                provi--) {
19172            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19173            for (int i = cpr.connections.size()-1;
19174                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19175                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19176                            || procState > ActivityManager.PROCESS_STATE_TOP);
19177                    i--) {
19178                ContentProviderConnection conn = cpr.connections.get(i);
19179                ProcessRecord client = conn.client;
19180                if (client == app) {
19181                    // Being our own client is not interesting.
19182                    continue;
19183                }
19184                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19185                int clientProcState = client.curProcState;
19186                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19187                    // If the other app is cached for any reason, for purposes here
19188                    // we are going to consider it empty.
19189                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19190                }
19191                if (adj > clientAdj) {
19192                    if (app.hasShownUi && app != mHomeProcess
19193                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19194                        app.adjType = "cch-ui-provider";
19195                    } else {
19196                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19197                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19198                        app.adjType = "provider";
19199                    }
19200                    app.cached &= client.cached;
19201                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19202                            .REASON_PROVIDER_IN_USE;
19203                    app.adjSource = client;
19204                    app.adjSourceProcState = clientProcState;
19205                    app.adjTarget = cpr.name;
19206                }
19207                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19208                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19209                        // Special handling of clients who are in the top state.
19210                        // We *may* want to consider this process to be in the
19211                        // top state as well, but only if there is not another
19212                        // reason for it to be running.  Being on the top is a
19213                        // special state, meaning you are specifically running
19214                        // for the current top app.  If the process is already
19215                        // running in the background for some other reason, it
19216                        // is more important to continue considering it to be
19217                        // in the background state.
19218                        mayBeTop = true;
19219                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19220                    } else {
19221                        // Special handling for above-top states (persistent
19222                        // processes).  These should not bring the current process
19223                        // into the top state, since they are not on top.  Instead
19224                        // give them the best state after that.
19225                        clientProcState =
19226                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19227                    }
19228                }
19229                if (procState > clientProcState) {
19230                    procState = clientProcState;
19231                }
19232                if (client.curSchedGroup > schedGroup) {
19233                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19234                }
19235            }
19236            // If the provider has external (non-framework) process
19237            // dependencies, ensure that its adjustment is at least
19238            // FOREGROUND_APP_ADJ.
19239            if (cpr.hasExternalProcessHandles()) {
19240                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19241                    adj = ProcessList.FOREGROUND_APP_ADJ;
19242                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19243                    app.cached = false;
19244                    app.adjType = "provider";
19245                    app.adjTarget = cpr.name;
19246                }
19247                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19248                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19249                }
19250            }
19251        }
19252
19253        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19254            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19255                adj = ProcessList.PREVIOUS_APP_ADJ;
19256                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19257                app.cached = false;
19258                app.adjType = "provider";
19259            }
19260            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19261                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19262            }
19263        }
19264
19265        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19266            // A client of one of our services or providers is in the top state.  We
19267            // *may* want to be in the top state, but not if we are already running in
19268            // the background for some other reason.  For the decision here, we are going
19269            // to pick out a few specific states that we want to remain in when a client
19270            // is top (states that tend to be longer-term) and otherwise allow it to go
19271            // to the top state.
19272            switch (procState) {
19273                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19274                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19275                case ActivityManager.PROCESS_STATE_SERVICE:
19276                    // These all are longer-term states, so pull them up to the top
19277                    // of the background states, but not all the way to the top state.
19278                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19279                    break;
19280                default:
19281                    // Otherwise, top is a better choice, so take it.
19282                    procState = ActivityManager.PROCESS_STATE_TOP;
19283                    break;
19284            }
19285        }
19286
19287        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19288            if (app.hasClientActivities) {
19289                // This is a cached process, but with client activities.  Mark it so.
19290                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19291                app.adjType = "cch-client-act";
19292            } else if (app.treatLikeActivity) {
19293                // This is a cached process, but somebody wants us to treat it like it has
19294                // an activity, okay!
19295                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19296                app.adjType = "cch-as-act";
19297            }
19298        }
19299
19300        if (adj == ProcessList.SERVICE_ADJ) {
19301            if (doingAll) {
19302                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19303                mNewNumServiceProcs++;
19304                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19305                if (!app.serviceb) {
19306                    // This service isn't far enough down on the LRU list to
19307                    // normally be a B service, but if we are low on RAM and it
19308                    // is large we want to force it down since we would prefer to
19309                    // keep launcher over it.
19310                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19311                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19312                        app.serviceHighRam = true;
19313                        app.serviceb = true;
19314                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19315                    } else {
19316                        mNewNumAServiceProcs++;
19317                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19318                    }
19319                } else {
19320                    app.serviceHighRam = false;
19321                }
19322            }
19323            if (app.serviceb) {
19324                adj = ProcessList.SERVICE_B_ADJ;
19325            }
19326        }
19327
19328        app.curRawAdj = adj;
19329
19330        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19331        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19332        if (adj > app.maxAdj) {
19333            adj = app.maxAdj;
19334            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19335                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19336            }
19337        }
19338
19339        // Do final modification to adj.  Everything we do between here and applying
19340        // the final setAdj must be done in this function, because we will also use
19341        // it when computing the final cached adj later.  Note that we don't need to
19342        // worry about this for max adj above, since max adj will always be used to
19343        // keep it out of the cached vaues.
19344        app.curAdj = app.modifyRawOomAdj(adj);
19345        app.curSchedGroup = schedGroup;
19346        app.curProcState = procState;
19347        app.foregroundActivities = foregroundActivities;
19348
19349        return app.curRawAdj;
19350    }
19351
19352    /**
19353     * Record new PSS sample for a process.
19354     */
19355    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19356            long now) {
19357        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19358                swapPss * 1024);
19359        proc.lastPssTime = now;
19360        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19361        if (DEBUG_PSS) Slog.d(TAG_PSS,
19362                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19363                + " state=" + ProcessList.makeProcStateString(procState));
19364        if (proc.initialIdlePss == 0) {
19365            proc.initialIdlePss = pss;
19366        }
19367        proc.lastPss = pss;
19368        proc.lastSwapPss = swapPss;
19369        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19370            proc.lastCachedPss = pss;
19371            proc.lastCachedSwapPss = swapPss;
19372        }
19373
19374        final SparseArray<Pair<Long, String>> watchUids
19375                = mMemWatchProcesses.getMap().get(proc.processName);
19376        Long check = null;
19377        if (watchUids != null) {
19378            Pair<Long, String> val = watchUids.get(proc.uid);
19379            if (val == null) {
19380                val = watchUids.get(0);
19381            }
19382            if (val != null) {
19383                check = val.first;
19384            }
19385        }
19386        if (check != null) {
19387            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19388                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19389                if (!isDebuggable) {
19390                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19391                        isDebuggable = true;
19392                    }
19393                }
19394                if (isDebuggable) {
19395                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19396                    final ProcessRecord myProc = proc;
19397                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19398                    mMemWatchDumpProcName = proc.processName;
19399                    mMemWatchDumpFile = heapdumpFile.toString();
19400                    mMemWatchDumpPid = proc.pid;
19401                    mMemWatchDumpUid = proc.uid;
19402                    BackgroundThread.getHandler().post(new Runnable() {
19403                        @Override
19404                        public void run() {
19405                            revokeUriPermission(ActivityThread.currentActivityThread()
19406                                            .getApplicationThread(),
19407                                    DumpHeapActivity.JAVA_URI,
19408                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19409                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19410                                    UserHandle.myUserId());
19411                            ParcelFileDescriptor fd = null;
19412                            try {
19413                                heapdumpFile.delete();
19414                                fd = ParcelFileDescriptor.open(heapdumpFile,
19415                                        ParcelFileDescriptor.MODE_CREATE |
19416                                                ParcelFileDescriptor.MODE_TRUNCATE |
19417                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19418                                                ParcelFileDescriptor.MODE_APPEND);
19419                                IApplicationThread thread = myProc.thread;
19420                                if (thread != null) {
19421                                    try {
19422                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19423                                                "Requesting dump heap from "
19424                                                + myProc + " to " + heapdumpFile);
19425                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19426                                    } catch (RemoteException e) {
19427                                    }
19428                                }
19429                            } catch (FileNotFoundException e) {
19430                                e.printStackTrace();
19431                            } finally {
19432                                if (fd != null) {
19433                                    try {
19434                                        fd.close();
19435                                    } catch (IOException e) {
19436                                    }
19437                                }
19438                            }
19439                        }
19440                    });
19441                } else {
19442                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19443                            + ", but debugging not enabled");
19444                }
19445            }
19446        }
19447    }
19448
19449    /**
19450     * Schedule PSS collection of a process.
19451     */
19452    void requestPssLocked(ProcessRecord proc, int procState) {
19453        if (mPendingPssProcesses.contains(proc)) {
19454            return;
19455        }
19456        if (mPendingPssProcesses.size() == 0) {
19457            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19458        }
19459        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19460        proc.pssProcState = procState;
19461        mPendingPssProcesses.add(proc);
19462    }
19463
19464    /**
19465     * Schedule PSS collection of all processes.
19466     */
19467    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19468        if (!always) {
19469            if (now < (mLastFullPssTime +
19470                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19471                return;
19472            }
19473        }
19474        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19475        mLastFullPssTime = now;
19476        mFullPssPending = true;
19477        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19478        mPendingPssProcesses.clear();
19479        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19480            ProcessRecord app = mLruProcesses.get(i);
19481            if (app.thread == null
19482                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19483                continue;
19484            }
19485            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19486                app.pssProcState = app.setProcState;
19487                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19488                        mTestPssMode, isSleeping(), now);
19489                mPendingPssProcesses.add(app);
19490            }
19491        }
19492        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19493    }
19494
19495    public void setTestPssMode(boolean enabled) {
19496        synchronized (this) {
19497            mTestPssMode = enabled;
19498            if (enabled) {
19499                // Whenever we enable the mode, we want to take a snapshot all of current
19500                // process mem use.
19501                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19502            }
19503        }
19504    }
19505
19506    /**
19507     * Ask a given process to GC right now.
19508     */
19509    final void performAppGcLocked(ProcessRecord app) {
19510        try {
19511            app.lastRequestedGc = SystemClock.uptimeMillis();
19512            if (app.thread != null) {
19513                if (app.reportLowMemory) {
19514                    app.reportLowMemory = false;
19515                    app.thread.scheduleLowMemory();
19516                } else {
19517                    app.thread.processInBackground();
19518                }
19519            }
19520        } catch (Exception e) {
19521            // whatever.
19522        }
19523    }
19524
19525    /**
19526     * Returns true if things are idle enough to perform GCs.
19527     */
19528    private final boolean canGcNowLocked() {
19529        boolean processingBroadcasts = false;
19530        for (BroadcastQueue q : mBroadcastQueues) {
19531            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19532                processingBroadcasts = true;
19533            }
19534        }
19535        return !processingBroadcasts
19536                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19537    }
19538
19539    /**
19540     * Perform GCs on all processes that are waiting for it, but only
19541     * if things are idle.
19542     */
19543    final void performAppGcsLocked() {
19544        final int N = mProcessesToGc.size();
19545        if (N <= 0) {
19546            return;
19547        }
19548        if (canGcNowLocked()) {
19549            while (mProcessesToGc.size() > 0) {
19550                ProcessRecord proc = mProcessesToGc.remove(0);
19551                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19552                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19553                            <= SystemClock.uptimeMillis()) {
19554                        // To avoid spamming the system, we will GC processes one
19555                        // at a time, waiting a few seconds between each.
19556                        performAppGcLocked(proc);
19557                        scheduleAppGcsLocked();
19558                        return;
19559                    } else {
19560                        // It hasn't been long enough since we last GCed this
19561                        // process...  put it in the list to wait for its time.
19562                        addProcessToGcListLocked(proc);
19563                        break;
19564                    }
19565                }
19566            }
19567
19568            scheduleAppGcsLocked();
19569        }
19570    }
19571
19572    /**
19573     * If all looks good, perform GCs on all processes waiting for them.
19574     */
19575    final void performAppGcsIfAppropriateLocked() {
19576        if (canGcNowLocked()) {
19577            performAppGcsLocked();
19578            return;
19579        }
19580        // Still not idle, wait some more.
19581        scheduleAppGcsLocked();
19582    }
19583
19584    /**
19585     * Schedule the execution of all pending app GCs.
19586     */
19587    final void scheduleAppGcsLocked() {
19588        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19589
19590        if (mProcessesToGc.size() > 0) {
19591            // Schedule a GC for the time to the next process.
19592            ProcessRecord proc = mProcessesToGc.get(0);
19593            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19594
19595            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19596            long now = SystemClock.uptimeMillis();
19597            if (when < (now+GC_TIMEOUT)) {
19598                when = now + GC_TIMEOUT;
19599            }
19600            mHandler.sendMessageAtTime(msg, when);
19601        }
19602    }
19603
19604    /**
19605     * Add a process to the array of processes waiting to be GCed.  Keeps the
19606     * list in sorted order by the last GC time.  The process can't already be
19607     * on the list.
19608     */
19609    final void addProcessToGcListLocked(ProcessRecord proc) {
19610        boolean added = false;
19611        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19612            if (mProcessesToGc.get(i).lastRequestedGc <
19613                    proc.lastRequestedGc) {
19614                added = true;
19615                mProcessesToGc.add(i+1, proc);
19616                break;
19617            }
19618        }
19619        if (!added) {
19620            mProcessesToGc.add(0, proc);
19621        }
19622    }
19623
19624    /**
19625     * Set up to ask a process to GC itself.  This will either do it
19626     * immediately, or put it on the list of processes to gc the next
19627     * time things are idle.
19628     */
19629    final void scheduleAppGcLocked(ProcessRecord app) {
19630        long now = SystemClock.uptimeMillis();
19631        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19632            return;
19633        }
19634        if (!mProcessesToGc.contains(app)) {
19635            addProcessToGcListLocked(app);
19636            scheduleAppGcsLocked();
19637        }
19638    }
19639
19640    final void checkExcessivePowerUsageLocked(boolean doKills) {
19641        updateCpuStatsNow();
19642
19643        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19644        boolean doWakeKills = doKills;
19645        boolean doCpuKills = doKills;
19646        if (mLastPowerCheckRealtime == 0) {
19647            doWakeKills = false;
19648        }
19649        if (mLastPowerCheckUptime == 0) {
19650            doCpuKills = false;
19651        }
19652        if (stats.isScreenOn()) {
19653            doWakeKills = false;
19654        }
19655        final long curRealtime = SystemClock.elapsedRealtime();
19656        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19657        final long curUptime = SystemClock.uptimeMillis();
19658        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19659        mLastPowerCheckRealtime = curRealtime;
19660        mLastPowerCheckUptime = curUptime;
19661        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19662            doWakeKills = false;
19663        }
19664        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19665            doCpuKills = false;
19666        }
19667        int i = mLruProcesses.size();
19668        while (i > 0) {
19669            i--;
19670            ProcessRecord app = mLruProcesses.get(i);
19671            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19672                long wtime;
19673                synchronized (stats) {
19674                    wtime = stats.getProcessWakeTime(app.info.uid,
19675                            app.pid, curRealtime);
19676                }
19677                long wtimeUsed = wtime - app.lastWakeTime;
19678                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19679                if (DEBUG_POWER) {
19680                    StringBuilder sb = new StringBuilder(128);
19681                    sb.append("Wake for ");
19682                    app.toShortString(sb);
19683                    sb.append(": over ");
19684                    TimeUtils.formatDuration(realtimeSince, sb);
19685                    sb.append(" used ");
19686                    TimeUtils.formatDuration(wtimeUsed, sb);
19687                    sb.append(" (");
19688                    sb.append((wtimeUsed*100)/realtimeSince);
19689                    sb.append("%)");
19690                    Slog.i(TAG_POWER, sb.toString());
19691                    sb.setLength(0);
19692                    sb.append("CPU for ");
19693                    app.toShortString(sb);
19694                    sb.append(": over ");
19695                    TimeUtils.formatDuration(uptimeSince, sb);
19696                    sb.append(" used ");
19697                    TimeUtils.formatDuration(cputimeUsed, sb);
19698                    sb.append(" (");
19699                    sb.append((cputimeUsed*100)/uptimeSince);
19700                    sb.append("%)");
19701                    Slog.i(TAG_POWER, sb.toString());
19702                }
19703                // If a process has held a wake lock for more
19704                // than 50% of the time during this period,
19705                // that sounds bad.  Kill!
19706                if (doWakeKills && realtimeSince > 0
19707                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19708                    synchronized (stats) {
19709                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19710                                realtimeSince, wtimeUsed);
19711                    }
19712                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19713                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19714                } else if (doCpuKills && uptimeSince > 0
19715                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19716                    synchronized (stats) {
19717                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19718                                uptimeSince, cputimeUsed);
19719                    }
19720                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19721                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19722                } else {
19723                    app.lastWakeTime = wtime;
19724                    app.lastCpuTime = app.curCpuTime;
19725                }
19726            }
19727        }
19728    }
19729
19730    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19731            long nowElapsed) {
19732        boolean success = true;
19733
19734        if (app.curRawAdj != app.setRawAdj) {
19735            app.setRawAdj = app.curRawAdj;
19736        }
19737
19738        int changes = 0;
19739
19740        if (app.curAdj != app.setAdj) {
19741            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19742            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19743                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19744                    + app.adjType);
19745            app.setAdj = app.curAdj;
19746        }
19747
19748        if (app.setSchedGroup != app.curSchedGroup) {
19749            app.setSchedGroup = app.curSchedGroup;
19750            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19751                    "Setting sched group of " + app.processName
19752                    + " to " + app.curSchedGroup);
19753            if (app.waitingToKill != null && app.curReceiver == null
19754                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19755                app.kill(app.waitingToKill, true);
19756                success = false;
19757            } else {
19758                int processGroup;
19759                switch (app.curSchedGroup) {
19760                    case ProcessList.SCHED_GROUP_BACKGROUND:
19761                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19762                        break;
19763                    case ProcessList.SCHED_GROUP_TOP_APP:
19764                        processGroup = Process.THREAD_GROUP_TOP_APP;
19765                        break;
19766                    default:
19767                        processGroup = Process.THREAD_GROUP_DEFAULT;
19768                        break;
19769                }
19770                if (true) {
19771                    long oldId = Binder.clearCallingIdentity();
19772                    try {
19773                        Process.setProcessGroup(app.pid, processGroup);
19774                    } catch (Exception e) {
19775                        Slog.w(TAG, "Failed setting process group of " + app.pid
19776                                + " to " + app.curSchedGroup);
19777                        e.printStackTrace();
19778                    } finally {
19779                        Binder.restoreCallingIdentity(oldId);
19780                    }
19781                } else {
19782                    if (app.thread != null) {
19783                        try {
19784                            app.thread.setSchedulingGroup(processGroup);
19785                        } catch (RemoteException e) {
19786                        }
19787                    }
19788                }
19789            }
19790        }
19791        if (app.repForegroundActivities != app.foregroundActivities) {
19792            app.repForegroundActivities = app.foregroundActivities;
19793            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19794        }
19795        if (app.repProcState != app.curProcState) {
19796            app.repProcState = app.curProcState;
19797            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19798            if (app.thread != null) {
19799                try {
19800                    if (false) {
19801                        //RuntimeException h = new RuntimeException("here");
19802                        Slog.i(TAG, "Sending new process state " + app.repProcState
19803                                + " to " + app /*, h*/);
19804                    }
19805                    app.thread.setProcessState(app.repProcState);
19806                } catch (RemoteException e) {
19807                }
19808            }
19809        }
19810        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19811                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19812            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19813                // Experimental code to more aggressively collect pss while
19814                // running test...  the problem is that this tends to collect
19815                // the data right when a process is transitioning between process
19816                // states, which well tend to give noisy data.
19817                long start = SystemClock.uptimeMillis();
19818                long pss = Debug.getPss(app.pid, mTmpLong, null);
19819                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19820                mPendingPssProcesses.remove(app);
19821                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19822                        + " to " + app.curProcState + ": "
19823                        + (SystemClock.uptimeMillis()-start) + "ms");
19824            }
19825            app.lastStateTime = now;
19826            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19827                    mTestPssMode, isSleeping(), now);
19828            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19829                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19830                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19831                    + (app.nextPssTime-now) + ": " + app);
19832        } else {
19833            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19834                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19835                    mTestPssMode)))) {
19836                requestPssLocked(app, app.setProcState);
19837                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19838                        mTestPssMode, isSleeping(), now);
19839            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19840                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19841        }
19842        if (app.setProcState != app.curProcState) {
19843            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19844                    "Proc state change of " + app.processName
19845                            + " to " + app.curProcState);
19846            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19847            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19848            if (setImportant && !curImportant) {
19849                // This app is no longer something we consider important enough to allow to
19850                // use arbitrary amounts of battery power.  Note
19851                // its current wake lock time to later know to kill it if
19852                // it is not behaving well.
19853                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19854                synchronized (stats) {
19855                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19856                            app.pid, nowElapsed);
19857                }
19858                app.lastCpuTime = app.curCpuTime;
19859
19860            }
19861            // Inform UsageStats of important process state change
19862            // Must be called before updating setProcState
19863            maybeUpdateUsageStatsLocked(app, nowElapsed);
19864
19865            app.setProcState = app.curProcState;
19866            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19867                app.notCachedSinceIdle = false;
19868            }
19869            if (!doingAll) {
19870                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19871            } else {
19872                app.procStateChanged = true;
19873            }
19874        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19875                > USAGE_STATS_INTERACTION_INTERVAL) {
19876            // For apps that sit around for a long time in the interactive state, we need
19877            // to report this at least once a day so they don't go idle.
19878            maybeUpdateUsageStatsLocked(app, nowElapsed);
19879        }
19880
19881        if (changes != 0) {
19882            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19883                    "Changes in " + app + ": " + changes);
19884            int i = mPendingProcessChanges.size()-1;
19885            ProcessChangeItem item = null;
19886            while (i >= 0) {
19887                item = mPendingProcessChanges.get(i);
19888                if (item.pid == app.pid) {
19889                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19890                            "Re-using existing item: " + item);
19891                    break;
19892                }
19893                i--;
19894            }
19895            if (i < 0) {
19896                // No existing item in pending changes; need a new one.
19897                final int NA = mAvailProcessChanges.size();
19898                if (NA > 0) {
19899                    item = mAvailProcessChanges.remove(NA-1);
19900                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19901                            "Retrieving available item: " + item);
19902                } else {
19903                    item = new ProcessChangeItem();
19904                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19905                            "Allocating new item: " + item);
19906                }
19907                item.changes = 0;
19908                item.pid = app.pid;
19909                item.uid = app.info.uid;
19910                if (mPendingProcessChanges.size() == 0) {
19911                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19912                            "*** Enqueueing dispatch processes changed!");
19913                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19914                }
19915                mPendingProcessChanges.add(item);
19916            }
19917            item.changes |= changes;
19918            item.processState = app.repProcState;
19919            item.foregroundActivities = app.repForegroundActivities;
19920            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19921                    "Item " + Integer.toHexString(System.identityHashCode(item))
19922                    + " " + app.toShortString() + ": changes=" + item.changes
19923                    + " procState=" + item.processState
19924                    + " foreground=" + item.foregroundActivities
19925                    + " type=" + app.adjType + " source=" + app.adjSource
19926                    + " target=" + app.adjTarget);
19927        }
19928
19929        return success;
19930    }
19931
19932    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19933        final UidRecord.ChangeItem pendingChange;
19934        if (uidRec == null || uidRec.pendingChange == null) {
19935            if (mPendingUidChanges.size() == 0) {
19936                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19937                        "*** Enqueueing dispatch uid changed!");
19938                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19939            }
19940            final int NA = mAvailUidChanges.size();
19941            if (NA > 0) {
19942                pendingChange = mAvailUidChanges.remove(NA-1);
19943                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19944                        "Retrieving available item: " + pendingChange);
19945            } else {
19946                pendingChange = new UidRecord.ChangeItem();
19947                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19948                        "Allocating new item: " + pendingChange);
19949            }
19950            if (uidRec != null) {
19951                uidRec.pendingChange = pendingChange;
19952                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19953                    // If this uid is going away, and we haven't yet reported it is gone,
19954                    // then do so now.
19955                    change = UidRecord.CHANGE_GONE_IDLE;
19956                }
19957            } else if (uid < 0) {
19958                throw new IllegalArgumentException("No UidRecord or uid");
19959            }
19960            pendingChange.uidRecord = uidRec;
19961            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19962            mPendingUidChanges.add(pendingChange);
19963        } else {
19964            pendingChange = uidRec.pendingChange;
19965            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19966                change = UidRecord.CHANGE_GONE_IDLE;
19967            }
19968        }
19969        pendingChange.change = change;
19970        pendingChange.processState = uidRec != null
19971                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19972    }
19973
19974    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19975            String authority) {
19976        if (app == null) return;
19977        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19978            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19979            if (userState == null) return;
19980            final long now = SystemClock.elapsedRealtime();
19981            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19982            if (lastReported == null || lastReported < now - 60 * 1000L) {
19983                mUsageStatsService.reportContentProviderUsage(
19984                        authority, providerPkgName, app.userId);
19985                userState.mProviderLastReportedFg.put(authority, now);
19986            }
19987        }
19988    }
19989
19990    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19991        if (DEBUG_USAGE_STATS) {
19992            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19993                    + "] state changes: old = " + app.setProcState + ", new = "
19994                    + app.curProcState);
19995        }
19996        if (mUsageStatsService == null) {
19997            return;
19998        }
19999        boolean isInteraction;
20000        // To avoid some abuse patterns, we are going to be careful about what we consider
20001        // to be an app interaction.  Being the top activity doesn't count while the display
20002        // is sleeping, nor do short foreground services.
20003        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20004            isInteraction = true;
20005            app.fgInteractionTime = 0;
20006        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20007            if (app.fgInteractionTime == 0) {
20008                app.fgInteractionTime = nowElapsed;
20009                isInteraction = false;
20010            } else {
20011                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20012            }
20013        } else {
20014            isInteraction = app.curProcState
20015                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20016            app.fgInteractionTime = 0;
20017        }
20018        if (isInteraction && (!app.reportedInteraction
20019                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20020            app.interactionEventTime = nowElapsed;
20021            String[] packages = app.getPackageList();
20022            if (packages != null) {
20023                for (int i = 0; i < packages.length; i++) {
20024                    mUsageStatsService.reportEvent(packages[i], app.userId,
20025                            UsageEvents.Event.SYSTEM_INTERACTION);
20026                }
20027            }
20028        }
20029        app.reportedInteraction = isInteraction;
20030        if (!isInteraction) {
20031            app.interactionEventTime = 0;
20032        }
20033    }
20034
20035    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20036        if (proc.thread != null) {
20037            if (proc.baseProcessTracker != null) {
20038                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20039            }
20040        }
20041    }
20042
20043    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20044            ProcessRecord TOP_APP, boolean doingAll, long now) {
20045        if (app.thread == null) {
20046            return false;
20047        }
20048
20049        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20050
20051        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20052    }
20053
20054    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20055            boolean oomAdj) {
20056        if (isForeground != proc.foregroundServices) {
20057            proc.foregroundServices = isForeground;
20058            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20059                    proc.info.uid);
20060            if (isForeground) {
20061                if (curProcs == null) {
20062                    curProcs = new ArrayList<ProcessRecord>();
20063                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20064                }
20065                if (!curProcs.contains(proc)) {
20066                    curProcs.add(proc);
20067                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20068                            proc.info.packageName, proc.info.uid);
20069                }
20070            } else {
20071                if (curProcs != null) {
20072                    if (curProcs.remove(proc)) {
20073                        mBatteryStatsService.noteEvent(
20074                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20075                                proc.info.packageName, proc.info.uid);
20076                        if (curProcs.size() <= 0) {
20077                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20078                        }
20079                    }
20080                }
20081            }
20082            if (oomAdj) {
20083                updateOomAdjLocked();
20084            }
20085        }
20086    }
20087
20088    private final ActivityRecord resumedAppLocked() {
20089        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20090        String pkg;
20091        int uid;
20092        if (act != null) {
20093            pkg = act.packageName;
20094            uid = act.info.applicationInfo.uid;
20095        } else {
20096            pkg = null;
20097            uid = -1;
20098        }
20099        // Has the UID or resumed package name changed?
20100        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20101                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20102            if (mCurResumedPackage != null) {
20103                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20104                        mCurResumedPackage, mCurResumedUid);
20105            }
20106            mCurResumedPackage = pkg;
20107            mCurResumedUid = uid;
20108            if (mCurResumedPackage != null) {
20109                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20110                        mCurResumedPackage, mCurResumedUid);
20111            }
20112        }
20113        return act;
20114    }
20115
20116    final boolean updateOomAdjLocked(ProcessRecord app) {
20117        final ActivityRecord TOP_ACT = resumedAppLocked();
20118        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20119        final boolean wasCached = app.cached;
20120
20121        mAdjSeq++;
20122
20123        // This is the desired cached adjusment we want to tell it to use.
20124        // If our app is currently cached, we know it, and that is it.  Otherwise,
20125        // we don't know it yet, and it needs to now be cached we will then
20126        // need to do a complete oom adj.
20127        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20128                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20129        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20130                SystemClock.uptimeMillis());
20131        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20132            // Changed to/from cached state, so apps after it in the LRU
20133            // list may also be changed.
20134            updateOomAdjLocked();
20135        }
20136        return success;
20137    }
20138
20139    final void updateOomAdjLocked() {
20140        final ActivityRecord TOP_ACT = resumedAppLocked();
20141        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20142        final long now = SystemClock.uptimeMillis();
20143        final long nowElapsed = SystemClock.elapsedRealtime();
20144        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20145        final int N = mLruProcesses.size();
20146
20147        if (false) {
20148            RuntimeException e = new RuntimeException();
20149            e.fillInStackTrace();
20150            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20151        }
20152
20153        // Reset state in all uid records.
20154        for (int i=mActiveUids.size()-1; i>=0; i--) {
20155            final UidRecord uidRec = mActiveUids.valueAt(i);
20156            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20157                    "Starting update of " + uidRec);
20158            uidRec.reset();
20159        }
20160
20161        mStackSupervisor.rankTaskLayersIfNeeded();
20162
20163        mAdjSeq++;
20164        mNewNumServiceProcs = 0;
20165        mNewNumAServiceProcs = 0;
20166
20167        final int emptyProcessLimit;
20168        final int cachedProcessLimit;
20169        if (mProcessLimit <= 0) {
20170            emptyProcessLimit = cachedProcessLimit = 0;
20171        } else if (mProcessLimit == 1) {
20172            emptyProcessLimit = 1;
20173            cachedProcessLimit = 0;
20174        } else {
20175            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20176            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20177        }
20178
20179        // Let's determine how many processes we have running vs.
20180        // how many slots we have for background processes; we may want
20181        // to put multiple processes in a slot of there are enough of
20182        // them.
20183        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20184                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20185        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20186        if (numEmptyProcs > cachedProcessLimit) {
20187            // If there are more empty processes than our limit on cached
20188            // processes, then use the cached process limit for the factor.
20189            // This ensures that the really old empty processes get pushed
20190            // down to the bottom, so if we are running low on memory we will
20191            // have a better chance at keeping around more cached processes
20192            // instead of a gazillion empty processes.
20193            numEmptyProcs = cachedProcessLimit;
20194        }
20195        int emptyFactor = numEmptyProcs/numSlots;
20196        if (emptyFactor < 1) emptyFactor = 1;
20197        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20198        if (cachedFactor < 1) cachedFactor = 1;
20199        int stepCached = 0;
20200        int stepEmpty = 0;
20201        int numCached = 0;
20202        int numEmpty = 0;
20203        int numTrimming = 0;
20204
20205        mNumNonCachedProcs = 0;
20206        mNumCachedHiddenProcs = 0;
20207
20208        // First update the OOM adjustment for each of the
20209        // application processes based on their current state.
20210        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20211        int nextCachedAdj = curCachedAdj+1;
20212        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20213        int nextEmptyAdj = curEmptyAdj+2;
20214        for (int i=N-1; i>=0; i--) {
20215            ProcessRecord app = mLruProcesses.get(i);
20216            if (!app.killedByAm && app.thread != null) {
20217                app.procStateChanged = false;
20218                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20219
20220                // If we haven't yet assigned the final cached adj
20221                // to the process, do that now.
20222                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20223                    switch (app.curProcState) {
20224                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20225                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20226                            // This process is a cached process holding activities...
20227                            // assign it the next cached value for that type, and then
20228                            // step that cached level.
20229                            app.curRawAdj = curCachedAdj;
20230                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20231                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20232                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20233                                    + ")");
20234                            if (curCachedAdj != nextCachedAdj) {
20235                                stepCached++;
20236                                if (stepCached >= cachedFactor) {
20237                                    stepCached = 0;
20238                                    curCachedAdj = nextCachedAdj;
20239                                    nextCachedAdj += 2;
20240                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20241                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20242                                    }
20243                                }
20244                            }
20245                            break;
20246                        default:
20247                            // For everything else, assign next empty cached process
20248                            // level and bump that up.  Note that this means that
20249                            // long-running services that have dropped down to the
20250                            // cached level will be treated as empty (since their process
20251                            // state is still as a service), which is what we want.
20252                            app.curRawAdj = curEmptyAdj;
20253                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20254                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20255                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20256                                    + ")");
20257                            if (curEmptyAdj != nextEmptyAdj) {
20258                                stepEmpty++;
20259                                if (stepEmpty >= emptyFactor) {
20260                                    stepEmpty = 0;
20261                                    curEmptyAdj = nextEmptyAdj;
20262                                    nextEmptyAdj += 2;
20263                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20264                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20265                                    }
20266                                }
20267                            }
20268                            break;
20269                    }
20270                }
20271
20272                applyOomAdjLocked(app, true, now, nowElapsed);
20273
20274                // Count the number of process types.
20275                switch (app.curProcState) {
20276                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20277                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20278                        mNumCachedHiddenProcs++;
20279                        numCached++;
20280                        if (numCached > cachedProcessLimit) {
20281                            app.kill("cached #" + numCached, true);
20282                        }
20283                        break;
20284                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20285                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20286                                && app.lastActivityTime < oldTime) {
20287                            app.kill("empty for "
20288                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20289                                    / 1000) + "s", true);
20290                        } else {
20291                            numEmpty++;
20292                            if (numEmpty > emptyProcessLimit) {
20293                                app.kill("empty #" + numEmpty, true);
20294                            }
20295                        }
20296                        break;
20297                    default:
20298                        mNumNonCachedProcs++;
20299                        break;
20300                }
20301
20302                if (app.isolated && app.services.size() <= 0) {
20303                    // If this is an isolated process, and there are no
20304                    // services running in it, then the process is no longer
20305                    // needed.  We agressively kill these because we can by
20306                    // definition not re-use the same process again, and it is
20307                    // good to avoid having whatever code was running in them
20308                    // left sitting around after no longer needed.
20309                    app.kill("isolated not needed", true);
20310                } else {
20311                    // Keeping this process, update its uid.
20312                    final UidRecord uidRec = app.uidRecord;
20313                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20314                        uidRec.curProcState = app.curProcState;
20315                    }
20316                }
20317
20318                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20319                        && !app.killedByAm) {
20320                    numTrimming++;
20321                }
20322            }
20323        }
20324
20325        mNumServiceProcs = mNewNumServiceProcs;
20326
20327        // Now determine the memory trimming level of background processes.
20328        // Unfortunately we need to start at the back of the list to do this
20329        // properly.  We only do this if the number of background apps we
20330        // are managing to keep around is less than half the maximum we desire;
20331        // if we are keeping a good number around, we'll let them use whatever
20332        // memory they want.
20333        final int numCachedAndEmpty = numCached + numEmpty;
20334        int memFactor;
20335        if (numCached <= ProcessList.TRIM_CACHED_APPS
20336                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20337            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20338                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20339            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20340                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20341            } else {
20342                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20343            }
20344        } else {
20345            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20346        }
20347        // We always allow the memory level to go up (better).  We only allow it to go
20348        // down if we are in a state where that is allowed, *and* the total number of processes
20349        // has gone down since last time.
20350        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20351                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20352                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20353        if (memFactor > mLastMemoryLevel) {
20354            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20355                memFactor = mLastMemoryLevel;
20356                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20357            }
20358        }
20359        if (memFactor != mLastMemoryLevel) {
20360            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20361        }
20362        mLastMemoryLevel = memFactor;
20363        mLastNumProcesses = mLruProcesses.size();
20364        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20365        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20366        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20367            if (mLowRamStartTime == 0) {
20368                mLowRamStartTime = now;
20369            }
20370            int step = 0;
20371            int fgTrimLevel;
20372            switch (memFactor) {
20373                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20374                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20375                    break;
20376                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20377                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20378                    break;
20379                default:
20380                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20381                    break;
20382            }
20383            int factor = numTrimming/3;
20384            int minFactor = 2;
20385            if (mHomeProcess != null) minFactor++;
20386            if (mPreviousProcess != null) minFactor++;
20387            if (factor < minFactor) factor = minFactor;
20388            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20389            for (int i=N-1; i>=0; i--) {
20390                ProcessRecord app = mLruProcesses.get(i);
20391                if (allChanged || app.procStateChanged) {
20392                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20393                    app.procStateChanged = false;
20394                }
20395                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20396                        && !app.killedByAm) {
20397                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20398                        try {
20399                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20400                                    "Trimming memory of " + app.processName + " to " + curLevel);
20401                            app.thread.scheduleTrimMemory(curLevel);
20402                        } catch (RemoteException e) {
20403                        }
20404                        if (false) {
20405                            // For now we won't do this; our memory trimming seems
20406                            // to be good enough at this point that destroying
20407                            // activities causes more harm than good.
20408                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20409                                    && app != mHomeProcess && app != mPreviousProcess) {
20410                                // Need to do this on its own message because the stack may not
20411                                // be in a consistent state at this point.
20412                                // For these apps we will also finish their activities
20413                                // to help them free memory.
20414                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20415                            }
20416                        }
20417                    }
20418                    app.trimMemoryLevel = curLevel;
20419                    step++;
20420                    if (step >= factor) {
20421                        step = 0;
20422                        switch (curLevel) {
20423                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20424                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20425                                break;
20426                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20427                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20428                                break;
20429                        }
20430                    }
20431                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20432                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20433                            && app.thread != null) {
20434                        try {
20435                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20436                                    "Trimming memory of heavy-weight " + app.processName
20437                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20438                            app.thread.scheduleTrimMemory(
20439                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20440                        } catch (RemoteException e) {
20441                        }
20442                    }
20443                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20444                } else {
20445                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20446                            || app.systemNoUi) && app.pendingUiClean) {
20447                        // If this application is now in the background and it
20448                        // had done UI, then give it the special trim level to
20449                        // have it free UI resources.
20450                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20451                        if (app.trimMemoryLevel < level && app.thread != null) {
20452                            try {
20453                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20454                                        "Trimming memory of bg-ui " + app.processName
20455                                        + " to " + level);
20456                                app.thread.scheduleTrimMemory(level);
20457                            } catch (RemoteException e) {
20458                            }
20459                        }
20460                        app.pendingUiClean = false;
20461                    }
20462                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20463                        try {
20464                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20465                                    "Trimming memory of fg " + app.processName
20466                                    + " to " + fgTrimLevel);
20467                            app.thread.scheduleTrimMemory(fgTrimLevel);
20468                        } catch (RemoteException e) {
20469                        }
20470                    }
20471                    app.trimMemoryLevel = fgTrimLevel;
20472                }
20473            }
20474        } else {
20475            if (mLowRamStartTime != 0) {
20476                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20477                mLowRamStartTime = 0;
20478            }
20479            for (int i=N-1; i>=0; i--) {
20480                ProcessRecord app = mLruProcesses.get(i);
20481                if (allChanged || app.procStateChanged) {
20482                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20483                    app.procStateChanged = false;
20484                }
20485                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20486                        || app.systemNoUi) && app.pendingUiClean) {
20487                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20488                            && app.thread != null) {
20489                        try {
20490                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20491                                    "Trimming memory of ui hidden " + app.processName
20492                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20493                            app.thread.scheduleTrimMemory(
20494                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20495                        } catch (RemoteException e) {
20496                        }
20497                    }
20498                    app.pendingUiClean = false;
20499                }
20500                app.trimMemoryLevel = 0;
20501            }
20502        }
20503
20504        if (mAlwaysFinishActivities) {
20505            // Need to do this on its own message because the stack may not
20506            // be in a consistent state at this point.
20507            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20508        }
20509
20510        if (allChanged) {
20511            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20512        }
20513
20514        // Update from any uid changes.
20515        for (int i=mActiveUids.size()-1; i>=0; i--) {
20516            final UidRecord uidRec = mActiveUids.valueAt(i);
20517            int uidChange = UidRecord.CHANGE_PROCSTATE;
20518            if (uidRec.setProcState != uidRec.curProcState) {
20519                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20520                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20521                        + " to " + uidRec.curProcState);
20522                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20523                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20524                        uidRec.lastBackgroundTime = nowElapsed;
20525                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20526                            // Note: the background settle time is in elapsed realtime, while
20527                            // the handler time base is uptime.  All this means is that we may
20528                            // stop background uids later than we had intended, but that only
20529                            // happens because the device was sleeping so we are okay anyway.
20530                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20531                        }
20532                    }
20533                } else {
20534                    if (uidRec.idle) {
20535                        uidChange = UidRecord.CHANGE_ACTIVE;
20536                        uidRec.idle = false;
20537                    }
20538                    uidRec.lastBackgroundTime = 0;
20539                }
20540                uidRec.setProcState = uidRec.curProcState;
20541                enqueueUidChangeLocked(uidRec, -1, uidChange);
20542                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20543            }
20544        }
20545
20546        if (mProcessStats.shouldWriteNowLocked(now)) {
20547            mHandler.post(new Runnable() {
20548                @Override public void run() {
20549                    synchronized (ActivityManagerService.this) {
20550                        mProcessStats.writeStateAsyncLocked();
20551                    }
20552                }
20553            });
20554        }
20555
20556        if (DEBUG_OOM_ADJ) {
20557            final long duration = SystemClock.uptimeMillis() - now;
20558            if (false) {
20559                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20560                        new RuntimeException("here").fillInStackTrace());
20561            } else {
20562                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20563            }
20564        }
20565    }
20566
20567    final void idleUids() {
20568        synchronized (this) {
20569            final long nowElapsed = SystemClock.elapsedRealtime();
20570            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20571            long nextTime = 0;
20572            for (int i=mActiveUids.size()-1; i>=0; i--) {
20573                final UidRecord uidRec = mActiveUids.valueAt(i);
20574                final long bgTime = uidRec.lastBackgroundTime;
20575                if (bgTime > 0 && !uidRec.idle) {
20576                    if (bgTime <= maxBgTime) {
20577                        uidRec.idle = true;
20578                        doStopUidLocked(uidRec.uid, uidRec);
20579                    } else {
20580                        if (nextTime == 0 || nextTime > bgTime) {
20581                            nextTime = bgTime;
20582                        }
20583                    }
20584                }
20585            }
20586            if (nextTime > 0) {
20587                mHandler.removeMessages(IDLE_UIDS_MSG);
20588                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20589                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20590            }
20591        }
20592    }
20593
20594    final void runInBackgroundDisabled(int uid) {
20595        synchronized (this) {
20596            UidRecord uidRec = mActiveUids.get(uid);
20597            if (uidRec != null) {
20598                // This uid is actually running...  should it be considered background now?
20599                if (uidRec.idle) {
20600                    doStopUidLocked(uidRec.uid, uidRec);
20601                }
20602            } else {
20603                // This uid isn't actually running...  still send a report about it being "stopped".
20604                doStopUidLocked(uid, null);
20605            }
20606        }
20607    }
20608
20609    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20610        mServices.stopInBackgroundLocked(uid);
20611        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20612    }
20613
20614    final void trimApplications() {
20615        synchronized (this) {
20616            int i;
20617
20618            // First remove any unused application processes whose package
20619            // has been removed.
20620            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20621                final ProcessRecord app = mRemovedProcesses.get(i);
20622                if (app.activities.size() == 0
20623                        && app.curReceiver == null && app.services.size() == 0) {
20624                    Slog.i(
20625                        TAG, "Exiting empty application process "
20626                        + app.toShortString() + " ("
20627                        + (app.thread != null ? app.thread.asBinder() : null)
20628                        + ")\n");
20629                    if (app.pid > 0 && app.pid != MY_PID) {
20630                        app.kill("empty", false);
20631                    } else {
20632                        try {
20633                            app.thread.scheduleExit();
20634                        } catch (Exception e) {
20635                            // Ignore exceptions.
20636                        }
20637                    }
20638                    cleanUpApplicationRecordLocked(app, false, true, -1);
20639                    mRemovedProcesses.remove(i);
20640
20641                    if (app.persistent) {
20642                        addAppLocked(app.info, false, null /* ABI override */);
20643                    }
20644                }
20645            }
20646
20647            // Now update the oom adj for all processes.
20648            updateOomAdjLocked();
20649        }
20650    }
20651
20652    /** This method sends the specified signal to each of the persistent apps */
20653    public void signalPersistentProcesses(int sig) throws RemoteException {
20654        if (sig != Process.SIGNAL_USR1) {
20655            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20656        }
20657
20658        synchronized (this) {
20659            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20660                    != PackageManager.PERMISSION_GRANTED) {
20661                throw new SecurityException("Requires permission "
20662                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20663            }
20664
20665            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20666                ProcessRecord r = mLruProcesses.get(i);
20667                if (r.thread != null && r.persistent) {
20668                    Process.sendSignal(r.pid, sig);
20669                }
20670            }
20671        }
20672    }
20673
20674    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20675        if (proc == null || proc == mProfileProc) {
20676            proc = mProfileProc;
20677            profileType = mProfileType;
20678            clearProfilerLocked();
20679        }
20680        if (proc == null) {
20681            return;
20682        }
20683        try {
20684            proc.thread.profilerControl(false, null, profileType);
20685        } catch (RemoteException e) {
20686            throw new IllegalStateException("Process disappeared");
20687        }
20688    }
20689
20690    private void clearProfilerLocked() {
20691        if (mProfileFd != null) {
20692            try {
20693                mProfileFd.close();
20694            } catch (IOException e) {
20695            }
20696        }
20697        mProfileApp = null;
20698        mProfileProc = null;
20699        mProfileFile = null;
20700        mProfileType = 0;
20701        mAutoStopProfiler = false;
20702        mSamplingInterval = 0;
20703    }
20704
20705    public boolean profileControl(String process, int userId, boolean start,
20706            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20707
20708        try {
20709            synchronized (this) {
20710                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20711                // its own permission.
20712                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20713                        != PackageManager.PERMISSION_GRANTED) {
20714                    throw new SecurityException("Requires permission "
20715                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20716                }
20717
20718                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20719                    throw new IllegalArgumentException("null profile info or fd");
20720                }
20721
20722                ProcessRecord proc = null;
20723                if (process != null) {
20724                    proc = findProcessLocked(process, userId, "profileControl");
20725                }
20726
20727                if (start && (proc == null || proc.thread == null)) {
20728                    throw new IllegalArgumentException("Unknown process: " + process);
20729                }
20730
20731                if (start) {
20732                    stopProfilerLocked(null, 0);
20733                    setProfileApp(proc.info, proc.processName, profilerInfo);
20734                    mProfileProc = proc;
20735                    mProfileType = profileType;
20736                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20737                    try {
20738                        fd = fd.dup();
20739                    } catch (IOException e) {
20740                        fd = null;
20741                    }
20742                    profilerInfo.profileFd = fd;
20743                    proc.thread.profilerControl(start, profilerInfo, profileType);
20744                    fd = null;
20745                    mProfileFd = null;
20746                } else {
20747                    stopProfilerLocked(proc, profileType);
20748                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20749                        try {
20750                            profilerInfo.profileFd.close();
20751                        } catch (IOException e) {
20752                        }
20753                    }
20754                }
20755
20756                return true;
20757            }
20758        } catch (RemoteException e) {
20759            throw new IllegalStateException("Process disappeared");
20760        } finally {
20761            if (profilerInfo != null && profilerInfo.profileFd != null) {
20762                try {
20763                    profilerInfo.profileFd.close();
20764                } catch (IOException e) {
20765                }
20766            }
20767        }
20768    }
20769
20770    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20771        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20772                userId, true, ALLOW_FULL_ONLY, callName, null);
20773        ProcessRecord proc = null;
20774        try {
20775            int pid = Integer.parseInt(process);
20776            synchronized (mPidsSelfLocked) {
20777                proc = mPidsSelfLocked.get(pid);
20778            }
20779        } catch (NumberFormatException e) {
20780        }
20781
20782        if (proc == null) {
20783            ArrayMap<String, SparseArray<ProcessRecord>> all
20784                    = mProcessNames.getMap();
20785            SparseArray<ProcessRecord> procs = all.get(process);
20786            if (procs != null && procs.size() > 0) {
20787                proc = procs.valueAt(0);
20788                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20789                    for (int i=1; i<procs.size(); i++) {
20790                        ProcessRecord thisProc = procs.valueAt(i);
20791                        if (thisProc.userId == userId) {
20792                            proc = thisProc;
20793                            break;
20794                        }
20795                    }
20796                }
20797            }
20798        }
20799
20800        return proc;
20801    }
20802
20803    public boolean dumpHeap(String process, int userId, boolean managed,
20804            String path, ParcelFileDescriptor fd) throws RemoteException {
20805
20806        try {
20807            synchronized (this) {
20808                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20809                // its own permission (same as profileControl).
20810                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20811                        != PackageManager.PERMISSION_GRANTED) {
20812                    throw new SecurityException("Requires permission "
20813                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20814                }
20815
20816                if (fd == null) {
20817                    throw new IllegalArgumentException("null fd");
20818                }
20819
20820                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20821                if (proc == null || proc.thread == null) {
20822                    throw new IllegalArgumentException("Unknown process: " + process);
20823                }
20824
20825                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20826                if (!isDebuggable) {
20827                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20828                        throw new SecurityException("Process not debuggable: " + proc);
20829                    }
20830                }
20831
20832                proc.thread.dumpHeap(managed, path, fd);
20833                fd = null;
20834                return true;
20835            }
20836        } catch (RemoteException e) {
20837            throw new IllegalStateException("Process disappeared");
20838        } finally {
20839            if (fd != null) {
20840                try {
20841                    fd.close();
20842                } catch (IOException e) {
20843                }
20844            }
20845        }
20846    }
20847
20848    @Override
20849    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20850            String reportPackage) {
20851        if (processName != null) {
20852            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20853                    "setDumpHeapDebugLimit()");
20854        } else {
20855            synchronized (mPidsSelfLocked) {
20856                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20857                if (proc == null) {
20858                    throw new SecurityException("No process found for calling pid "
20859                            + Binder.getCallingPid());
20860                }
20861                if (!Build.IS_DEBUGGABLE
20862                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20863                    throw new SecurityException("Not running a debuggable build");
20864                }
20865                processName = proc.processName;
20866                uid = proc.uid;
20867                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20868                    throw new SecurityException("Package " + reportPackage + " is not running in "
20869                            + proc);
20870                }
20871            }
20872        }
20873        synchronized (this) {
20874            if (maxMemSize > 0) {
20875                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20876            } else {
20877                if (uid != 0) {
20878                    mMemWatchProcesses.remove(processName, uid);
20879                } else {
20880                    mMemWatchProcesses.getMap().remove(processName);
20881                }
20882            }
20883        }
20884    }
20885
20886    @Override
20887    public void dumpHeapFinished(String path) {
20888        synchronized (this) {
20889            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20890                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20891                        + " does not match last pid " + mMemWatchDumpPid);
20892                return;
20893            }
20894            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20895                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20896                        + " does not match last path " + mMemWatchDumpFile);
20897                return;
20898            }
20899            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20900            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20901        }
20902    }
20903
20904    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20905    public void monitor() {
20906        synchronized (this) { }
20907    }
20908
20909    void onCoreSettingsChange(Bundle settings) {
20910        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20911            ProcessRecord processRecord = mLruProcesses.get(i);
20912            try {
20913                if (processRecord.thread != null) {
20914                    processRecord.thread.setCoreSettings(settings);
20915                }
20916            } catch (RemoteException re) {
20917                /* ignore */
20918            }
20919        }
20920    }
20921
20922    // Multi-user methods
20923
20924    /**
20925     * Start user, if its not already running, but don't bring it to foreground.
20926     */
20927    @Override
20928    public boolean startUserInBackground(final int userId) {
20929        return mUserController.startUser(userId, /* foreground */ false);
20930    }
20931
20932    @Override
20933    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20934        return mUserController.unlockUser(userId, token, secret, listener);
20935    }
20936
20937    @Override
20938    public boolean switchUser(final int targetUserId) {
20939        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20940        UserInfo currentUserInfo;
20941        UserInfo targetUserInfo;
20942        synchronized (this) {
20943            int currentUserId = mUserController.getCurrentUserIdLocked();
20944            currentUserInfo = mUserController.getUserInfo(currentUserId);
20945            targetUserInfo = mUserController.getUserInfo(targetUserId);
20946            if (targetUserInfo == null) {
20947                Slog.w(TAG, "No user info for user #" + targetUserId);
20948                return false;
20949            }
20950            if (!targetUserInfo.supportsSwitchTo()) {
20951                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20952                return false;
20953            }
20954            if (targetUserInfo.isManagedProfile()) {
20955                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20956                return false;
20957            }
20958            mUserController.setTargetUserIdLocked(targetUserId);
20959        }
20960        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20961        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20962        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20963        return true;
20964    }
20965
20966    void scheduleStartProfilesLocked() {
20967        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20968            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20969                    DateUtils.SECOND_IN_MILLIS);
20970        }
20971    }
20972
20973    @Override
20974    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20975        return mUserController.stopUser(userId, force, callback);
20976    }
20977
20978    @Override
20979    public UserInfo getCurrentUser() {
20980        return mUserController.getCurrentUser();
20981    }
20982
20983    @Override
20984    public boolean isUserRunning(int userId, int flags) {
20985        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20986                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20987            String msg = "Permission Denial: isUserRunning() from pid="
20988                    + Binder.getCallingPid()
20989                    + ", uid=" + Binder.getCallingUid()
20990                    + " requires " + INTERACT_ACROSS_USERS;
20991            Slog.w(TAG, msg);
20992            throw new SecurityException(msg);
20993        }
20994        synchronized (this) {
20995            return mUserController.isUserRunningLocked(userId, flags);
20996        }
20997    }
20998
20999    @Override
21000    public int[] getRunningUserIds() {
21001        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21002                != PackageManager.PERMISSION_GRANTED) {
21003            String msg = "Permission Denial: isUserRunning() from pid="
21004                    + Binder.getCallingPid()
21005                    + ", uid=" + Binder.getCallingUid()
21006                    + " requires " + INTERACT_ACROSS_USERS;
21007            Slog.w(TAG, msg);
21008            throw new SecurityException(msg);
21009        }
21010        synchronized (this) {
21011            return mUserController.getStartedUserArrayLocked();
21012        }
21013    }
21014
21015    @Override
21016    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21017        mUserController.registerUserSwitchObserver(observer);
21018    }
21019
21020    @Override
21021    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21022        mUserController.unregisterUserSwitchObserver(observer);
21023    }
21024
21025    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21026        if (info == null) return null;
21027        ApplicationInfo newInfo = new ApplicationInfo(info);
21028        newInfo.initForUser(userId);
21029        return newInfo;
21030    }
21031
21032    public boolean isUserStopped(int userId) {
21033        synchronized (this) {
21034            return mUserController.getStartedUserStateLocked(userId) == null;
21035        }
21036    }
21037
21038    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21039        if (aInfo == null
21040                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21041            return aInfo;
21042        }
21043
21044        ActivityInfo info = new ActivityInfo(aInfo);
21045        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21046        return info;
21047    }
21048
21049    private boolean processSanityChecksLocked(ProcessRecord process) {
21050        if (process == null || process.thread == null) {
21051            return false;
21052        }
21053
21054        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21055        if (!isDebuggable) {
21056            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21057                return false;
21058            }
21059        }
21060
21061        return true;
21062    }
21063
21064    public boolean startBinderTracking() throws RemoteException {
21065        synchronized (this) {
21066            mBinderTransactionTrackingEnabled = true;
21067            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21068            // permission (same as profileControl).
21069            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21070                    != PackageManager.PERMISSION_GRANTED) {
21071                throw new SecurityException("Requires permission "
21072                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21073            }
21074
21075            for (int i = 0; i < mLruProcesses.size(); i++) {
21076                ProcessRecord process = mLruProcesses.get(i);
21077                if (!processSanityChecksLocked(process)) {
21078                    continue;
21079                }
21080                try {
21081                    process.thread.startBinderTracking();
21082                } catch (RemoteException e) {
21083                    Log.v(TAG, "Process disappared");
21084                }
21085            }
21086            return true;
21087        }
21088    }
21089
21090    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21091        try {
21092            synchronized (this) {
21093                mBinderTransactionTrackingEnabled = false;
21094                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21095                // permission (same as profileControl).
21096                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21097                        != PackageManager.PERMISSION_GRANTED) {
21098                    throw new SecurityException("Requires permission "
21099                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21100                }
21101
21102                if (fd == null) {
21103                    throw new IllegalArgumentException("null fd");
21104                }
21105
21106                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21107                pw.println("Binder transaction traces for all processes.\n");
21108                for (ProcessRecord process : mLruProcesses) {
21109                    if (!processSanityChecksLocked(process)) {
21110                        continue;
21111                    }
21112
21113                    pw.println("Traces for process: " + process.processName);
21114                    pw.flush();
21115                    try {
21116                        TransferPipe tp = new TransferPipe();
21117                        try {
21118                            process.thread.stopBinderTrackingAndDump(
21119                                    tp.getWriteFd().getFileDescriptor());
21120                            tp.go(fd.getFileDescriptor());
21121                        } finally {
21122                            tp.kill();
21123                        }
21124                    } catch (IOException e) {
21125                        pw.println("Failure while dumping IPC traces from " + process +
21126                                ".  Exception: " + e);
21127                        pw.flush();
21128                    } catch (RemoteException e) {
21129                        pw.println("Got a RemoteException while dumping IPC traces from " +
21130                                process + ".  Exception: " + e);
21131                        pw.flush();
21132                    }
21133                }
21134                fd = null;
21135                return true;
21136            }
21137        } finally {
21138            if (fd != null) {
21139                try {
21140                    fd.close();
21141                } catch (IOException e) {
21142                }
21143            }
21144        }
21145    }
21146
21147    private final class LocalService extends ActivityManagerInternal {
21148        @Override
21149        public void onWakefulnessChanged(int wakefulness) {
21150            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21151        }
21152
21153        @Override
21154        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21155                String processName, String abiOverride, int uid, Runnable crashHandler) {
21156            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21157                    processName, abiOverride, uid, crashHandler);
21158        }
21159
21160        @Override
21161        public SleepToken acquireSleepToken(String tag) {
21162            Preconditions.checkNotNull(tag);
21163
21164            synchronized (ActivityManagerService.this) {
21165                SleepTokenImpl token = new SleepTokenImpl(tag);
21166                mSleepTokens.add(token);
21167                updateSleepIfNeededLocked();
21168                applyVrModeIfNeededLocked(mFocusedActivity, false);
21169                return token;
21170            }
21171        }
21172
21173        @Override
21174        public ComponentName getHomeActivityForUser(int userId) {
21175            synchronized (ActivityManagerService.this) {
21176                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21177                return homeActivity == null ? null : homeActivity.realActivity;
21178            }
21179        }
21180
21181        @Override
21182        public void onUserRemoved(int userId) {
21183            synchronized (ActivityManagerService.this) {
21184                ActivityManagerService.this.onUserStoppedLocked(userId);
21185            }
21186        }
21187
21188        @Override
21189        public void onLocalVoiceInteractionStarted(IBinder activity,
21190                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21191            synchronized (ActivityManagerService.this) {
21192                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21193                        voiceSession, voiceInteractor);
21194            }
21195        }
21196
21197        @Override
21198        public void notifyStartingWindowDrawn() {
21199            synchronized (ActivityManagerService.this) {
21200                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21201            }
21202        }
21203
21204        @Override
21205        public void notifyAppTransitionStarting(int reason) {
21206            synchronized (ActivityManagerService.this) {
21207                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21208            }
21209        }
21210
21211        @Override
21212        public void notifyAppTransitionFinished() {
21213            synchronized (ActivityManagerService.this) {
21214                mStackSupervisor.notifyAppTransitionDone();
21215            }
21216        }
21217
21218        @Override
21219        public void notifyAppTransitionCancelled() {
21220            synchronized (ActivityManagerService.this) {
21221                mStackSupervisor.notifyAppTransitionDone();
21222            }
21223        }
21224
21225        @Override
21226        public List<IBinder> getTopVisibleActivities() {
21227            synchronized (ActivityManagerService.this) {
21228                return mStackSupervisor.getTopVisibleActivities();
21229            }
21230        }
21231
21232        @Override
21233        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21234            synchronized (ActivityManagerService.this) {
21235                mStackSupervisor.setDockedStackMinimized(minimized);
21236            }
21237        }
21238
21239        @Override
21240        public void killForegroundAppsForUser(int userHandle) {
21241            synchronized (ActivityManagerService.this) {
21242                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21243                final int NP = mProcessNames.getMap().size();
21244                for (int ip = 0; ip < NP; ip++) {
21245                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21246                    final int NA = apps.size();
21247                    for (int ia = 0; ia < NA; ia++) {
21248                        final ProcessRecord app = apps.valueAt(ia);
21249                        if (app.persistent) {
21250                            // We don't kill persistent processes.
21251                            continue;
21252                        }
21253                        if (app.removed) {
21254                            procs.add(app);
21255                        } else if (app.userId == userHandle && app.foregroundActivities) {
21256                            app.removed = true;
21257                            procs.add(app);
21258                        }
21259                    }
21260                }
21261
21262                final int N = procs.size();
21263                for (int i = 0; i < N; i++) {
21264                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21265                }
21266            }
21267        }
21268    }
21269
21270    private final class SleepTokenImpl extends SleepToken {
21271        private final String mTag;
21272        private final long mAcquireTime;
21273
21274        public SleepTokenImpl(String tag) {
21275            mTag = tag;
21276            mAcquireTime = SystemClock.uptimeMillis();
21277        }
21278
21279        @Override
21280        public void release() {
21281            synchronized (ActivityManagerService.this) {
21282                if (mSleepTokens.remove(this)) {
21283                    updateSleepIfNeededLocked();
21284                }
21285            }
21286        }
21287
21288        @Override
21289        public String toString() {
21290            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21291        }
21292    }
21293
21294    /**
21295     * An implementation of IAppTask, that allows an app to manage its own tasks via
21296     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21297     * only the process that calls getAppTasks() can call the AppTask methods.
21298     */
21299    class AppTaskImpl extends IAppTask.Stub {
21300        private int mTaskId;
21301        private int mCallingUid;
21302
21303        public AppTaskImpl(int taskId, int callingUid) {
21304            mTaskId = taskId;
21305            mCallingUid = callingUid;
21306        }
21307
21308        private void checkCaller() {
21309            if (mCallingUid != Binder.getCallingUid()) {
21310                throw new SecurityException("Caller " + mCallingUid
21311                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21312            }
21313        }
21314
21315        @Override
21316        public void finishAndRemoveTask() {
21317            checkCaller();
21318
21319            synchronized (ActivityManagerService.this) {
21320                long origId = Binder.clearCallingIdentity();
21321                try {
21322                    // We remove the task from recents to preserve backwards
21323                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21324                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21325                    }
21326                } finally {
21327                    Binder.restoreCallingIdentity(origId);
21328                }
21329            }
21330        }
21331
21332        @Override
21333        public ActivityManager.RecentTaskInfo getTaskInfo() {
21334            checkCaller();
21335
21336            synchronized (ActivityManagerService.this) {
21337                long origId = Binder.clearCallingIdentity();
21338                try {
21339                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21340                    if (tr == null) {
21341                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21342                    }
21343                    return createRecentTaskInfoFromTaskRecord(tr);
21344                } finally {
21345                    Binder.restoreCallingIdentity(origId);
21346                }
21347            }
21348        }
21349
21350        @Override
21351        public void moveToFront() {
21352            checkCaller();
21353            // Will bring task to front if it already has a root activity.
21354            final long origId = Binder.clearCallingIdentity();
21355            try {
21356                synchronized (this) {
21357                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21358                }
21359            } finally {
21360                Binder.restoreCallingIdentity(origId);
21361            }
21362        }
21363
21364        @Override
21365        public int startActivity(IBinder whoThread, String callingPackage,
21366                Intent intent, String resolvedType, Bundle bOptions) {
21367            checkCaller();
21368
21369            int callingUser = UserHandle.getCallingUserId();
21370            TaskRecord tr;
21371            IApplicationThread appThread;
21372            synchronized (ActivityManagerService.this) {
21373                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21374                if (tr == null) {
21375                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21376                }
21377                appThread = ApplicationThreadNative.asInterface(whoThread);
21378                if (appThread == null) {
21379                    throw new IllegalArgumentException("Bad app thread " + appThread);
21380                }
21381            }
21382            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21383                    resolvedType, null, null, null, null, 0, 0, null, null,
21384                    null, bOptions, false, callingUser, null, tr);
21385        }
21386
21387        @Override
21388        public void setExcludeFromRecents(boolean exclude) {
21389            checkCaller();
21390
21391            synchronized (ActivityManagerService.this) {
21392                long origId = Binder.clearCallingIdentity();
21393                try {
21394                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21395                    if (tr == null) {
21396                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21397                    }
21398                    Intent intent = tr.getBaseIntent();
21399                    if (exclude) {
21400                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21401                    } else {
21402                        intent.setFlags(intent.getFlags()
21403                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21404                    }
21405                } finally {
21406                    Binder.restoreCallingIdentity(origId);
21407                }
21408            }
21409        }
21410    }
21411
21412    /**
21413     * Kill processes for the user with id userId and that depend on the package named packageName
21414     */
21415    @Override
21416    public void killPackageDependents(String packageName, int userId) {
21417        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21418        if (packageName == null) {
21419            throw new NullPointerException(
21420                    "Cannot kill the dependents of a package without its name.");
21421        }
21422
21423        long callingId = Binder.clearCallingIdentity();
21424        IPackageManager pm = AppGlobals.getPackageManager();
21425        int pkgUid = -1;
21426        try {
21427            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21428        } catch (RemoteException e) {
21429        }
21430        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21431            throw new IllegalArgumentException(
21432                    "Cannot kill dependents of non-existing package " + packageName);
21433        }
21434        try {
21435            synchronized(this) {
21436                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21437                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21438                        "dep: " + packageName);
21439            }
21440        } finally {
21441            Binder.restoreCallingIdentity(callingId);
21442        }
21443    }
21444}
21445