ActivityManagerService.java revision 66ec21a817db000ffc9868eddcf0fcb1caf9eee7
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
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    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519    static final int FIRST_COMPAT_MODE_MSG = 300;
1520    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522    static ServiceThread sKillThread = null;
1523    static KillHandler sKillHandler = null;
1524
1525    CompatModeDialog mCompatModeDialog;
1526    long mLastMemUsageReportTime = 0;
1527
1528    /**
1529     * Flag whether the current user is a "monkey", i.e. whether
1530     * the UI is driven by a UI automation tool.
1531     */
1532    private boolean mUserIsMonkey;
1533
1534    /** Flag whether the device has a Recents UI */
1535    boolean mHasRecents;
1536
1537    /** The dimensions of the thumbnails in the Recents UI. */
1538    int mThumbnailWidth;
1539    int mThumbnailHeight;
1540    float mFullscreenThumbnailScale;
1541
1542    final ServiceThread mHandlerThread;
1543    final MainHandler mHandler;
1544    final UiHandler mUiHandler;
1545
1546    PackageManagerInternal mPackageManagerInt;
1547
1548    // VoiceInteraction session ID that changes for each new request except when
1549    // being called for multiwindow assist in a single session.
1550    private int mViSessionId = 1000;
1551
1552    final class KillHandler extends Handler {
1553        static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555        public KillHandler(Looper looper) {
1556            super(looper, null, true);
1557        }
1558
1559        @Override
1560        public void handleMessage(Message msg) {
1561            switch (msg.what) {
1562                case KILL_PROCESS_GROUP_MSG:
1563                {
1564                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                }
1568                break;
1569
1570                default:
1571                    super.handleMessage(msg);
1572            }
1573        }
1574    }
1575
1576    final class UiHandler extends Handler {
1577        public UiHandler() {
1578            super(com.android.server.UiThread.get().getLooper(), null, true);
1579        }
1580
1581        @Override
1582        public void handleMessage(Message msg) {
1583            switch (msg.what) {
1584            case SHOW_ERROR_UI_MSG: {
1585                mAppErrors.handleShowAppErrorUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_NOT_RESPONDING_UI_MSG: {
1589                mAppErrors.handleShowAnrUi(msg);
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord proc = (ProcessRecord) data.get("app");
1596                    if (proc == null) {
1597                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                        break;
1599                    }
1600                    if (proc.crashDialog != null) {
1601                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                        return;
1603                    }
1604                    AppErrorResult res = (AppErrorResult) data.get("result");
1605                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                        Dialog d = new StrictModeViolationDialog(mContext,
1607                                ActivityManagerService.this, res, proc);
1608                        d.show();
1609                        proc.crashDialog = d;
1610                    } else {
1611                        // The device is asleep, so just pretend that the user
1612                        // saw a crash dialog and hit "force quit".
1613                        res.set(0);
1614                    }
1615                }
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_FACTORY_ERROR_UI_MSG: {
1619                Dialog d = new FactoryErrorDialog(
1620                    mContext, msg.getData().getCharSequence("msg"));
1621                d.show();
1622                ensureBootCompleted();
1623            } break;
1624            case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ProcessRecord app = (ProcessRecord)msg.obj;
1627                    if (msg.arg1 != 0) {
1628                        if (!app.waitedForDebugger) {
1629                            Dialog d = new AppWaitingForDebuggerDialog(
1630                                    ActivityManagerService.this,
1631                                    mContext, app);
1632                            app.waitDialog = d;
1633                            app.waitedForDebugger = true;
1634                            d.show();
1635                        }
1636                    } else {
1637                        if (app.waitDialog != null) {
1638                            app.waitDialog.dismiss();
1639                            app.waitDialog = null;
1640                        }
1641                    }
1642                }
1643            } break;
1644            case SHOW_UID_ERROR_UI_MSG: {
1645                if (mShowDialogs) {
1646                    AlertDialog d = new BaseErrorDialog(mContext);
1647                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                    d.setCancelable(false);
1649                    d.setTitle(mContext.getText(R.string.android_system_label));
1650                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                    d.show();
1654                }
1655            } break;
1656            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                if (mShowDialogs) {
1658                    AlertDialog d = new BaseErrorDialog(mContext);
1659                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                    d.setCancelable(false);
1661                    d.setTitle(mContext.getText(R.string.android_system_label));
1662                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                    d.show();
1666                }
1667            } break;
1668            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                synchronized (ActivityManagerService.this) {
1670                    ActivityRecord ar = (ActivityRecord) msg.obj;
1671                    if (mCompatModeDialog != null) {
1672                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                ar.info.applicationInfo.packageName)) {
1674                            return;
1675                        }
1676                        mCompatModeDialog.dismiss();
1677                        mCompatModeDialog = null;
1678                    }
1679                    if (ar != null && false) {
1680                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                ar.packageName)) {
1682                            int mode = mCompatModePackages.computeCompatModeLocked(
1683                                    ar.info.applicationInfo);
1684                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                mCompatModeDialog = new CompatModeDialog(
1687                                        ActivityManagerService.this, mContext,
1688                                        ar.info.applicationInfo);
1689                                mCompatModeDialog.show();
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case START_USER_SWITCH_UI_MSG: {
1697                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                break;
1699            }
1700            case DISMISS_DIALOG_UI_MSG: {
1701                final Dialog d = (Dialog) msg.obj;
1702                d.dismiss();
1703                break;
1704            }
1705            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                dispatchProcessesChanged();
1707                break;
1708            }
1709            case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                final int pid = msg.arg1;
1711                final int uid = msg.arg2;
1712                dispatchProcessDied(pid, uid);
1713                break;
1714            }
1715            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                dispatchUidsChanged();
1717            } break;
1718            }
1719        }
1720    }
1721
1722    final class MainHandler extends Handler {
1723        public MainHandler(Looper looper) {
1724            super(looper, null, true);
1725        }
1726
1727        @Override
1728        public void handleMessage(Message msg) {
1729            switch (msg.what) {
1730            case UPDATE_CONFIGURATION_MSG: {
1731                final ContentResolver resolver = mContext.getContentResolver();
1732                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                        msg.arg1);
1734            } break;
1735            case GC_BACKGROUND_PROCESSES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    performAppGcsIfAppropriateLocked();
1738                }
1739            } break;
1740            case SERVICE_TIMEOUT_MSG: {
1741                if (mDidDexOpt) {
1742                    mDidDexOpt = false;
1743                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                    nmsg.obj = msg.obj;
1745                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                    return;
1747                }
1748                mServices.serviceTimeout((ProcessRecord)msg.obj);
1749            } break;
1750            case UPDATE_TIME_ZONE: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimeZone();
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763            } break;
1764            case CLEAR_DNS_CACHE_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.clearDnsCache();
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case UPDATE_HTTP_PROXY_MSG: {
1779                ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                String host = "";
1781                String port = "";
1782                String exclList = "";
1783                Uri pacFileUrl = Uri.EMPTY;
1784                if (proxy != null) {
1785                    host = proxy.getHost();
1786                    port = Integer.toString(proxy.getPort());
1787                    exclList = proxy.getExclusionListAsString();
1788                    pacFileUrl = proxy.getPacFileUrl();
1789                }
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update http proxy for: " +
1798                                        r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case PROC_START_TIMEOUT_MSG: {
1805                if (mDidDexOpt) {
1806                    mDidDexOpt = false;
1807                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                    nmsg.obj = msg.obj;
1809                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                    return;
1811                }
1812                ProcessRecord app = (ProcessRecord)msg.obj;
1813                synchronized (ActivityManagerService.this) {
1814                    processStartTimedOutLocked(app);
1815                }
1816            } break;
1817            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                ProcessRecord app = (ProcessRecord)msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    processContentProviderPublishTimedOutLocked(app);
1821                }
1822            } break;
1823            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                }
1827            } break;
1828            case KILL_APPLICATION_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    int appid = msg.arg1;
1831                    boolean restart = (msg.arg2 == 1);
1832                    Bundle bundle = (Bundle)msg.obj;
1833                    String pkg = bundle.getString("pkg");
1834                    String reason = bundle.getString("reason");
1835                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                            false, UserHandle.USER_ALL, reason);
1837                }
1838            } break;
1839            case FINALIZE_PENDING_INTENT_MSG: {
1840                ((PendingIntentRecord)msg.obj).completeFinalize();
1841            } break;
1842            case POST_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847
1848                ActivityRecord root = (ActivityRecord)msg.obj;
1849                ProcessRecord process = root.app;
1850                if (process == null) {
1851                    return;
1852                }
1853
1854                try {
1855                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                    String text = mContext.getString(R.string.heavy_weight_notification,
1857                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                    Notification notification = new Notification.Builder(context)
1859                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                            .setWhen(0)
1861                            .setOngoing(true)
1862                            .setTicker(text)
1863                            .setColor(mContext.getColor(
1864                                    com.android.internal.R.color.system_notification_accent_color))
1865                            .setContentTitle(text)
1866                            .setContentText(
1867                                    mContext.getText(R.string.heavy_weight_notification_detail))
1868                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                    new UserHandle(root.userId)))
1871                            .build();
1872                    try {
1873                        int[] outId = new int[1];
1874                        inm.enqueueNotificationWithTag("android", "android", null,
1875                                R.string.heavy_weight_notification,
1876                                notification, outId, root.userId);
1877                    } catch (RuntimeException e) {
1878                        Slog.w(ActivityManagerService.TAG,
1879                                "Error showing notification for heavy-weight app", e);
1880                    } catch (RemoteException e) {
1881                    }
1882                } catch (NameNotFoundException e) {
1883                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                }
1885            } break;
1886            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891                try {
1892                    inm.cancelNotificationWithTag("android", null,
1893                            R.string.heavy_weight_notification,  msg.arg1);
1894                } catch (RuntimeException e) {
1895                    Slog.w(ActivityManagerService.TAG,
1896                            "Error canceling notification for service", e);
1897                } catch (RemoteException e) {
1898                }
1899            } break;
1900            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    checkExcessivePowerUsageLocked(true);
1903                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                }
1907            } break;
1908            case REPORT_MEM_USAGE_MSG: {
1909                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                Thread thread = new Thread() {
1911                    @Override public void run() {
1912                        reportMemUsage(memInfos);
1913                    }
1914                };
1915                thread.start();
1916                break;
1917            }
1918            case REPORT_USER_SWITCH_MSG: {
1919                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case CONTINUE_USER_SWITCH_MSG: {
1923                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case USER_SWITCH_TIMEOUT_MSG: {
1927                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                break;
1929            }
1930            case IMMERSIVE_MODE_LOCK_MSG: {
1931                final boolean nextState = (msg.arg1 != 0);
1932                if (mUpdateLock.isHeld() != nextState) {
1933                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                            "Applying new update lock state '" + nextState
1935                            + "' for " + (ActivityRecord)msg.obj);
1936                    if (nextState) {
1937                        mUpdateLock.acquire();
1938                    } else {
1939                        mUpdateLock.release();
1940                    }
1941                }
1942                break;
1943            }
1944            case PERSIST_URI_GRANTS_MSG: {
1945                writeGrantedUriPermissions();
1946                break;
1947            }
1948            case REQUEST_ALL_PSS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                }
1952                break;
1953            }
1954            case START_PROFILES_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    mUserController.startProfilesLocked();
1957                }
1958                break;
1959            }
1960            case UPDATE_TIME: {
1961                synchronized (ActivityManagerService.this) {
1962                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                        ProcessRecord r = mLruProcesses.get(i);
1964                        if (r.thread != null) {
1965                            try {
1966                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                            } catch (RemoteException ex) {
1968                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                            }
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case SYSTEM_USER_START_MSG: {
1976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                        Integer.toString(msg.arg1), msg.arg1);
1978                mSystemServiceManager.startUser(msg.arg1);
1979                break;
1980            }
1981            case SYSTEM_USER_UNLOCK_MSG: {
1982                final int userId = msg.arg1;
1983                mSystemServiceManager.unlockUser(userId);
1984                synchronized (ActivityManagerService.this) {
1985                    mRecentTasks.loadUserRecentsLocked(userId);
1986                }
1987                if (userId == UserHandle.USER_SYSTEM) {
1988                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                }
1990                installEncryptionUnawareProviders(userId);
1991                mUserController.finishUserUnlocked((UserState) msg.obj);
1992                break;
1993            }
1994            case SYSTEM_USER_CURRENT_MSG: {
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                        Integer.toString(msg.arg2), msg.arg2);
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                        Integer.toString(msg.arg1), msg.arg1);
2001                mSystemServiceManager.switchUser(msg.arg1);
2002                break;
2003            }
2004            case ENTER_ANIMATION_COMPLETE_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                    if (r != null && r.app != null && r.app.thread != null) {
2008                        try {
2009                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                        } catch (RemoteException e) {
2011                        }
2012                    }
2013                }
2014                break;
2015            }
2016            case FINISH_BOOTING_MSG: {
2017                if (msg.arg1 != 0) {
2018                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                    finishBooting();
2020                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                }
2022                if (msg.arg2 != 0) {
2023                    enableScreenAfterBoot();
2024                }
2025                break;
2026            }
2027            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                try {
2029                    Locale l = (Locale) msg.obj;
2030                    IBinder service = ServiceManager.getService("mount");
2031                    IMountService mountService = IMountService.Stub.asInterface(service);
2032                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                } catch (RemoteException e) {
2035                    Log.e(TAG, "Error storing locale for decryption UI", e);
2036                }
2037                break;
2038            }
2039            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                        } catch (RemoteException e){
2060                            // Handled by the RemoteCallbackList
2061                        }
2062                    }
2063                    mTaskStackListeners.finishBroadcast();
2064                }
2065                break;
2066            }
2067            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                        try {
2071                            // Make a one-way callback to the listener
2072                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                        } catch (RemoteException e){
2074                            // Handled by the RemoteCallbackList
2075                        }
2076                    }
2077                    mTaskStackListeners.finishBroadcast();
2078                }
2079                break;
2080            }
2081            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                    (String) msg.obj, msg.arg1);
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                    synchronized (ActivityManagerService.this) {
2112                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                            try {
2114                                // Make a one-way callback to the listener
2115                                mTaskStackListeners.getBroadcastItem(i)
2116                                        .onActivityDismissingDockedStack();
2117                            } catch (RemoteException e){
2118                                // Handled by the RemoteCallbackList
2119                            }
2120                        }
2121                        mTaskStackListeners.finishBroadcast();
2122                    }
2123                    break;
2124                }
2125            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                final int uid = msg.arg1;
2127                final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                synchronized (mPidsSelfLocked) {
2130                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                        if (p.uid == uid) {
2133                            try {
2134                                p.thread.notifyCleartextNetwork(firstPacket);
2135                            } catch (RemoteException ignored) {
2136                            }
2137                        }
2138                    }
2139                }
2140                break;
2141            }
2142            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                final String procName;
2144                final int uid;
2145                final long memLimit;
2146                final String reportPackage;
2147                synchronized (ActivityManagerService.this) {
2148                    procName = mMemWatchDumpProcName;
2149                    uid = mMemWatchDumpUid;
2150                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                    if (val == null) {
2152                        val = mMemWatchProcesses.get(procName, 0);
2153                    }
2154                    if (val != null) {
2155                        memLimit = val.first;
2156                        reportPackage = val.second;
2157                    } else {
2158                        memLimit = 0;
2159                        reportPackage = null;
2160                    }
2161                }
2162                if (procName == null) {
2163                    return;
2164                }
2165
2166                if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                        "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                INotificationManager inm = NotificationManager.getService();
2170                if (inm == null) {
2171                    return;
2172                }
2173
2174                String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                Intent deleteIntent = new Intent();
2178                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                Intent intent = new Intent();
2180                intent.setClassName("android", DumpHeapActivity.class.getName());
2181                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                if (reportPackage != null) {
2184                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                }
2186                int userId = UserHandle.getUserId(uid);
2187                Notification notification = new Notification.Builder(mContext)
2188                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                        .setWhen(0)
2190                        .setOngoing(true)
2191                        .setAutoCancel(true)
2192                        .setTicker(text)
2193                        .setColor(mContext.getColor(
2194                                com.android.internal.R.color.system_notification_accent_color))
2195                        .setContentTitle(text)
2196                        .setContentText(
2197                                mContext.getText(R.string.dump_heap_notification_detail))
2198                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                new UserHandle(userId)))
2201                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                deleteIntent, 0, UserHandle.SYSTEM))
2203                        .build();
2204
2205                try {
2206                    int[] outId = new int[1];
2207                    inm.enqueueNotificationWithTag("android", "android", null,
2208                            R.string.dump_heap_notification,
2209                            notification, outId, userId);
2210                } catch (RuntimeException e) {
2211                    Slog.w(ActivityManagerService.TAG,
2212                            "Error showing notification for dump heap", e);
2213                } catch (RemoteException e) {
2214                }
2215            } break;
2216            case DELETE_DUMPHEAP_MSG: {
2217                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                        DumpHeapActivity.JAVA_URI,
2219                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                        UserHandle.myUserId());
2222                synchronized (ActivityManagerService.this) {
2223                    mMemWatchDumpFile = null;
2224                    mMemWatchDumpProcName = null;
2225                    mMemWatchDumpPid = -1;
2226                    mMemWatchDumpUid = -1;
2227                }
2228            } break;
2229            case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231            } break;
2232            case REPORT_TIME_TRACKER_MSG: {
2233                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                tracker.deliverResult(mContext);
2235            } break;
2236            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                mUserController.dispatchUserSwitchComplete(msg.arg1);
2238            } break;
2239            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                try {
2242                    connection.shutdown();
2243                } catch (RemoteException e) {
2244                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                }
2246                // Only a UiAutomation can set this flag and now that
2247                // it is finished we make sure it is reset to its default.
2248                mUserIsMonkey = false;
2249            } break;
2250            case APP_BOOST_DEACTIVATE_MSG: {
2251                synchronized(ActivityManagerService.this) {
2252                    if (mIsBoosted) {
2253                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                            nativeMigrateFromBoost();
2255                            mIsBoosted = false;
2256                            mBoostStartTime = 0;
2257                        } else {
2258                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                        }
2261                    }
2262                }
2263            } break;
2264            case IDLE_UIDS_MSG: {
2265                idleUids();
2266            } break;
2267            case LOG_STACK_STATE: {
2268                synchronized (ActivityManagerService.this) {
2269                    mStackSupervisor.logStackState();
2270                }
2271            } break;
2272            case VR_MODE_CHANGE_MSG: {
2273                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                    }
2288                }
2289                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290            } break;
2291            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                if (needsVrMode) {
2295                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2296                            r.info.getComponentName(), false);
2297                }
2298            } break;
2299            }
2300        }
2301    };
2302
2303    static final int COLLECT_PSS_BG_MSG = 1;
2304
2305    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306        @Override
2307        public void handleMessage(Message msg) {
2308            switch (msg.what) {
2309            case COLLECT_PSS_BG_MSG: {
2310                long start = SystemClock.uptimeMillis();
2311                MemInfoReader memInfo = null;
2312                synchronized (ActivityManagerService.this) {
2313                    if (mFullPssPending) {
2314                        mFullPssPending = false;
2315                        memInfo = new MemInfoReader();
2316                    }
2317                }
2318                if (memInfo != null) {
2319                    updateCpuStatsNow();
2320                    long nativeTotalPss = 0;
2321                    synchronized (mProcessCpuTracker) {
2322                        final int N = mProcessCpuTracker.countStats();
2323                        for (int j=0; j<N; j++) {
2324                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                // This is definitely an application process; skip it.
2327                                continue;
2328                            }
2329                            synchronized (mPidsSelfLocked) {
2330                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                    // This is one of our own processes; skip it.
2332                                    continue;
2333                                }
2334                            }
2335                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                        }
2337                    }
2338                    memInfo.readMemInfo();
2339                    synchronized (ActivityManagerService.this) {
2340                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                + (SystemClock.uptimeMillis()-start) + "ms");
2342                        final long cachedKb = memInfo.getCachedSizeKb();
2343                        final long freeKb = memInfo.getFreeSizeKb();
2344                        final long zramKb = memInfo.getZramTotalSizeKb();
2345                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                kernelKb*1024, nativeTotalPss*1024);
2348                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                nativeTotalPss);
2350                    }
2351                }
2352
2353                int num = 0;
2354                long[] tmp = new long[2];
2355                do {
2356                    ProcessRecord proc;
2357                    int procState;
2358                    int pid;
2359                    long lastPssTime;
2360                    synchronized (ActivityManagerService.this) {
2361                        if (mPendingPssProcesses.size() <= 0) {
2362                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                    "Collected PSS of " + num + " processes in "
2364                                    + (SystemClock.uptimeMillis() - start) + "ms");
2365                            mPendingPssProcesses.clear();
2366                            return;
2367                        }
2368                        proc = mPendingPssProcesses.remove(0);
2369                        procState = proc.pssProcState;
2370                        lastPssTime = proc.lastPssTime;
2371                        if (proc.thread != null && procState == proc.setProcState
2372                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                        < SystemClock.uptimeMillis()) {
2374                            pid = proc.pid;
2375                        } else {
2376                            proc = null;
2377                            pid = 0;
2378                        }
2379                    }
2380                    if (proc != null) {
2381                        long pss = Debug.getPss(pid, tmp, null);
2382                        synchronized (ActivityManagerService.this) {
2383                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                num++;
2386                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                        SystemClock.uptimeMillis());
2388                            }
2389                        }
2390                    }
2391                } while (true);
2392            }
2393            }
2394        }
2395    };
2396
2397    public void setSystemProcess() {
2398        try {
2399            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401            ServiceManager.addService("meminfo", new MemBinder(this));
2402            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403            ServiceManager.addService("dbinfo", new DbBinder(this));
2404            if (MONITOR_CPU_USAGE) {
2405                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406            }
2407            ServiceManager.addService("permission", new PermissionController(this));
2408            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414            synchronized (this) {
2415                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                app.persistent = true;
2417                app.pid = MY_PID;
2418                app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                synchronized (mPidsSelfLocked) {
2421                    mPidsSelfLocked.put(app.pid, app);
2422                }
2423                updateLruProcessLocked(app, false, null);
2424                updateOomAdjLocked();
2425            }
2426        } catch (PackageManager.NameNotFoundException e) {
2427            throw new RuntimeException(
2428                    "Unable to find android system package", e);
2429        }
2430    }
2431
2432    public void setWindowManager(WindowManagerService wm) {
2433        mWindowManager = wm;
2434        mStackSupervisor.setWindowManager(wm);
2435        mActivityStarter.setWindowManager(wm);
2436    }
2437
2438    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439        mUsageStatsService = usageStatsManager;
2440    }
2441
2442    public void startObservingNativeCrashes() {
2443        final NativeCrashListener ncl = new NativeCrashListener(this);
2444        ncl.start();
2445    }
2446
2447    public IAppOpsService getAppOpsService() {
2448        return mAppOpsService;
2449    }
2450
2451    static class MemBinder extends Binder {
2452        ActivityManagerService mActivityManagerService;
2453        MemBinder(ActivityManagerService activityManagerService) {
2454            mActivityManagerService = activityManagerService;
2455        }
2456
2457        @Override
2458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                    != PackageManager.PERMISSION_GRANTED) {
2461                pw.println("Permission Denial: can't dump meminfo from from pid="
2462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                        + " without permission " + android.Manifest.permission.DUMP);
2464                return;
2465            }
2466
2467            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468        }
2469    }
2470
2471    static class GraphicsBinder extends Binder {
2472        ActivityManagerService mActivityManagerService;
2473        GraphicsBinder(ActivityManagerService activityManagerService) {
2474            mActivityManagerService = activityManagerService;
2475        }
2476
2477        @Override
2478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                    != PackageManager.PERMISSION_GRANTED) {
2481                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                        + " without permission " + android.Manifest.permission.DUMP);
2484                return;
2485            }
2486
2487            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488        }
2489    }
2490
2491    static class DbBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        DbBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpDbInfo(fd, pw, args);
2508        }
2509    }
2510
2511    static class CpuBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        CpuBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                        SystemClock.uptimeMillis()));
2531            }
2532        }
2533    }
2534
2535    public static final class Lifecycle extends SystemService {
2536        private final ActivityManagerService mService;
2537
2538        public Lifecycle(Context context) {
2539            super(context);
2540            mService = new ActivityManagerService(context);
2541        }
2542
2543        @Override
2544        public void onStart() {
2545            mService.start();
2546        }
2547
2548        public ActivityManagerService getService() {
2549            return mService;
2550        }
2551    }
2552
2553    // Note: This method is invoked on the main thread but may need to attach various
2554    // handlers to other threads.  So take care to be explicit about the looper.
2555    public ActivityManagerService(Context systemContext) {
2556        mContext = systemContext;
2557        mFactoryTest = FactoryTest.getMode();
2558        mSystemThread = ActivityThread.currentActivityThread();
2559
2560        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562        mHandlerThread = new ServiceThread(TAG,
2563                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564        mHandlerThread.start();
2565        mHandler = new MainHandler(mHandlerThread.getLooper());
2566        mUiHandler = new UiHandler();
2567
2568        /* static; one-time init here */
2569        if (sKillHandler == null) {
2570            sKillThread = new ServiceThread(TAG + ":kill",
2571                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572            sKillThread.start();
2573            sKillHandler = new KillHandler(sKillThread.getLooper());
2574        }
2575
2576        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "foreground", BROADCAST_FG_TIMEOUT, false);
2578        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "background", BROADCAST_BG_TIMEOUT, true);
2580        mBroadcastQueues[0] = mFgBroadcastQueue;
2581        mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583        mServices = new ActiveServices(this);
2584        mProviderMap = new ProviderMap(this);
2585        mAppErrors = new AppErrors(mContext, this);
2586
2587        // TODO: Move creation of battery stats service outside of activity manager service.
2588        File dataDir = Environment.getDataDirectory();
2589        File systemDir = new File(dataDir, "system");
2590        systemDir.mkdirs();
2591        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592        mBatteryStatsService.getActiveStatistics().readLocked();
2593        mBatteryStatsService.scheduleWriteToDisk();
2594        mOnBattery = DEBUG_POWER ? true
2595                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596        mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                new IAppOpsCallback.Stub() {
2603                    @Override public void opChanged(int op, int uid, String packageName) {
2604                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                            if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                    != AppOpsManager.MODE_ALLOWED) {
2607                                runInBackgroundDisabled(uid);
2608                            }
2609                        }
2610                    }
2611                });
2612
2613        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615        mUserController = new UserController(this);
2616
2617        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mConfiguration.setToDefaults();
2623        mConfiguration.setLocales(LocaleList.getDefault());
2624
2625        mConfigurationSeq = mConfiguration.seq = 1;
2626        mProcessCpuTracker.init();
2627
2628        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630        mStackSupervisor = new ActivityStackSupervisor(this);
2631        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634        mProcessCpuThread = new Thread("CpuTracker") {
2635            @Override
2636            public void run() {
2637                while (true) {
2638                    try {
2639                        try {
2640                            synchronized(this) {
2641                                final long now = SystemClock.uptimeMillis();
2642                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                //        + ", write delay=" + nextWriteDelay);
2646                                if (nextWriteDelay < nextCpuDelay) {
2647                                    nextCpuDelay = nextWriteDelay;
2648                                }
2649                                if (nextCpuDelay > 0) {
2650                                    mProcessCpuMutexFree.set(true);
2651                                    this.wait(nextCpuDelay);
2652                                }
2653                            }
2654                        } catch (InterruptedException e) {
2655                        }
2656                        updateCpuStatsNow();
2657                    } catch (Exception e) {
2658                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                    }
2660                }
2661            }
2662        };
2663
2664        Watchdog.getInstance().addMonitor(this);
2665        Watchdog.getInstance().addThread(mHandler);
2666    }
2667
2668    public void setSystemServiceManager(SystemServiceManager mgr) {
2669        mSystemServiceManager = mgr;
2670    }
2671
2672    public void setInstaller(Installer installer) {
2673        mInstaller = installer;
2674    }
2675
2676    private void start() {
2677        Process.removeAllProcessGroups();
2678        mProcessCpuThread.start();
2679
2680        mBatteryStatsService.publish(mContext);
2681        mAppOpsService.publish(mContext);
2682        Slog.d("AppOps", "AppOpsService published");
2683        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684    }
2685
2686    void onUserStoppedLocked(int userId) {
2687        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688    }
2689
2690    public void initPowerManagement() {
2691        mStackSupervisor.initPowerManagement();
2692        mBatteryStatsService.initPowerManagement();
2693        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696        mVoiceWakeLock.setReferenceCounted(false);
2697    }
2698
2699    @Override
2700    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701            throws RemoteException {
2702        if (code == SYSPROPS_TRANSACTION) {
2703            // We need to tell all apps about the system property change.
2704            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705            synchronized(this) {
2706                final int NP = mProcessNames.getMap().size();
2707                for (int ip=0; ip<NP; ip++) {
2708                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                    final int NA = apps.size();
2710                    for (int ia=0; ia<NA; ia++) {
2711                        ProcessRecord app = apps.valueAt(ia);
2712                        if (app.thread != null) {
2713                            procs.add(app.thread.asBinder());
2714                        }
2715                    }
2716                }
2717            }
2718
2719            int N = procs.size();
2720            for (int i=0; i<N; i++) {
2721                Parcel data2 = Parcel.obtain();
2722                try {
2723                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                } catch (RemoteException e) {
2725                }
2726                data2.recycle();
2727            }
2728        }
2729        try {
2730            return super.onTransact(code, data, reply, flags);
2731        } catch (RuntimeException e) {
2732            // The activity manager only throws security exceptions, so let's
2733            // log all others.
2734            if (!(e instanceof SecurityException)) {
2735                Slog.wtf(TAG, "Activity Manager Crash", e);
2736            }
2737            throw e;
2738        }
2739    }
2740
2741    void updateCpuStats() {
2742        final long now = SystemClock.uptimeMillis();
2743        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744            return;
2745        }
2746        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747            synchronized (mProcessCpuThread) {
2748                mProcessCpuThread.notify();
2749            }
2750        }
2751    }
2752
2753    void updateCpuStatsNow() {
2754        synchronized (mProcessCpuTracker) {
2755            mProcessCpuMutexFree.set(false);
2756            final long now = SystemClock.uptimeMillis();
2757            boolean haveNewCpuStats = false;
2758
2759            if (MONITOR_CPU_USAGE &&
2760                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                mLastCpuTime.set(now);
2762                mProcessCpuTracker.update();
2763                if (mProcessCpuTracker.hasGoodLastStats()) {
2764                    haveNewCpuStats = true;
2765                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                    //Slog.i(TAG, "Total CPU usage: "
2767                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                    // Slog the cpu usage if the property is set.
2770                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                        int user = mProcessCpuTracker.getLastUserTime();
2772                        int system = mProcessCpuTracker.getLastSystemTime();
2773                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                        int irq = mProcessCpuTracker.getLastIrqTime();
2775                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                        int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                        int total = user + system + iowait + irq + softIrq + idle;
2779                        if (total == 0) total = 1;
2780
2781                        EventLog.writeEvent(EventLogTags.CPU,
2782                                ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                (user * 100) / total,
2784                                (system * 100) / total,
2785                                (iowait * 100) / total,
2786                                (irq * 100) / total,
2787                                (softIrq * 100) / total);
2788                    }
2789                }
2790            }
2791
2792            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793            synchronized(bstats) {
2794                synchronized(mPidsSelfLocked) {
2795                    if (haveNewCpuStats) {
2796                        if (bstats.startAddingCpuLocked()) {
2797                            int totalUTime = 0;
2798                            int totalSTime = 0;
2799                            final int N = mProcessCpuTracker.countStats();
2800                            for (int i=0; i<N; i++) {
2801                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                if (!st.working) {
2803                                    continue;
2804                                }
2805                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                totalUTime += st.rel_utime;
2807                                totalSTime += st.rel_stime;
2808                                if (pr != null) {
2809                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                    if (ps == null || !ps.isActive()) {
2811                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                pr.info.uid, pr.processName);
2813                                    }
2814                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                } else {
2817                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                    if (ps == null || !ps.isActive()) {
2819                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                bstats.mapUid(st.uid), st.name);
2821                                    }
2822                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                }
2824                            }
2825                            final int userTime = mProcessCpuTracker.getLastUserTime();
2826                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                        }
2834                    }
2835                }
2836
2837                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                    mLastWriteTime = now;
2839                    mBatteryStatsService.scheduleWriteToDisk();
2840                }
2841            }
2842        }
2843    }
2844
2845    @Override
2846    public void batteryNeedsCpuUpdate() {
2847        updateCpuStatsNow();
2848    }
2849
2850    @Override
2851    public void batteryPowerChanged(boolean onBattery) {
2852        // When plugging in, update the CPU stats first before changing
2853        // the plug state.
2854        updateCpuStatsNow();
2855        synchronized (this) {
2856            synchronized(mPidsSelfLocked) {
2857                mOnBattery = DEBUG_POWER ? true : onBattery;
2858            }
2859        }
2860    }
2861
2862    @Override
2863    public void batterySendBroadcast(Intent intent) {
2864        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                AppOpsManager.OP_NONE, null, false, false,
2866                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867    }
2868
2869    /**
2870     * Initialize the application bind args. These are passed to each
2871     * process when the bindApplication() IPC is sent to the process. They're
2872     * lazily setup to make sure the services are running when they're asked for.
2873     */
2874    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875        if (mAppBindArgs == null) {
2876            mAppBindArgs = new HashMap<>();
2877
2878            // Isolated processes won't get this optimization, so that we don't
2879            // violate the rules about which services they have access to.
2880            if (!isolated) {
2881                // Setup the application init args
2882                mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                mAppBindArgs.put(Context.ALARM_SERVICE,
2885                        ServiceManager.getService(Context.ALARM_SERVICE));
2886            }
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892        if (r == null || mFocusedActivity == r) {
2893            return false;
2894        }
2895
2896        if (!r.isFocusable()) {
2897            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898            return false;
2899        }
2900
2901        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906        mDoingSetFocusedActivity = true;
2907
2908        final ActivityRecord last = mFocusedActivity;
2909        mFocusedActivity = r;
2910        if (r.task.isApplicationTask()) {
2911            if (mCurAppTimeTracker != r.appTimeTracker) {
2912                // We are switching app tracking.  Complete the current one.
2913                if (mCurAppTimeTracker != null) {
2914                    mCurAppTimeTracker.stop();
2915                    mHandler.obtainMessage(
2916                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                    mCurAppTimeTracker = null;
2919                }
2920                if (r.appTimeTracker != null) {
2921                    mCurAppTimeTracker = r.appTimeTracker;
2922                    startTimeTrackingFocusedActivityLocked();
2923                }
2924            } else {
2925                startTimeTrackingFocusedActivityLocked();
2926            }
2927        } else {
2928            r.appTimeTracker = null;
2929        }
2930        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931        // TODO: Probably not, because we don't want to resume voice on switching
2932        // back to this activity
2933        if (r.task.voiceInteractor != null) {
2934            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935        } else {
2936            finishRunningVoiceLocked();
2937            IVoiceInteractionSession session;
2938            if (last != null && ((session = last.task.voiceSession) != null
2939                    || (session = last.voiceSession) != null)) {
2940                // We had been in a voice interaction session, but now focused has
2941                // move to something different.  Just finish the session, we can't
2942                // return to it and retain the proper state and synchronization with
2943                // the voice interaction service.
2944                finishVoiceTask(session);
2945            }
2946        }
2947        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948            mWindowManager.setFocusedApp(r.appToken, true);
2949        }
2950        applyUpdateLockStateLocked(r);
2951        applyUpdateVrModeLocked(r);
2952        if (mFocusedActivity.userId != mLastFocusedUserId) {
2953            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954            mHandler.obtainMessage(
2955                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956            mLastFocusedUserId = mFocusedActivity.userId;
2957        }
2958
2959        // Log a warning if the focused app is changed during the process. This could
2960        // indicate a problem of the focus setting logic!
2961        if (mFocusedActivity != r) Slog.w(TAG,
2962                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965        EventLogTags.writeAmFocusedActivity(
2966                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                reason);
2969        return true;
2970    }
2971
2972    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973        if (mFocusedActivity != goingAway) {
2974            return;
2975        }
2976
2977        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978        if (focusedStack != null) {
2979            final ActivityRecord top = focusedStack.topActivity();
2980            if (top != null && top.userId != mLastFocusedUserId) {
2981                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                mHandler.sendMessage(
2983                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                mLastFocusedUserId = top.userId;
2985            }
2986        }
2987
2988        // Try to move focus to another activity if possible.
2989        if (setFocusedActivityLocked(
2990                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991            return;
2992        }
2993
2994        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996        mFocusedActivity = null;
2997        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998    }
2999
3000    @Override
3001    public void setFocusedStack(int stackId) {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004        final long callingId = Binder.clearCallingIdentity();
3005        try {
3006            synchronized (this) {
3007                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                if (stack == null) {
3009                    return;
3010                }
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                }
3015            }
3016        } finally {
3017            Binder.restoreCallingIdentity(callingId);
3018        }
3019    }
3020
3021    @Override
3022    public void setFocusedTask(int taskId) {
3023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025        final long callingId = Binder.clearCallingIdentity();
3026        try {
3027            synchronized (this) {
3028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                if (task == null) {
3030                    return;
3031                }
3032                final ActivityRecord r = task.topRunningActivityLocked();
3033                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                }
3036            }
3037        } finally {
3038            Binder.restoreCallingIdentity(callingId);
3039        }
3040    }
3041
3042    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043    @Override
3044    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046        synchronized (this) {
3047            if (listener != null) {
3048                mTaskStackListeners.register(listener);
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.task.stack.notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082    }
3083
3084    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3085            ComponentName callingPackage, boolean immediate) {
3086        VrManagerInternal vrService =
3087                LocalServices.getService(VrManagerInternal.class);
3088        if (immediate) {
3089            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3090        } else {
3091            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3092        }
3093    }
3094
3095    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3096        Message msg = Message.obtain();
3097        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3098        msg.obj = r.task.askedCompatMode ? null : r;
3099        mUiHandler.sendMessage(msg);
3100    }
3101
3102    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3103            String what, Object obj, ProcessRecord srcApp) {
3104        app.lastActivityTime = now;
3105
3106        if (app.activities.size() > 0) {
3107            // Don't want to touch dependent processes that are hosting activities.
3108            return index;
3109        }
3110
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui < 0) {
3113            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3114                    + what + " " + obj + " from " + srcApp);
3115            return index;
3116        }
3117
3118        if (lrui >= index) {
3119            // Don't want to cause this to move dependent processes *back* in the
3120            // list as if they were less frequently used.
3121            return index;
3122        }
3123
3124        if (lrui >= mLruProcessActivityStart) {
3125            // Don't want to touch dependent processes that are hosting activities.
3126            return index;
3127        }
3128
3129        mLruProcesses.remove(lrui);
3130        if (index > 0) {
3131            index--;
3132        }
3133        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3134                + " in LRU list: " + app);
3135        mLruProcesses.add(index, app);
3136        return index;
3137    }
3138
3139    static void killProcessGroup(int uid, int pid) {
3140        if (sKillHandler != null) {
3141            sKillHandler.sendMessage(
3142                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3143        } else {
3144            Slog.w(TAG, "Asked to kill process group before system bringup!");
3145            Process.killProcessGroup(uid, pid);
3146        }
3147    }
3148
3149    final void removeLruProcessLocked(ProcessRecord app) {
3150        int lrui = mLruProcesses.lastIndexOf(app);
3151        if (lrui >= 0) {
3152            if (!app.killed) {
3153                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3154                Process.killProcessQuiet(app.pid);
3155                killProcessGroup(app.uid, app.pid);
3156            }
3157            if (lrui <= mLruProcessActivityStart) {
3158                mLruProcessActivityStart--;
3159            }
3160            if (lrui <= mLruProcessServiceStart) {
3161                mLruProcessServiceStart--;
3162            }
3163            mLruProcesses.remove(lrui);
3164        }
3165    }
3166
3167    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3168            ProcessRecord client) {
3169        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3170                || app.treatLikeActivity;
3171        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3172        if (!activityChange && hasActivity) {
3173            // The process has activities, so we are only allowing activity-based adjustments
3174            // to move it.  It should be kept in the front of the list with other
3175            // processes that have activities, and we don't want those to change their
3176            // order except due to activity operations.
3177            return;
3178        }
3179
3180        mLruSeq++;
3181        final long now = SystemClock.uptimeMillis();
3182        app.lastActivityTime = now;
3183
3184        // First a quick reject: if the app is already at the position we will
3185        // put it, then there is nothing to do.
3186        if (hasActivity) {
3187            final int N = mLruProcesses.size();
3188            if (N > 0 && mLruProcesses.get(N-1) == app) {
3189                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3190                return;
3191            }
3192        } else {
3193            if (mLruProcessServiceStart > 0
3194                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3195                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3196                return;
3197            }
3198        }
3199
3200        int lrui = mLruProcesses.lastIndexOf(app);
3201
3202        if (app.persistent && lrui >= 0) {
3203            // We don't care about the position of persistent processes, as long as
3204            // they are in the list.
3205            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3206            return;
3207        }
3208
3209        /* In progress: compute new position first, so we can avoid doing work
3210           if the process is not actually going to move.  Not yet working.
3211        int addIndex;
3212        int nextIndex;
3213        boolean inActivity = false, inService = false;
3214        if (hasActivity) {
3215            // Process has activities, put it at the very tipsy-top.
3216            addIndex = mLruProcesses.size();
3217            nextIndex = mLruProcessServiceStart;
3218            inActivity = true;
3219        } else if (hasService) {
3220            // Process has services, put it at the top of the service list.
3221            addIndex = mLruProcessActivityStart;
3222            nextIndex = mLruProcessServiceStart;
3223            inActivity = true;
3224            inService = true;
3225        } else  {
3226            // Process not otherwise of interest, it goes to the top of the non-service area.
3227            addIndex = mLruProcessServiceStart;
3228            if (client != null) {
3229                int clientIndex = mLruProcesses.lastIndexOf(client);
3230                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3231                        + app);
3232                if (clientIndex >= 0 && addIndex > clientIndex) {
3233                    addIndex = clientIndex;
3234                }
3235            }
3236            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3237        }
3238
3239        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3240                + mLruProcessActivityStart + "): " + app);
3241        */
3242
3243        if (lrui >= 0) {
3244            if (lrui < mLruProcessActivityStart) {
3245                mLruProcessActivityStart--;
3246            }
3247            if (lrui < mLruProcessServiceStart) {
3248                mLruProcessServiceStart--;
3249            }
3250            /*
3251            if (addIndex > lrui) {
3252                addIndex--;
3253            }
3254            if (nextIndex > lrui) {
3255                nextIndex--;
3256            }
3257            */
3258            mLruProcesses.remove(lrui);
3259        }
3260
3261        /*
3262        mLruProcesses.add(addIndex, app);
3263        if (inActivity) {
3264            mLruProcessActivityStart++;
3265        }
3266        if (inService) {
3267            mLruProcessActivityStart++;
3268        }
3269        */
3270
3271        int nextIndex;
3272        if (hasActivity) {
3273            final int N = mLruProcesses.size();
3274            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3275                // Process doesn't have activities, but has clients with
3276                // activities...  move it up, but one below the top (the top
3277                // should always have a real activity).
3278                if (DEBUG_LRU) Slog.d(TAG_LRU,
3279                        "Adding to second-top of LRU activity list: " + app);
3280                mLruProcesses.add(N - 1, app);
3281                // To keep it from spamming the LRU list (by making a bunch of clients),
3282                // we will push down any other entries owned by the app.
3283                final int uid = app.info.uid;
3284                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3285                    ProcessRecord subProc = mLruProcesses.get(i);
3286                    if (subProc.info.uid == uid) {
3287                        // We want to push this one down the list.  If the process after
3288                        // it is for the same uid, however, don't do so, because we don't
3289                        // want them internally to be re-ordered.
3290                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3291                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3292                                    "Pushing uid " + uid + " swapping at " + i + ": "
3293                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3294                            ProcessRecord tmp = mLruProcesses.get(i);
3295                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3296                            mLruProcesses.set(i - 1, tmp);
3297                            i--;
3298                        }
3299                    } else {
3300                        // A gap, we can stop here.
3301                        break;
3302                    }
3303                }
3304            } else {
3305                // Process has activities, put it at the very tipsy-top.
3306                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3307                mLruProcesses.add(app);
3308            }
3309            nextIndex = mLruProcessServiceStart;
3310        } else if (hasService) {
3311            // Process has services, put it at the top of the service list.
3312            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3313            mLruProcesses.add(mLruProcessActivityStart, app);
3314            nextIndex = mLruProcessServiceStart;
3315            mLruProcessActivityStart++;
3316        } else  {
3317            // Process not otherwise of interest, it goes to the top of the non-service area.
3318            int index = mLruProcessServiceStart;
3319            if (client != null) {
3320                // If there is a client, don't allow the process to be moved up higher
3321                // in the list than that client.
3322                int clientIndex = mLruProcesses.lastIndexOf(client);
3323                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3324                        + " when updating " + app);
3325                if (clientIndex <= lrui) {
3326                    // Don't allow the client index restriction to push it down farther in the
3327                    // list than it already is.
3328                    clientIndex = lrui;
3329                }
3330                if (clientIndex >= 0 && index > clientIndex) {
3331                    index = clientIndex;
3332                }
3333            }
3334            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3335            mLruProcesses.add(index, app);
3336            nextIndex = index-1;
3337            mLruProcessActivityStart++;
3338            mLruProcessServiceStart++;
3339        }
3340
3341        // If the app is currently using a content provider or service,
3342        // bump those processes as well.
3343        for (int j=app.connections.size()-1; j>=0; j--) {
3344            ConnectionRecord cr = app.connections.valueAt(j);
3345            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3346                    && cr.binding.service.app != null
3347                    && cr.binding.service.app.lruSeq != mLruSeq
3348                    && !cr.binding.service.app.persistent) {
3349                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3350                        "service connection", cr, app);
3351            }
3352        }
3353        for (int j=app.conProviders.size()-1; j>=0; j--) {
3354            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3355            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3356                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3357                        "provider reference", cpr, app);
3358            }
3359        }
3360    }
3361
3362    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3363        if (uid == Process.SYSTEM_UID) {
3364            // The system gets to run in any process.  If there are multiple
3365            // processes with the same uid, just pick the first (this
3366            // should never happen).
3367            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3368            if (procs == null) return null;
3369            final int procCount = procs.size();
3370            for (int i = 0; i < procCount; i++) {
3371                final int procUid = procs.keyAt(i);
3372                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3373                    // Don't use an app process or different user process for system component.
3374                    continue;
3375                }
3376                return procs.valueAt(i);
3377            }
3378        }
3379        ProcessRecord proc = mProcessNames.get(processName, uid);
3380        if (false && proc != null && !keepIfLarge
3381                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3382                && proc.lastCachedPss >= 4000) {
3383            // Turn this condition on to cause killing to happen regularly, for testing.
3384            if (proc.baseProcessTracker != null) {
3385                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3386            }
3387            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3388        } else if (proc != null && !keepIfLarge
3389                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3390                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3391            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3392            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3393                if (proc.baseProcessTracker != null) {
3394                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3395                }
3396                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3397            }
3398        }
3399        return proc;
3400    }
3401
3402    void notifyPackageUse(String packageName, int reason) {
3403        IPackageManager pm = AppGlobals.getPackageManager();
3404        try {
3405            pm.notifyPackageUse(packageName, reason);
3406        } catch (RemoteException e) {
3407        }
3408    }
3409
3410    boolean isNextTransitionForward() {
3411        int transit = mWindowManager.getPendingAppTransition();
3412        return transit == TRANSIT_ACTIVITY_OPEN
3413                || transit == TRANSIT_TASK_OPEN
3414                || transit == TRANSIT_TASK_TO_FRONT;
3415    }
3416
3417    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3418            String processName, String abiOverride, int uid, Runnable crashHandler) {
3419        synchronized(this) {
3420            ApplicationInfo info = new ApplicationInfo();
3421            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3422            // For isolated processes, the former contains the parent's uid and the latter the
3423            // actual uid of the isolated process.
3424            // In the special case introduced by this method (which is, starting an isolated
3425            // process directly from the SystemServer without an actual parent app process) the
3426            // closest thing to a parent's uid is SYSTEM_UID.
3427            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3428            // the |isolated| logic in the ProcessRecord constructor.
3429            info.uid = Process.SYSTEM_UID;
3430            info.processName = processName;
3431            info.className = entryPoint;
3432            info.packageName = "android";
3433            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3434                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3435                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3436                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3437                    crashHandler);
3438            return proc != null ? proc.pid : 0;
3439        }
3440    }
3441
3442    final ProcessRecord startProcessLocked(String processName,
3443            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3444            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3445            boolean isolated, boolean keepIfLarge) {
3446        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3447                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3448                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3449                null /* crashHandler */);
3450    }
3451
3452    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3453            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3454            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3455            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3456        long startTime = SystemClock.elapsedRealtime();
3457        ProcessRecord app;
3458        if (!isolated) {
3459            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3460            checkTime(startTime, "startProcess: after getProcessRecord");
3461
3462            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3463                // If we are in the background, then check to see if this process
3464                // is bad.  If so, we will just silently fail.
3465                if (mAppErrors.isBadProcessLocked(info)) {
3466                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3467                            + "/" + info.processName);
3468                    return null;
3469                }
3470            } else {
3471                // When the user is explicitly starting a process, then clear its
3472                // crash count so that we won't make it bad until they see at
3473                // least one crash dialog again, and make the process good again
3474                // if it had been bad.
3475                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3476                        + "/" + info.processName);
3477                mAppErrors.resetProcessCrashTimeLocked(info);
3478                if (mAppErrors.isBadProcessLocked(info)) {
3479                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3480                            UserHandle.getUserId(info.uid), info.uid,
3481                            info.processName);
3482                    mAppErrors.clearBadProcessLocked(info);
3483                    if (app != null) {
3484                        app.bad = false;
3485                    }
3486                }
3487            }
3488        } else {
3489            // If this is an isolated process, it can't re-use an existing process.
3490            app = null;
3491        }
3492
3493        // app launch boost for big.little configurations
3494        // use cpusets to migrate freshly launched tasks to big cores
3495        nativeMigrateToBoost();
3496        mIsBoosted = true;
3497        mBoostStartTime = SystemClock.uptimeMillis();
3498        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3499        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3500
3501        // We don't have to do anything more if:
3502        // (1) There is an existing application record; and
3503        // (2) The caller doesn't think it is dead, OR there is no thread
3504        //     object attached to it so we know it couldn't have crashed; and
3505        // (3) There is a pid assigned to it, so it is either starting or
3506        //     already running.
3507        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3508                + " app=" + app + " knownToBeDead=" + knownToBeDead
3509                + " thread=" + (app != null ? app.thread : null)
3510                + " pid=" + (app != null ? app.pid : -1));
3511        if (app != null && app.pid > 0) {
3512            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3513                // We already have the app running, or are waiting for it to
3514                // come up (we have a pid but not yet its thread), so keep it.
3515                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3516                // If this is a new package in the process, add the package to the list
3517                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3518                checkTime(startTime, "startProcess: done, added package to proc");
3519                return app;
3520            }
3521
3522            // An application record is attached to a previous process,
3523            // clean it up now.
3524            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3525            checkTime(startTime, "startProcess: bad proc running, killing");
3526            killProcessGroup(app.uid, app.pid);
3527            handleAppDiedLocked(app, true, true);
3528            checkTime(startTime, "startProcess: done killing old proc");
3529        }
3530
3531        String hostingNameStr = hostingName != null
3532                ? hostingName.flattenToShortString() : null;
3533
3534        if (app == null) {
3535            checkTime(startTime, "startProcess: creating new process record");
3536            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3537            if (app == null) {
3538                Slog.w(TAG, "Failed making new process record for "
3539                        + processName + "/" + info.uid + " isolated=" + isolated);
3540                return null;
3541            }
3542            app.crashHandler = crashHandler;
3543            checkTime(startTime, "startProcess: done creating new process record");
3544        } else {
3545            // If this is a new package in the process, add the package to the list
3546            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3547            checkTime(startTime, "startProcess: added package to existing proc");
3548        }
3549
3550        // If the system is not ready yet, then hold off on starting this
3551        // process until it is.
3552        if (!mProcessesReady
3553                && !isAllowedWhileBooting(info)
3554                && !allowWhileBooting) {
3555            if (!mProcessesOnHold.contains(app)) {
3556                mProcessesOnHold.add(app);
3557            }
3558            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3559                    "System not ready, putting on hold: " + app);
3560            checkTime(startTime, "startProcess: returning with proc on hold");
3561            return app;
3562        }
3563
3564        checkTime(startTime, "startProcess: stepping in to startProcess");
3565        startProcessLocked(
3566                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3567        checkTime(startTime, "startProcess: done starting proc!");
3568        return (app.pid != 0) ? app : null;
3569    }
3570
3571    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3572        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3573    }
3574
3575    private final void startProcessLocked(ProcessRecord app,
3576            String hostingType, String hostingNameStr) {
3577        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3578                null /* entryPoint */, null /* entryPointArgs */);
3579    }
3580
3581    private final void startProcessLocked(ProcessRecord app, String hostingType,
3582            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3583        long startTime = SystemClock.elapsedRealtime();
3584        if (app.pid > 0 && app.pid != MY_PID) {
3585            checkTime(startTime, "startProcess: removing from pids map");
3586            synchronized (mPidsSelfLocked) {
3587                mPidsSelfLocked.remove(app.pid);
3588                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3589            }
3590            checkTime(startTime, "startProcess: done removing from pids map");
3591            app.setPid(0);
3592        }
3593
3594        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3595                "startProcessLocked removing on hold: " + app);
3596        mProcessesOnHold.remove(app);
3597
3598        checkTime(startTime, "startProcess: starting to update cpu stats");
3599        updateCpuStats();
3600        checkTime(startTime, "startProcess: done updating cpu stats");
3601
3602        try {
3603            try {
3604                final int userId = UserHandle.getUserId(app.uid);
3605                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3606            } catch (RemoteException e) {
3607                throw e.rethrowAsRuntimeException();
3608            }
3609
3610            int uid = app.uid;
3611            int[] gids = null;
3612            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3613            if (!app.isolated) {
3614                int[] permGids = null;
3615                try {
3616                    checkTime(startTime, "startProcess: getting gids from package manager");
3617                    final IPackageManager pm = AppGlobals.getPackageManager();
3618                    permGids = pm.getPackageGids(app.info.packageName,
3619                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3620                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3621                            MountServiceInternal.class);
3622                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3623                            app.info.packageName);
3624                } catch (RemoteException e) {
3625                    throw e.rethrowAsRuntimeException();
3626                }
3627
3628                /*
3629                 * Add shared application and profile GIDs so applications can share some
3630                 * resources like shared libraries and access user-wide resources
3631                 */
3632                if (ArrayUtils.isEmpty(permGids)) {
3633                    gids = new int[2];
3634                } else {
3635                    gids = new int[permGids.length + 2];
3636                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3637                }
3638                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3639                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3640            }
3641            checkTime(startTime, "startProcess: building args");
3642            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3643                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3644                        && mTopComponent != null
3645                        && app.processName.equals(mTopComponent.getPackageName())) {
3646                    uid = 0;
3647                }
3648                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3649                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3650                    uid = 0;
3651                }
3652            }
3653            int debugFlags = 0;
3654            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3655                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3656                // Also turn on CheckJNI for debuggable apps. It's quite
3657                // awkward to turn on otherwise.
3658                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3659            }
3660            // Run the app in safe mode if its manifest requests so or the
3661            // system is booted in safe mode.
3662            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3663                mSafeMode == true) {
3664                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3665            }
3666            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3667                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3668            }
3669            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3670            if ("true".equals(genDebugInfoProperty)) {
3671                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3672            }
3673            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3674                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3675            }
3676            if ("1".equals(SystemProperties.get("debug.assert"))) {
3677                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3678            }
3679            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3680                // Enable all debug flags required by the native debugger.
3681                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3682                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3683                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3684                mNativeDebuggingApp = null;
3685            }
3686
3687            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3688            if (requiredAbi == null) {
3689                requiredAbi = Build.SUPPORTED_ABIS[0];
3690            }
3691
3692            String instructionSet = null;
3693            if (app.info.primaryCpuAbi != null) {
3694                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3695            }
3696
3697            app.gids = gids;
3698            app.requiredAbi = requiredAbi;
3699            app.instructionSet = instructionSet;
3700
3701            // Start the process.  It will either succeed and return a result containing
3702            // the PID of the new process, or else throw a RuntimeException.
3703            boolean isActivityProcess = (entryPoint == null);
3704            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3705            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3706                    app.processName);
3707            checkTime(startTime, "startProcess: asking zygote to start proc");
3708            Process.ProcessStartResult startResult = Process.start(entryPoint,
3709                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3710                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3711                    app.info.dataDir, entryPointArgs);
3712            checkTime(startTime, "startProcess: returned from zygote!");
3713            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3714
3715            if (app.isolated) {
3716                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3717            }
3718            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3719            checkTime(startTime, "startProcess: done updating battery stats");
3720
3721            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3722                    UserHandle.getUserId(uid), startResult.pid, uid,
3723                    app.processName, hostingType,
3724                    hostingNameStr != null ? hostingNameStr : "");
3725
3726            try {
3727                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3728                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3729            } catch (RemoteException ex) {
3730                // Ignore
3731            }
3732
3733            if (app.persistent) {
3734                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3735            }
3736
3737            checkTime(startTime, "startProcess: building log message");
3738            StringBuilder buf = mStringBuilder;
3739            buf.setLength(0);
3740            buf.append("Start proc ");
3741            buf.append(startResult.pid);
3742            buf.append(':');
3743            buf.append(app.processName);
3744            buf.append('/');
3745            UserHandle.formatUid(buf, uid);
3746            if (!isActivityProcess) {
3747                buf.append(" [");
3748                buf.append(entryPoint);
3749                buf.append("]");
3750            }
3751            buf.append(" for ");
3752            buf.append(hostingType);
3753            if (hostingNameStr != null) {
3754                buf.append(" ");
3755                buf.append(hostingNameStr);
3756            }
3757            Slog.i(TAG, buf.toString());
3758            app.setPid(startResult.pid);
3759            app.usingWrapper = startResult.usingWrapper;
3760            app.removed = false;
3761            app.killed = false;
3762            app.killedByAm = false;
3763            checkTime(startTime, "startProcess: starting to update pids map");
3764            synchronized (mPidsSelfLocked) {
3765                this.mPidsSelfLocked.put(startResult.pid, app);
3766                if (isActivityProcess) {
3767                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3768                    msg.obj = app;
3769                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3770                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3771                }
3772            }
3773            checkTime(startTime, "startProcess: done updating pids map");
3774        } catch (RuntimeException e) {
3775            Slog.e(TAG, "Failure starting process " + app.processName, e);
3776
3777            // Something went very wrong while trying to start this process; one
3778            // common case is when the package is frozen due to an active
3779            // upgrade. To recover, clean up any active bookkeeping related to
3780            // starting this process. (We already invoked this method once when
3781            // the package was initially frozen through KILL_APPLICATION_MSG, so
3782            // it doesn't hurt to use it again.)
3783            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3784                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3785        }
3786    }
3787
3788    void updateUsageStats(ActivityRecord component, boolean resumed) {
3789        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3790                "updateUsageStats: comp=" + component + "res=" + resumed);
3791        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3792        if (resumed) {
3793            if (mUsageStatsService != null) {
3794                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3795                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3796            }
3797            synchronized (stats) {
3798                stats.noteActivityResumedLocked(component.app.uid);
3799            }
3800        } else {
3801            if (mUsageStatsService != null) {
3802                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3803                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3804            }
3805            synchronized (stats) {
3806                stats.noteActivityPausedLocked(component.app.uid);
3807            }
3808        }
3809    }
3810
3811    Intent getHomeIntent() {
3812        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3813        intent.setComponent(mTopComponent);
3814        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3815        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3816            intent.addCategory(Intent.CATEGORY_HOME);
3817        }
3818        return intent;
3819    }
3820
3821    boolean startHomeActivityLocked(int userId, String reason) {
3822        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3823                && mTopAction == null) {
3824            // We are running in factory test mode, but unable to find
3825            // the factory test app, so just sit around displaying the
3826            // error message and don't try to start anything.
3827            return false;
3828        }
3829        Intent intent = getHomeIntent();
3830        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3831        if (aInfo != null) {
3832            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3833            // Don't do this if the home app is currently being
3834            // instrumented.
3835            aInfo = new ActivityInfo(aInfo);
3836            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3837            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3838                    aInfo.applicationInfo.uid, true);
3839            if (app == null || app.instrumentationClass == null) {
3840                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3841                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3842            }
3843        } else {
3844            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3845        }
3846
3847        return true;
3848    }
3849
3850    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3851        ActivityInfo ai = null;
3852        ComponentName comp = intent.getComponent();
3853        try {
3854            if (comp != null) {
3855                // Factory test.
3856                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3857            } else {
3858                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3859                        intent,
3860                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3861                        flags, userId);
3862
3863                if (info != null) {
3864                    ai = info.activityInfo;
3865                }
3866            }
3867        } catch (RemoteException e) {
3868            // ignore
3869        }
3870
3871        return ai;
3872    }
3873
3874    /**
3875     * Starts the "new version setup screen" if appropriate.
3876     */
3877    void startSetupActivityLocked() {
3878        // Only do this once per boot.
3879        if (mCheckedForSetup) {
3880            return;
3881        }
3882
3883        // We will show this screen if the current one is a different
3884        // version than the last one shown, and we are not running in
3885        // low-level factory test mode.
3886        final ContentResolver resolver = mContext.getContentResolver();
3887        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3888                Settings.Global.getInt(resolver,
3889                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3890            mCheckedForSetup = true;
3891
3892            // See if we should be showing the platform update setup UI.
3893            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3894            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3895                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3896            if (!ris.isEmpty()) {
3897                final ResolveInfo ri = ris.get(0);
3898                String vers = ri.activityInfo.metaData != null
3899                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3900                        : null;
3901                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3902                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3903                            Intent.METADATA_SETUP_VERSION);
3904                }
3905                String lastVers = Settings.Secure.getString(
3906                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3907                if (vers != null && !vers.equals(lastVers)) {
3908                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3909                    intent.setComponent(new ComponentName(
3910                            ri.activityInfo.packageName, ri.activityInfo.name));
3911                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3912                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3913                            null, 0, 0, 0, null, false, false, null, null, null);
3914                }
3915            }
3916        }
3917    }
3918
3919    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3920        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3921    }
3922
3923    void enforceNotIsolatedCaller(String caller) {
3924        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3925            throw new SecurityException("Isolated process not allowed to call " + caller);
3926        }
3927    }
3928
3929    void enforceShellRestriction(String restriction, int userHandle) {
3930        if (Binder.getCallingUid() == Process.SHELL_UID) {
3931            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3932                throw new SecurityException("Shell does not have permission to access user "
3933                        + userHandle);
3934            }
3935        }
3936    }
3937
3938    @Override
3939    public int getFrontActivityScreenCompatMode() {
3940        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3941        synchronized (this) {
3942            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3943        }
3944    }
3945
3946    @Override
3947    public void setFrontActivityScreenCompatMode(int mode) {
3948        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3949                "setFrontActivityScreenCompatMode");
3950        synchronized (this) {
3951            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3952        }
3953    }
3954
3955    @Override
3956    public int getPackageScreenCompatMode(String packageName) {
3957        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3958        synchronized (this) {
3959            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3960        }
3961    }
3962
3963    @Override
3964    public void setPackageScreenCompatMode(String packageName, int mode) {
3965        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3966                "setPackageScreenCompatMode");
3967        synchronized (this) {
3968            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3969        }
3970    }
3971
3972    @Override
3973    public boolean getPackageAskScreenCompat(String packageName) {
3974        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3975        synchronized (this) {
3976            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3977        }
3978    }
3979
3980    @Override
3981    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3982        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3983                "setPackageAskScreenCompat");
3984        synchronized (this) {
3985            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3986        }
3987    }
3988
3989    private boolean hasUsageStatsPermission(String callingPackage) {
3990        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3991                Binder.getCallingUid(), callingPackage);
3992        if (mode == AppOpsManager.MODE_DEFAULT) {
3993            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3994                    == PackageManager.PERMISSION_GRANTED;
3995        }
3996        return mode == AppOpsManager.MODE_ALLOWED;
3997    }
3998
3999    @Override
4000    public int getPackageProcessState(String packageName, String callingPackage) {
4001        if (!hasUsageStatsPermission(callingPackage)) {
4002            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4003                    "getPackageProcessState");
4004        }
4005
4006        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4007        synchronized (this) {
4008            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4009                final ProcessRecord proc = mLruProcesses.get(i);
4010                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4011                        || procState > proc.setProcState) {
4012                    boolean found = false;
4013                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4014                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4015                            procState = proc.setProcState;
4016                            found = true;
4017                        }
4018                    }
4019                    if (proc.pkgDeps != null && !found) {
4020                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4021                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4022                                procState = proc.setProcState;
4023                                break;
4024                            }
4025                        }
4026                    }
4027                }
4028            }
4029        }
4030        return procState;
4031    }
4032
4033    @Override
4034    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4035        synchronized (this) {
4036            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4037            if (app == null) {
4038                return false;
4039            }
4040            if (app.trimMemoryLevel < level && app.thread != null &&
4041                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4042                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4043                try {
4044                    app.thread.scheduleTrimMemory(level);
4045                    app.trimMemoryLevel = level;
4046                    return true;
4047                } catch (RemoteException e) {
4048                    // Fallthrough to failure case.
4049                }
4050            }
4051        }
4052        return false;
4053    }
4054
4055    private void dispatchProcessesChanged() {
4056        int N;
4057        synchronized (this) {
4058            N = mPendingProcessChanges.size();
4059            if (mActiveProcessChanges.length < N) {
4060                mActiveProcessChanges = new ProcessChangeItem[N];
4061            }
4062            mPendingProcessChanges.toArray(mActiveProcessChanges);
4063            mPendingProcessChanges.clear();
4064            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4065                    "*** Delivering " + N + " process changes");
4066        }
4067
4068        int i = mProcessObservers.beginBroadcast();
4069        while (i > 0) {
4070            i--;
4071            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4072            if (observer != null) {
4073                try {
4074                    for (int j=0; j<N; j++) {
4075                        ProcessChangeItem item = mActiveProcessChanges[j];
4076                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4077                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4078                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4079                                    + item.uid + ": " + item.foregroundActivities);
4080                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4081                                    item.foregroundActivities);
4082                        }
4083                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4084                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4085                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4086                                    + ": " + item.processState);
4087                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4088                        }
4089                    }
4090                } catch (RemoteException e) {
4091                }
4092            }
4093        }
4094        mProcessObservers.finishBroadcast();
4095
4096        synchronized (this) {
4097            for (int j=0; j<N; j++) {
4098                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4099            }
4100        }
4101    }
4102
4103    private void dispatchProcessDied(int pid, int uid) {
4104        int i = mProcessObservers.beginBroadcast();
4105        while (i > 0) {
4106            i--;
4107            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4108            if (observer != null) {
4109                try {
4110                    observer.onProcessDied(pid, uid);
4111                } catch (RemoteException e) {
4112                }
4113            }
4114        }
4115        mProcessObservers.finishBroadcast();
4116    }
4117
4118    private void dispatchUidsChanged() {
4119        int N;
4120        synchronized (this) {
4121            N = mPendingUidChanges.size();
4122            if (mActiveUidChanges.length < N) {
4123                mActiveUidChanges = new UidRecord.ChangeItem[N];
4124            }
4125            for (int i=0; i<N; i++) {
4126                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4127                mActiveUidChanges[i] = change;
4128                if (change.uidRecord != null) {
4129                    change.uidRecord.pendingChange = null;
4130                    change.uidRecord = null;
4131                }
4132            }
4133            mPendingUidChanges.clear();
4134            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4135                    "*** Delivering " + N + " uid changes");
4136        }
4137
4138        if (mLocalPowerManager != null) {
4139            for (int j=0; j<N; j++) {
4140                UidRecord.ChangeItem item = mActiveUidChanges[j];
4141                if (item.change == UidRecord.CHANGE_GONE
4142                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4143                    mLocalPowerManager.uidGone(item.uid);
4144                } else {
4145                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4146                }
4147            }
4148        }
4149
4150        int i = mUidObservers.beginBroadcast();
4151        while (i > 0) {
4152            i--;
4153            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4154            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4155            if (observer != null) {
4156                try {
4157                    for (int j=0; j<N; j++) {
4158                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4159                        final int change = item.change;
4160                        UidRecord validateUid = null;
4161                        if (VALIDATE_UID_STATES && i == 0) {
4162                            validateUid = mValidateUids.get(item.uid);
4163                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4164                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4165                                validateUid = new UidRecord(item.uid);
4166                                mValidateUids.put(item.uid, validateUid);
4167                            }
4168                        }
4169                        if (change == UidRecord.CHANGE_IDLE
4170                                || change == UidRecord.CHANGE_GONE_IDLE) {
4171                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4172                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4173                                        "UID idle uid=" + item.uid);
4174                                observer.onUidIdle(item.uid);
4175                            }
4176                            if (VALIDATE_UID_STATES && i == 0) {
4177                                if (validateUid != null) {
4178                                    validateUid.idle = true;
4179                                }
4180                            }
4181                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4182                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4183                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4184                                        "UID active uid=" + item.uid);
4185                                observer.onUidActive(item.uid);
4186                            }
4187                            if (VALIDATE_UID_STATES && i == 0) {
4188                                validateUid.idle = false;
4189                            }
4190                        }
4191                        if (change == UidRecord.CHANGE_GONE
4192                                || change == UidRecord.CHANGE_GONE_IDLE) {
4193                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4194                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4195                                        "UID gone uid=" + item.uid);
4196                                observer.onUidGone(item.uid);
4197                            }
4198                            if (VALIDATE_UID_STATES && i == 0) {
4199                                if (validateUid != null) {
4200                                    mValidateUids.remove(item.uid);
4201                                }
4202                            }
4203                        } else {
4204                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4205                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4206                                        "UID CHANGED uid=" + item.uid
4207                                                + ": " + item.processState);
4208                                observer.onUidStateChanged(item.uid, item.processState);
4209                            }
4210                            if (VALIDATE_UID_STATES && i == 0) {
4211                                validateUid.curProcState = validateUid.setProcState
4212                                        = item.processState;
4213                            }
4214                        }
4215                    }
4216                } catch (RemoteException e) {
4217                }
4218            }
4219        }
4220        mUidObservers.finishBroadcast();
4221
4222        synchronized (this) {
4223            for (int j=0; j<N; j++) {
4224                mAvailUidChanges.add(mActiveUidChanges[j]);
4225            }
4226        }
4227    }
4228
4229    @Override
4230    public final int startActivity(IApplicationThread caller, String callingPackage,
4231            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4232            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4233        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4234                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4235                UserHandle.getCallingUserId());
4236    }
4237
4238    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4239        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4240        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4241                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4242                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4243
4244        // TODO: Switch to user app stacks here.
4245        String mimeType = intent.getType();
4246        final Uri data = intent.getData();
4247        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4248            mimeType = getProviderMimeType(data, userId);
4249        }
4250        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4251
4252        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4253        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4254                null, 0, 0, null, null, null, null, false, userId, container, null);
4255    }
4256
4257    @Override
4258    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4259            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4260            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4261        enforceNotIsolatedCaller("startActivity");
4262        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4263                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4264        // TODO: Switch to user app stacks here.
4265        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4266                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4267                profilerInfo, null, null, bOptions, false, userId, null, null);
4268    }
4269
4270    @Override
4271    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4272            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4273            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4274            int userId) {
4275
4276        // This is very dangerous -- it allows you to perform a start activity (including
4277        // permission grants) as any app that may launch one of your own activities.  So
4278        // we will only allow this to be done from activities that are part of the core framework,
4279        // and then only when they are running as the system.
4280        final ActivityRecord sourceRecord;
4281        final int targetUid;
4282        final String targetPackage;
4283        synchronized (this) {
4284            if (resultTo == null) {
4285                throw new SecurityException("Must be called from an activity");
4286            }
4287            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4288            if (sourceRecord == null) {
4289                throw new SecurityException("Called with bad activity token: " + resultTo);
4290            }
4291            if (!sourceRecord.info.packageName.equals("android")) {
4292                throw new SecurityException(
4293                        "Must be called from an activity that is declared in the android package");
4294            }
4295            if (sourceRecord.app == null) {
4296                throw new SecurityException("Called without a process attached to activity");
4297            }
4298            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4299                // This is still okay, as long as this activity is running under the
4300                // uid of the original calling activity.
4301                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4302                    throw new SecurityException(
4303                            "Calling activity in uid " + sourceRecord.app.uid
4304                                    + " must be system uid or original calling uid "
4305                                    + sourceRecord.launchedFromUid);
4306                }
4307            }
4308            if (ignoreTargetSecurity) {
4309                if (intent.getComponent() == null) {
4310                    throw new SecurityException(
4311                            "Component must be specified with ignoreTargetSecurity");
4312                }
4313                if (intent.getSelector() != null) {
4314                    throw new SecurityException(
4315                            "Selector not allowed with ignoreTargetSecurity");
4316                }
4317            }
4318            targetUid = sourceRecord.launchedFromUid;
4319            targetPackage = sourceRecord.launchedFromPackage;
4320        }
4321
4322        if (userId == UserHandle.USER_NULL) {
4323            userId = UserHandle.getUserId(sourceRecord.app.uid);
4324        }
4325
4326        // TODO: Switch to user app stacks here.
4327        try {
4328            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4329                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4330                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4331            return ret;
4332        } catch (SecurityException e) {
4333            // XXX need to figure out how to propagate to original app.
4334            // A SecurityException here is generally actually a fault of the original
4335            // calling activity (such as a fairly granting permissions), so propagate it
4336            // back to them.
4337            /*
4338            StringBuilder msg = new StringBuilder();
4339            msg.append("While launching");
4340            msg.append(intent.toString());
4341            msg.append(": ");
4342            msg.append(e.getMessage());
4343            */
4344            throw e;
4345        }
4346    }
4347
4348    @Override
4349    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4350            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4351            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4352        enforceNotIsolatedCaller("startActivityAndWait");
4353        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4354                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4355        WaitResult res = new WaitResult();
4356        // TODO: Switch to user app stacks here.
4357        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4358                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4359                bOptions, false, userId, null, null);
4360        return res;
4361    }
4362
4363    @Override
4364    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4365            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4366            int startFlags, Configuration config, Bundle bOptions, int userId) {
4367        enforceNotIsolatedCaller("startActivityWithConfig");
4368        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4369                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4370        // TODO: Switch to user app stacks here.
4371        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4372                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4373                null, null, config, bOptions, false, userId, null, null);
4374        return ret;
4375    }
4376
4377    @Override
4378    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4379            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4380            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4381            throws TransactionTooLargeException {
4382        enforceNotIsolatedCaller("startActivityIntentSender");
4383        // Refuse possible leaked file descriptors
4384        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4385            throw new IllegalArgumentException("File descriptors passed in Intent");
4386        }
4387
4388        IIntentSender sender = intent.getTarget();
4389        if (!(sender instanceof PendingIntentRecord)) {
4390            throw new IllegalArgumentException("Bad PendingIntent object");
4391        }
4392
4393        PendingIntentRecord pir = (PendingIntentRecord)sender;
4394
4395        synchronized (this) {
4396            // If this is coming from the currently resumed activity, it is
4397            // effectively saying that app switches are allowed at this point.
4398            final ActivityStack stack = getFocusedStack();
4399            if (stack.mResumedActivity != null &&
4400                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4401                mAppSwitchesAllowedTime = 0;
4402            }
4403        }
4404        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4405                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4406        return ret;
4407    }
4408
4409    @Override
4410    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4411            Intent intent, String resolvedType, IVoiceInteractionSession session,
4412            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4413            Bundle bOptions, int userId) {
4414        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4415                != PackageManager.PERMISSION_GRANTED) {
4416            String msg = "Permission Denial: startVoiceActivity() from pid="
4417                    + Binder.getCallingPid()
4418                    + ", uid=" + Binder.getCallingUid()
4419                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4420            Slog.w(TAG, msg);
4421            throw new SecurityException(msg);
4422        }
4423        if (session == null || interactor == null) {
4424            throw new NullPointerException("null session or interactor");
4425        }
4426        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4427                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4428        // TODO: Switch to user app stacks here.
4429        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4430                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4431                null, bOptions, false, userId, null, null);
4432    }
4433
4434    @Override
4435    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4436            throws RemoteException {
4437        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4438        synchronized (this) {
4439            ActivityRecord activity = getFocusedStack().topActivity();
4440            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4441                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4442            }
4443            if (mRunningVoice != null || activity.task.voiceSession != null
4444                    || activity.voiceSession != null) {
4445                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4446                return;
4447            }
4448            if (activity.pendingVoiceInteractionStart) {
4449                Slog.w(TAG, "Pending start of voice interaction already.");
4450                return;
4451            }
4452            activity.pendingVoiceInteractionStart = true;
4453        }
4454        LocalServices.getService(VoiceInteractionManagerInternal.class)
4455                .startLocalVoiceInteraction(callingActivity, options);
4456    }
4457
4458    @Override
4459    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4460        LocalServices.getService(VoiceInteractionManagerInternal.class)
4461                .stopLocalVoiceInteraction(callingActivity);
4462    }
4463
4464    @Override
4465    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4466        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4467                .supportsLocalVoiceInteraction();
4468    }
4469
4470    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4471            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4472        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4473        if (activityToCallback == null) return;
4474        activityToCallback.setVoiceSessionLocked(voiceSession);
4475
4476        // Inform the activity
4477        try {
4478            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4479                    voiceInteractor);
4480            long token = Binder.clearCallingIdentity();
4481            try {
4482                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4483            } finally {
4484                Binder.restoreCallingIdentity(token);
4485            }
4486            // TODO: VI Should we cache the activity so that it's easier to find later
4487            // rather than scan through all the stacks and activities?
4488        } catch (RemoteException re) {
4489            activityToCallback.clearVoiceSessionLocked();
4490            // TODO: VI Should this terminate the voice session?
4491        }
4492    }
4493
4494    @Override
4495    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4496        synchronized (this) {
4497            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4498                if (keepAwake) {
4499                    mVoiceWakeLock.acquire();
4500                } else {
4501                    mVoiceWakeLock.release();
4502                }
4503            }
4504        }
4505    }
4506
4507    @Override
4508    public boolean startNextMatchingActivity(IBinder callingActivity,
4509            Intent intent, Bundle bOptions) {
4510        // Refuse possible leaked file descriptors
4511        if (intent != null && intent.hasFileDescriptors() == true) {
4512            throw new IllegalArgumentException("File descriptors passed in Intent");
4513        }
4514        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4515
4516        synchronized (this) {
4517            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4518            if (r == null) {
4519                ActivityOptions.abort(options);
4520                return false;
4521            }
4522            if (r.app == null || r.app.thread == null) {
4523                // The caller is not running...  d'oh!
4524                ActivityOptions.abort(options);
4525                return false;
4526            }
4527            intent = new Intent(intent);
4528            // The caller is not allowed to change the data.
4529            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4530            // And we are resetting to find the next component...
4531            intent.setComponent(null);
4532
4533            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4534
4535            ActivityInfo aInfo = null;
4536            try {
4537                List<ResolveInfo> resolves =
4538                    AppGlobals.getPackageManager().queryIntentActivities(
4539                            intent, r.resolvedType,
4540                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4541                            UserHandle.getCallingUserId()).getList();
4542
4543                // Look for the original activity in the list...
4544                final int N = resolves != null ? resolves.size() : 0;
4545                for (int i=0; i<N; i++) {
4546                    ResolveInfo rInfo = resolves.get(i);
4547                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4548                            && rInfo.activityInfo.name.equals(r.info.name)) {
4549                        // We found the current one...  the next matching is
4550                        // after it.
4551                        i++;
4552                        if (i<N) {
4553                            aInfo = resolves.get(i).activityInfo;
4554                        }
4555                        if (debug) {
4556                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4557                                    + "/" + r.info.name);
4558                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4559                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4560                        }
4561                        break;
4562                    }
4563                }
4564            } catch (RemoteException e) {
4565            }
4566
4567            if (aInfo == null) {
4568                // Nobody who is next!
4569                ActivityOptions.abort(options);
4570                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4571                return false;
4572            }
4573
4574            intent.setComponent(new ComponentName(
4575                    aInfo.applicationInfo.packageName, aInfo.name));
4576            intent.setFlags(intent.getFlags()&~(
4577                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4578                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4579                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4580                    Intent.FLAG_ACTIVITY_NEW_TASK));
4581
4582            // Okay now we need to start the new activity, replacing the
4583            // currently running activity.  This is a little tricky because
4584            // we want to start the new one as if the current one is finished,
4585            // but not finish the current one first so that there is no flicker.
4586            // And thus...
4587            final boolean wasFinishing = r.finishing;
4588            r.finishing = true;
4589
4590            // Propagate reply information over to the new activity.
4591            final ActivityRecord resultTo = r.resultTo;
4592            final String resultWho = r.resultWho;
4593            final int requestCode = r.requestCode;
4594            r.resultTo = null;
4595            if (resultTo != null) {
4596                resultTo.removeResultsLocked(r, resultWho, requestCode);
4597            }
4598
4599            final long origId = Binder.clearCallingIdentity();
4600            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4601                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4602                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4603                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4604                    false, false, null, null, null);
4605            Binder.restoreCallingIdentity(origId);
4606
4607            r.finishing = wasFinishing;
4608            if (res != ActivityManager.START_SUCCESS) {
4609                return false;
4610            }
4611            return true;
4612        }
4613    }
4614
4615    @Override
4616    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4617        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4618            String msg = "Permission Denial: startActivityFromRecents called without " +
4619                    START_TASKS_FROM_RECENTS;
4620            Slog.w(TAG, msg);
4621            throw new SecurityException(msg);
4622        }
4623        final long origId = Binder.clearCallingIdentity();
4624        try {
4625            synchronized (this) {
4626                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4627            }
4628        } finally {
4629            Binder.restoreCallingIdentity(origId);
4630        }
4631    }
4632
4633    final int startActivityInPackage(int uid, String callingPackage,
4634            Intent intent, String resolvedType, IBinder resultTo,
4635            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4636            IActivityContainer container, TaskRecord inTask) {
4637
4638        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4639                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4640
4641        // TODO: Switch to user app stacks here.
4642        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4643                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4644                null, null, null, bOptions, false, userId, container, inTask);
4645        return ret;
4646    }
4647
4648    @Override
4649    public final int startActivities(IApplicationThread caller, String callingPackage,
4650            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4651            int userId) {
4652        enforceNotIsolatedCaller("startActivities");
4653        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4654                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4655        // TODO: Switch to user app stacks here.
4656        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4657                resolvedTypes, resultTo, bOptions, userId);
4658        return ret;
4659    }
4660
4661    final int startActivitiesInPackage(int uid, String callingPackage,
4662            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4663            Bundle bOptions, int userId) {
4664
4665        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4666                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4667        // TODO: Switch to user app stacks here.
4668        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4669                resultTo, bOptions, userId);
4670        return ret;
4671    }
4672
4673    @Override
4674    public void reportActivityFullyDrawn(IBinder token) {
4675        synchronized (this) {
4676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4677            if (r == null) {
4678                return;
4679            }
4680            r.reportFullyDrawnLocked();
4681        }
4682    }
4683
4684    @Override
4685    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4686        synchronized (this) {
4687            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4688            if (r == null) {
4689                return;
4690            }
4691            TaskRecord task = r.task;
4692            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4693                // Fixed screen orientation isn't supported when activities aren't in full screen
4694                // mode.
4695                return;
4696            }
4697            final long origId = Binder.clearCallingIdentity();
4698            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4699            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4700                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4701            if (config != null) {
4702                r.frozenBeforeDestroy = true;
4703                if (!updateConfigurationLocked(config, r, false)) {
4704                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4705                }
4706            }
4707            Binder.restoreCallingIdentity(origId);
4708        }
4709    }
4710
4711    @Override
4712    public int getRequestedOrientation(IBinder token) {
4713        synchronized (this) {
4714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4715            if (r == null) {
4716                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4717            }
4718            return mWindowManager.getAppOrientation(r.appToken);
4719        }
4720    }
4721
4722    /**
4723     * This is the internal entry point for handling Activity.finish().
4724     *
4725     * @param token The Binder token referencing the Activity we want to finish.
4726     * @param resultCode Result code, if any, from this Activity.
4727     * @param resultData Result data (Intent), if any, from this Activity.
4728     * @param finishTask Whether to finish the task associated with this Activity.
4729     *
4730     * @return Returns true if the activity successfully finished, or false if it is still running.
4731     */
4732    @Override
4733    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4734            int finishTask) {
4735        // Refuse possible leaked file descriptors
4736        if (resultData != null && resultData.hasFileDescriptors() == true) {
4737            throw new IllegalArgumentException("File descriptors passed in Intent");
4738        }
4739
4740        synchronized(this) {
4741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4742            if (r == null) {
4743                return true;
4744            }
4745            // Keep track of the root activity of the task before we finish it
4746            TaskRecord tr = r.task;
4747            ActivityRecord rootR = tr.getRootActivity();
4748            if (rootR == null) {
4749                Slog.w(TAG, "Finishing task with all activities already finished");
4750            }
4751            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4752            // finish.
4753            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4754                    mStackSupervisor.isLastLockedTask(tr)) {
4755                Slog.i(TAG, "Not finishing task in lock task mode");
4756                mStackSupervisor.showLockTaskToast();
4757                return false;
4758            }
4759            if (mController != null) {
4760                // Find the first activity that is not finishing.
4761                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4762                if (next != null) {
4763                    // ask watcher if this is allowed
4764                    boolean resumeOK = true;
4765                    try {
4766                        resumeOK = mController.activityResuming(next.packageName);
4767                    } catch (RemoteException e) {
4768                        mController = null;
4769                        Watchdog.getInstance().setActivityController(null);
4770                    }
4771
4772                    if (!resumeOK) {
4773                        Slog.i(TAG, "Not finishing activity because controller resumed");
4774                        return false;
4775                    }
4776                }
4777            }
4778            final long origId = Binder.clearCallingIdentity();
4779            try {
4780                boolean res;
4781                final boolean finishWithRootActivity =
4782                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4783                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4784                        || (finishWithRootActivity && r == rootR)) {
4785                    // If requested, remove the task that is associated to this activity only if it
4786                    // was the root activity in the task. The result code and data is ignored
4787                    // because we don't support returning them across task boundaries. Also, to
4788                    // keep backwards compatibility we remove the task from recents when finishing
4789                    // task with root activity.
4790                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4791                    if (!res) {
4792                        Slog.i(TAG, "Removing task failed to finish activity");
4793                    }
4794                } else {
4795                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4796                            resultData, "app-request", true);
4797                    if (!res) {
4798                        Slog.i(TAG, "Failed to finish by app-request");
4799                    }
4800                }
4801                return res;
4802            } finally {
4803                Binder.restoreCallingIdentity(origId);
4804            }
4805        }
4806    }
4807
4808    @Override
4809    public final void finishHeavyWeightApp() {
4810        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4811                != PackageManager.PERMISSION_GRANTED) {
4812            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4813                    + Binder.getCallingPid()
4814                    + ", uid=" + Binder.getCallingUid()
4815                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4816            Slog.w(TAG, msg);
4817            throw new SecurityException(msg);
4818        }
4819
4820        synchronized(this) {
4821            if (mHeavyWeightProcess == null) {
4822                return;
4823            }
4824
4825            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4826            for (int i = 0; i < activities.size(); i++) {
4827                ActivityRecord r = activities.get(i);
4828                if (!r.finishing && r.isInStackLocked()) {
4829                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4830                            null, "finish-heavy", true);
4831                }
4832            }
4833
4834            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4835                    mHeavyWeightProcess.userId, 0));
4836            mHeavyWeightProcess = null;
4837        }
4838    }
4839
4840    @Override
4841    public void crashApplication(int uid, int initialPid, String packageName,
4842            String message) {
4843        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4844                != PackageManager.PERMISSION_GRANTED) {
4845            String msg = "Permission Denial: crashApplication() from pid="
4846                    + Binder.getCallingPid()
4847                    + ", uid=" + Binder.getCallingUid()
4848                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4849            Slog.w(TAG, msg);
4850            throw new SecurityException(msg);
4851        }
4852
4853        synchronized(this) {
4854            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4855        }
4856    }
4857
4858    @Override
4859    public final void finishSubActivity(IBinder token, String resultWho,
4860            int requestCode) {
4861        synchronized(this) {
4862            final long origId = Binder.clearCallingIdentity();
4863            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4864            if (r != null) {
4865                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4866            }
4867            Binder.restoreCallingIdentity(origId);
4868        }
4869    }
4870
4871    @Override
4872    public boolean finishActivityAffinity(IBinder token) {
4873        synchronized(this) {
4874            final long origId = Binder.clearCallingIdentity();
4875            try {
4876                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4877                if (r == null) {
4878                    return false;
4879                }
4880
4881                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4882                // can finish.
4883                final TaskRecord task = r.task;
4884                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4885                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4886                    mStackSupervisor.showLockTaskToast();
4887                    return false;
4888                }
4889                return task.stack.finishActivityAffinityLocked(r);
4890            } finally {
4891                Binder.restoreCallingIdentity(origId);
4892            }
4893        }
4894    }
4895
4896    @Override
4897    public void finishVoiceTask(IVoiceInteractionSession session) {
4898        synchronized (this) {
4899            final long origId = Binder.clearCallingIdentity();
4900            try {
4901                // TODO: VI Consider treating local voice interactions and voice tasks
4902                // differently here
4903                mStackSupervisor.finishVoiceTask(session);
4904            } finally {
4905                Binder.restoreCallingIdentity(origId);
4906            }
4907        }
4908
4909    }
4910
4911    @Override
4912    public boolean releaseActivityInstance(IBinder token) {
4913        synchronized(this) {
4914            final long origId = Binder.clearCallingIdentity();
4915            try {
4916                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4917                if (r == null) {
4918                    return false;
4919                }
4920                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4921            } finally {
4922                Binder.restoreCallingIdentity(origId);
4923            }
4924        }
4925    }
4926
4927    @Override
4928    public void releaseSomeActivities(IApplicationThread appInt) {
4929        synchronized(this) {
4930            final long origId = Binder.clearCallingIdentity();
4931            try {
4932                ProcessRecord app = getRecordForAppLocked(appInt);
4933                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4934            } finally {
4935                Binder.restoreCallingIdentity(origId);
4936            }
4937        }
4938    }
4939
4940    @Override
4941    public boolean willActivityBeVisible(IBinder token) {
4942        synchronized(this) {
4943            ActivityStack stack = ActivityRecord.getStackLocked(token);
4944            if (stack != null) {
4945                return stack.willActivityBeVisibleLocked(token);
4946            }
4947            return false;
4948        }
4949    }
4950
4951    @Override
4952    public void overridePendingTransition(IBinder token, String packageName,
4953            int enterAnim, int exitAnim) {
4954        synchronized(this) {
4955            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4956            if (self == null) {
4957                return;
4958            }
4959
4960            final long origId = Binder.clearCallingIdentity();
4961
4962            if (self.state == ActivityState.RESUMED
4963                    || self.state == ActivityState.PAUSING) {
4964                mWindowManager.overridePendingAppTransition(packageName,
4965                        enterAnim, exitAnim, null);
4966            }
4967
4968            Binder.restoreCallingIdentity(origId);
4969        }
4970    }
4971
4972    /**
4973     * Main function for removing an existing process from the activity manager
4974     * as a result of that process going away.  Clears out all connections
4975     * to the process.
4976     */
4977    private final void handleAppDiedLocked(ProcessRecord app,
4978            boolean restarting, boolean allowRestart) {
4979        int pid = app.pid;
4980        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4981        if (!kept && !restarting) {
4982            removeLruProcessLocked(app);
4983            if (pid > 0) {
4984                ProcessList.remove(pid);
4985            }
4986        }
4987
4988        if (mProfileProc == app) {
4989            clearProfilerLocked();
4990        }
4991
4992        // Remove this application's activities from active lists.
4993        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4994
4995        app.activities.clear();
4996
4997        if (app.instrumentationClass != null) {
4998            Slog.w(TAG, "Crash of app " + app.processName
4999                  + " running instrumentation " + app.instrumentationClass);
5000            Bundle info = new Bundle();
5001            info.putString("shortMsg", "Process crashed.");
5002            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5003        }
5004
5005        if (!restarting && hasVisibleActivities
5006                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5007            // If there was nothing to resume, and we are not already restarting this process, but
5008            // there is a visible activity that is hosted by the process...  then make sure all
5009            // visible activities are running, taking care of restarting this process.
5010            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5011        }
5012    }
5013
5014    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5015        IBinder threadBinder = thread.asBinder();
5016        // Find the application record.
5017        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5018            ProcessRecord rec = mLruProcesses.get(i);
5019            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5020                return i;
5021            }
5022        }
5023        return -1;
5024    }
5025
5026    final ProcessRecord getRecordForAppLocked(
5027            IApplicationThread thread) {
5028        if (thread == null) {
5029            return null;
5030        }
5031
5032        int appIndex = getLRURecordIndexForAppLocked(thread);
5033        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5034    }
5035
5036    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5037        // If there are no longer any background processes running,
5038        // and the app that died was not running instrumentation,
5039        // then tell everyone we are now low on memory.
5040        boolean haveBg = false;
5041        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5042            ProcessRecord rec = mLruProcesses.get(i);
5043            if (rec.thread != null
5044                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5045                haveBg = true;
5046                break;
5047            }
5048        }
5049
5050        if (!haveBg) {
5051            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5052            if (doReport) {
5053                long now = SystemClock.uptimeMillis();
5054                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5055                    doReport = false;
5056                } else {
5057                    mLastMemUsageReportTime = now;
5058                }
5059            }
5060            final ArrayList<ProcessMemInfo> memInfos
5061                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5062            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5063            long now = SystemClock.uptimeMillis();
5064            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5065                ProcessRecord rec = mLruProcesses.get(i);
5066                if (rec == dyingProc || rec.thread == null) {
5067                    continue;
5068                }
5069                if (doReport) {
5070                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5071                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5072                }
5073                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5074                    // The low memory report is overriding any current
5075                    // state for a GC request.  Make sure to do
5076                    // heavy/important/visible/foreground processes first.
5077                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5078                        rec.lastRequestedGc = 0;
5079                    } else {
5080                        rec.lastRequestedGc = rec.lastLowMemory;
5081                    }
5082                    rec.reportLowMemory = true;
5083                    rec.lastLowMemory = now;
5084                    mProcessesToGc.remove(rec);
5085                    addProcessToGcListLocked(rec);
5086                }
5087            }
5088            if (doReport) {
5089                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5090                mHandler.sendMessage(msg);
5091            }
5092            scheduleAppGcsLocked();
5093        }
5094    }
5095
5096    final void appDiedLocked(ProcessRecord app) {
5097       appDiedLocked(app, app.pid, app.thread, false);
5098    }
5099
5100    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5101            boolean fromBinderDied) {
5102        // First check if this ProcessRecord is actually active for the pid.
5103        synchronized (mPidsSelfLocked) {
5104            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5105            if (curProc != app) {
5106                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5107                return;
5108            }
5109        }
5110
5111        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5112        synchronized (stats) {
5113            stats.noteProcessDiedLocked(app.info.uid, pid);
5114        }
5115
5116        if (!app.killed) {
5117            if (!fromBinderDied) {
5118                Process.killProcessQuiet(pid);
5119            }
5120            killProcessGroup(app.uid, pid);
5121            app.killed = true;
5122        }
5123
5124        // Clean up already done if the process has been re-started.
5125        if (app.pid == pid && app.thread != null &&
5126                app.thread.asBinder() == thread.asBinder()) {
5127            boolean doLowMem = app.instrumentationClass == null;
5128            boolean doOomAdj = doLowMem;
5129            if (!app.killedByAm) {
5130                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5131                        + ") has died");
5132                mAllowLowerMemLevel = true;
5133            } else {
5134                // Note that we always want to do oom adj to update our state with the
5135                // new number of procs.
5136                mAllowLowerMemLevel = false;
5137                doLowMem = false;
5138            }
5139            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5140            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5141                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5142            handleAppDiedLocked(app, false, true);
5143
5144            if (doOomAdj) {
5145                updateOomAdjLocked();
5146            }
5147            if (doLowMem) {
5148                doLowMemReportIfNeededLocked(app);
5149            }
5150        } else if (app.pid != pid) {
5151            // A new process has already been started.
5152            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5153                    + ") has died and restarted (pid " + app.pid + ").");
5154            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5155        } else if (DEBUG_PROCESSES) {
5156            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5157                    + thread.asBinder());
5158        }
5159    }
5160
5161    /**
5162     * If a stack trace dump file is configured, dump process stack traces.
5163     * @param clearTraces causes the dump file to be erased prior to the new
5164     *    traces being written, if true; when false, the new traces will be
5165     *    appended to any existing file content.
5166     * @param firstPids of dalvik VM processes to dump stack traces for first
5167     * @param lastPids of dalvik VM processes to dump stack traces for last
5168     * @param nativeProcs optional list of native process names to dump stack crawls
5169     * @return file containing stack traces, or null if no dump file is configured
5170     */
5171    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5172            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5173        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5174        if (tracesPath == null || tracesPath.length() == 0) {
5175            return null;
5176        }
5177
5178        File tracesFile = new File(tracesPath);
5179        try {
5180            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5181            tracesFile.createNewFile();
5182            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5183        } catch (IOException e) {
5184            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5185            return null;
5186        }
5187
5188        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5189        return tracesFile;
5190    }
5191
5192    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5193            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5194        // Use a FileObserver to detect when traces finish writing.
5195        // The order of traces is considered important to maintain for legibility.
5196        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5197            @Override
5198            public synchronized void onEvent(int event, String path) { notify(); }
5199        };
5200
5201        try {
5202            observer.startWatching();
5203
5204            // First collect all of the stacks of the most important pids.
5205            if (firstPids != null) {
5206                try {
5207                    int num = firstPids.size();
5208                    for (int i = 0; i < num; i++) {
5209                        synchronized (observer) {
5210                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5211                                    + firstPids.get(i));
5212                            final long sime = SystemClock.elapsedRealtime();
5213                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5214                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5215                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5216                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5217                        }
5218                    }
5219                } catch (InterruptedException e) {
5220                    Slog.wtf(TAG, e);
5221                }
5222            }
5223
5224            // Next collect the stacks of the native pids
5225            if (nativeProcs != null) {
5226                int[] pids = Process.getPidsForCommands(nativeProcs);
5227                if (pids != null) {
5228                    for (int pid : pids) {
5229                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5230                        final long sime = SystemClock.elapsedRealtime();
5231                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5232                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5233                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5234                    }
5235                }
5236            }
5237
5238            // Lastly, measure CPU usage.
5239            if (processCpuTracker != null) {
5240                processCpuTracker.init();
5241                System.gc();
5242                processCpuTracker.update();
5243                try {
5244                    synchronized (processCpuTracker) {
5245                        processCpuTracker.wait(500); // measure over 1/2 second.
5246                    }
5247                } catch (InterruptedException e) {
5248                }
5249                processCpuTracker.update();
5250
5251                // We'll take the stack crawls of just the top apps using CPU.
5252                final int N = processCpuTracker.countWorkingStats();
5253                int numProcs = 0;
5254                for (int i=0; i<N && numProcs<5; i++) {
5255                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5256                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5257                        numProcs++;
5258                        try {
5259                            synchronized (observer) {
5260                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5261                                        + stats.pid);
5262                                final long stime = SystemClock.elapsedRealtime();
5263                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5264                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5265                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5266                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5267                            }
5268                        } catch (InterruptedException e) {
5269                            Slog.wtf(TAG, e);
5270                        }
5271                    } else if (DEBUG_ANR) {
5272                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5273                                + stats.pid);
5274                    }
5275                }
5276            }
5277        } finally {
5278            observer.stopWatching();
5279        }
5280    }
5281
5282    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5283        if (true || IS_USER_BUILD) {
5284            return;
5285        }
5286        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5287        if (tracesPath == null || tracesPath.length() == 0) {
5288            return;
5289        }
5290
5291        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5292        StrictMode.allowThreadDiskWrites();
5293        try {
5294            final File tracesFile = new File(tracesPath);
5295            final File tracesDir = tracesFile.getParentFile();
5296            final File tracesTmp = new File(tracesDir, "__tmp__");
5297            try {
5298                if (tracesFile.exists()) {
5299                    tracesTmp.delete();
5300                    tracesFile.renameTo(tracesTmp);
5301                }
5302                StringBuilder sb = new StringBuilder();
5303                Time tobj = new Time();
5304                tobj.set(System.currentTimeMillis());
5305                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5306                sb.append(": ");
5307                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5308                sb.append(" since ");
5309                sb.append(msg);
5310                FileOutputStream fos = new FileOutputStream(tracesFile);
5311                fos.write(sb.toString().getBytes());
5312                if (app == null) {
5313                    fos.write("\n*** No application process!".getBytes());
5314                }
5315                fos.close();
5316                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5317            } catch (IOException e) {
5318                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5319                return;
5320            }
5321
5322            if (app != null) {
5323                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5324                firstPids.add(app.pid);
5325                dumpStackTraces(tracesPath, firstPids, null, null, null);
5326            }
5327
5328            File lastTracesFile = null;
5329            File curTracesFile = null;
5330            for (int i=9; i>=0; i--) {
5331                String name = String.format(Locale.US, "slow%02d.txt", i);
5332                curTracesFile = new File(tracesDir, name);
5333                if (curTracesFile.exists()) {
5334                    if (lastTracesFile != null) {
5335                        curTracesFile.renameTo(lastTracesFile);
5336                    } else {
5337                        curTracesFile.delete();
5338                    }
5339                }
5340                lastTracesFile = curTracesFile;
5341            }
5342            tracesFile.renameTo(curTracesFile);
5343            if (tracesTmp.exists()) {
5344                tracesTmp.renameTo(tracesFile);
5345            }
5346        } finally {
5347            StrictMode.setThreadPolicy(oldPolicy);
5348        }
5349    }
5350
5351    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5352        if (!mLaunchWarningShown) {
5353            mLaunchWarningShown = true;
5354            mUiHandler.post(new Runnable() {
5355                @Override
5356                public void run() {
5357                    synchronized (ActivityManagerService.this) {
5358                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5359                        d.show();
5360                        mUiHandler.postDelayed(new Runnable() {
5361                            @Override
5362                            public void run() {
5363                                synchronized (ActivityManagerService.this) {
5364                                    d.dismiss();
5365                                    mLaunchWarningShown = false;
5366                                }
5367                            }
5368                        }, 4000);
5369                    }
5370                }
5371            });
5372        }
5373    }
5374
5375    @Override
5376    public boolean clearApplicationUserData(final String packageName,
5377            final IPackageDataObserver observer, int userId) {
5378        enforceNotIsolatedCaller("clearApplicationUserData");
5379        int uid = Binder.getCallingUid();
5380        int pid = Binder.getCallingPid();
5381        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5382                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5383
5384
5385        long callingId = Binder.clearCallingIdentity();
5386        try {
5387            IPackageManager pm = AppGlobals.getPackageManager();
5388            int pkgUid = -1;
5389            synchronized(this) {
5390                if (getPackageManagerInternalLocked().canPackageBeWiped(
5391                        userId, packageName)) {
5392                    throw new SecurityException(
5393                            "Cannot clear data for a device owner or a profile owner");
5394                }
5395
5396                try {
5397                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5398                } catch (RemoteException e) {
5399                }
5400                if (pkgUid == -1) {
5401                    Slog.w(TAG, "Invalid packageName: " + packageName);
5402                    if (observer != null) {
5403                        try {
5404                            observer.onRemoveCompleted(packageName, false);
5405                        } catch (RemoteException e) {
5406                            Slog.i(TAG, "Observer no longer exists.");
5407                        }
5408                    }
5409                    return false;
5410                }
5411                if (uid == pkgUid || checkComponentPermission(
5412                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5413                        pid, uid, -1, true)
5414                        == PackageManager.PERMISSION_GRANTED) {
5415                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5416                } else {
5417                    throw new SecurityException("PID " + pid + " does not have permission "
5418                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5419                                    + " of package " + packageName);
5420                }
5421
5422                // Remove all tasks match the cleared application package and user
5423                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5424                    final TaskRecord tr = mRecentTasks.get(i);
5425                    final String taskPackageName =
5426                            tr.getBaseIntent().getComponent().getPackageName();
5427                    if (tr.userId != userId) continue;
5428                    if (!taskPackageName.equals(packageName)) continue;
5429                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5430                }
5431            }
5432
5433            final int pkgUidF = pkgUid;
5434            final int userIdF = userId;
5435            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5436                @Override
5437                public void onRemoveCompleted(String packageName, boolean succeeded)
5438                        throws RemoteException {
5439                    synchronized (ActivityManagerService.this) {
5440                        finishForceStopPackageLocked(packageName, pkgUidF);
5441                    }
5442
5443                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5444                            Uri.fromParts("package", packageName, null));
5445                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5446                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5447                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5448                            null, null, 0, null, null, null, null, false, false, userIdF);
5449
5450                    if (observer != null) {
5451                        observer.onRemoveCompleted(packageName, succeeded);
5452                    }
5453                }
5454            };
5455
5456            try {
5457                // Clear application user data
5458                pm.clearApplicationUserData(packageName, localObserver, userId);
5459
5460                synchronized(this) {
5461                    // Remove all permissions granted from/to this package
5462                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5463                }
5464
5465                // Remove all zen rules created by this package; revoke it's zen access.
5466                INotificationManager inm = NotificationManager.getService();
5467                inm.removeAutomaticZenRules(packageName);
5468                inm.setNotificationPolicyAccessGranted(packageName, false);
5469
5470            } catch (RemoteException e) {
5471            }
5472        } finally {
5473            Binder.restoreCallingIdentity(callingId);
5474        }
5475        return true;
5476    }
5477
5478    @Override
5479    public void killBackgroundProcesses(final String packageName, int userId) {
5480        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5481                != PackageManager.PERMISSION_GRANTED &&
5482                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5483                        != PackageManager.PERMISSION_GRANTED) {
5484            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5485                    + Binder.getCallingPid()
5486                    + ", uid=" + Binder.getCallingUid()
5487                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5488            Slog.w(TAG, msg);
5489            throw new SecurityException(msg);
5490        }
5491
5492        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5493                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5494        long callingId = Binder.clearCallingIdentity();
5495        try {
5496            IPackageManager pm = AppGlobals.getPackageManager();
5497            synchronized(this) {
5498                int appId = -1;
5499                try {
5500                    appId = UserHandle.getAppId(
5501                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5502                } catch (RemoteException e) {
5503                }
5504                if (appId == -1) {
5505                    Slog.w(TAG, "Invalid packageName: " + packageName);
5506                    return;
5507                }
5508                killPackageProcessesLocked(packageName, appId, userId,
5509                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5510            }
5511        } finally {
5512            Binder.restoreCallingIdentity(callingId);
5513        }
5514    }
5515
5516    @Override
5517    public void killAllBackgroundProcesses() {
5518        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5519                != PackageManager.PERMISSION_GRANTED) {
5520            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5521                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5522                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5523            Slog.w(TAG, msg);
5524            throw new SecurityException(msg);
5525        }
5526
5527        final long callingId = Binder.clearCallingIdentity();
5528        try {
5529            synchronized (this) {
5530                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5531                final int NP = mProcessNames.getMap().size();
5532                for (int ip = 0; ip < NP; ip++) {
5533                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5534                    final int NA = apps.size();
5535                    for (int ia = 0; ia < NA; ia++) {
5536                        final ProcessRecord app = apps.valueAt(ia);
5537                        if (app.persistent) {
5538                            // We don't kill persistent processes.
5539                            continue;
5540                        }
5541                        if (app.removed) {
5542                            procs.add(app);
5543                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5544                            app.removed = true;
5545                            procs.add(app);
5546                        }
5547                    }
5548                }
5549
5550                final int N = procs.size();
5551                for (int i = 0; i < N; i++) {
5552                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5553                }
5554
5555                mAllowLowerMemLevel = true;
5556
5557                updateOomAdjLocked();
5558                doLowMemReportIfNeededLocked(null);
5559            }
5560        } finally {
5561            Binder.restoreCallingIdentity(callingId);
5562        }
5563    }
5564
5565    /**
5566     * Kills all background processes, except those matching any of the
5567     * specified properties.
5568     *
5569     * @param minTargetSdk the target SDK version at or above which to preserve
5570     *                     processes, or {@code -1} to ignore the target SDK
5571     * @param maxProcState the process state at or below which to preserve
5572     *                     processes, or {@code -1} to ignore the process state
5573     */
5574    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5575        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5576                != PackageManager.PERMISSION_GRANTED) {
5577            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5578                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5579                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5580            Slog.w(TAG, msg);
5581            throw new SecurityException(msg);
5582        }
5583
5584        final long callingId = Binder.clearCallingIdentity();
5585        try {
5586            synchronized (this) {
5587                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5588                final int NP = mProcessNames.getMap().size();
5589                for (int ip = 0; ip < NP; ip++) {
5590                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5591                    final int NA = apps.size();
5592                    for (int ia = 0; ia < NA; ia++) {
5593                        final ProcessRecord app = apps.valueAt(ia);
5594                        if (app.removed) {
5595                            procs.add(app);
5596                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5597                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5598                            app.removed = true;
5599                            procs.add(app);
5600                        }
5601                    }
5602                }
5603
5604                final int N = procs.size();
5605                for (int i = 0; i < N; i++) {
5606                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5607                }
5608            }
5609        } finally {
5610            Binder.restoreCallingIdentity(callingId);
5611        }
5612    }
5613
5614    @Override
5615    public void forceStopPackage(final String packageName, int userId) {
5616        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5617                != PackageManager.PERMISSION_GRANTED) {
5618            String msg = "Permission Denial: forceStopPackage() from pid="
5619                    + Binder.getCallingPid()
5620                    + ", uid=" + Binder.getCallingUid()
5621                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5622            Slog.w(TAG, msg);
5623            throw new SecurityException(msg);
5624        }
5625        final int callingPid = Binder.getCallingPid();
5626        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5627                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5628        long callingId = Binder.clearCallingIdentity();
5629        try {
5630            IPackageManager pm = AppGlobals.getPackageManager();
5631            synchronized(this) {
5632                int[] users = userId == UserHandle.USER_ALL
5633                        ? mUserController.getUsers() : new int[] { userId };
5634                for (int user : users) {
5635                    int pkgUid = -1;
5636                    try {
5637                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5638                                user);
5639                    } catch (RemoteException e) {
5640                    }
5641                    if (pkgUid == -1) {
5642                        Slog.w(TAG, "Invalid packageName: " + packageName);
5643                        continue;
5644                    }
5645                    try {
5646                        pm.setPackageStoppedState(packageName, true, user);
5647                    } catch (RemoteException e) {
5648                    } catch (IllegalArgumentException e) {
5649                        Slog.w(TAG, "Failed trying to unstop package "
5650                                + packageName + ": " + e);
5651                    }
5652                    if (mUserController.isUserRunningLocked(user, 0)) {
5653                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5654                        finishForceStopPackageLocked(packageName, pkgUid);
5655                    }
5656                }
5657            }
5658        } finally {
5659            Binder.restoreCallingIdentity(callingId);
5660        }
5661    }
5662
5663    @Override
5664    public void addPackageDependency(String packageName) {
5665        synchronized (this) {
5666            int callingPid = Binder.getCallingPid();
5667            if (callingPid == Process.myPid()) {
5668                //  Yeah, um, no.
5669                return;
5670            }
5671            ProcessRecord proc;
5672            synchronized (mPidsSelfLocked) {
5673                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5674            }
5675            if (proc != null) {
5676                if (proc.pkgDeps == null) {
5677                    proc.pkgDeps = new ArraySet<String>(1);
5678                }
5679                proc.pkgDeps.add(packageName);
5680            }
5681        }
5682    }
5683
5684    /*
5685     * The pkg name and app id have to be specified.
5686     */
5687    @Override
5688    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5689        if (pkg == null) {
5690            return;
5691        }
5692        // Make sure the uid is valid.
5693        if (appid < 0) {
5694            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5695            return;
5696        }
5697        int callerUid = Binder.getCallingUid();
5698        // Only the system server can kill an application
5699        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5700            // Post an aysnc message to kill the application
5701            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5702            msg.arg1 = appid;
5703            msg.arg2 = 0;
5704            Bundle bundle = new Bundle();
5705            bundle.putString("pkg", pkg);
5706            bundle.putString("reason", reason);
5707            msg.obj = bundle;
5708            mHandler.sendMessage(msg);
5709        } else {
5710            throw new SecurityException(callerUid + " cannot kill pkg: " +
5711                    pkg);
5712        }
5713    }
5714
5715    @Override
5716    public void closeSystemDialogs(String reason) {
5717        enforceNotIsolatedCaller("closeSystemDialogs");
5718
5719        final int pid = Binder.getCallingPid();
5720        final int uid = Binder.getCallingUid();
5721        final long origId = Binder.clearCallingIdentity();
5722        try {
5723            synchronized (this) {
5724                // Only allow this from foreground processes, so that background
5725                // applications can't abuse it to prevent system UI from being shown.
5726                if (uid >= Process.FIRST_APPLICATION_UID) {
5727                    ProcessRecord proc;
5728                    synchronized (mPidsSelfLocked) {
5729                        proc = mPidsSelfLocked.get(pid);
5730                    }
5731                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5732                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5733                                + " from background process " + proc);
5734                        return;
5735                    }
5736                }
5737                closeSystemDialogsLocked(reason);
5738            }
5739        } finally {
5740            Binder.restoreCallingIdentity(origId);
5741        }
5742    }
5743
5744    void closeSystemDialogsLocked(String reason) {
5745        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5746        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5747                | Intent.FLAG_RECEIVER_FOREGROUND);
5748        if (reason != null) {
5749            intent.putExtra("reason", reason);
5750        }
5751        mWindowManager.closeSystemDialogs(reason);
5752
5753        mStackSupervisor.closeSystemDialogsLocked();
5754
5755        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5756                AppOpsManager.OP_NONE, null, false, false,
5757                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5758    }
5759
5760    @Override
5761    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5762        enforceNotIsolatedCaller("getProcessMemoryInfo");
5763        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5764        for (int i=pids.length-1; i>=0; i--) {
5765            ProcessRecord proc;
5766            int oomAdj;
5767            synchronized (this) {
5768                synchronized (mPidsSelfLocked) {
5769                    proc = mPidsSelfLocked.get(pids[i]);
5770                    oomAdj = proc != null ? proc.setAdj : 0;
5771                }
5772            }
5773            infos[i] = new Debug.MemoryInfo();
5774            Debug.getMemoryInfo(pids[i], infos[i]);
5775            if (proc != null) {
5776                synchronized (this) {
5777                    if (proc.thread != null && proc.setAdj == oomAdj) {
5778                        // Record this for posterity if the process has been stable.
5779                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5780                                infos[i].getTotalUss(), false, proc.pkgList);
5781                    }
5782                }
5783            }
5784        }
5785        return infos;
5786    }
5787
5788    @Override
5789    public long[] getProcessPss(int[] pids) {
5790        enforceNotIsolatedCaller("getProcessPss");
5791        long[] pss = new long[pids.length];
5792        for (int i=pids.length-1; i>=0; i--) {
5793            ProcessRecord proc;
5794            int oomAdj;
5795            synchronized (this) {
5796                synchronized (mPidsSelfLocked) {
5797                    proc = mPidsSelfLocked.get(pids[i]);
5798                    oomAdj = proc != null ? proc.setAdj : 0;
5799                }
5800            }
5801            long[] tmpUss = new long[1];
5802            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5803            if (proc != null) {
5804                synchronized (this) {
5805                    if (proc.thread != null && proc.setAdj == oomAdj) {
5806                        // Record this for posterity if the process has been stable.
5807                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5808                    }
5809                }
5810            }
5811        }
5812        return pss;
5813    }
5814
5815    @Override
5816    public void killApplicationProcess(String processName, int uid) {
5817        if (processName == null) {
5818            return;
5819        }
5820
5821        int callerUid = Binder.getCallingUid();
5822        // Only the system server can kill an application
5823        if (callerUid == Process.SYSTEM_UID) {
5824            synchronized (this) {
5825                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5826                if (app != null && app.thread != null) {
5827                    try {
5828                        app.thread.scheduleSuicide();
5829                    } catch (RemoteException e) {
5830                        // If the other end already died, then our work here is done.
5831                    }
5832                } else {
5833                    Slog.w(TAG, "Process/uid not found attempting kill of "
5834                            + processName + " / " + uid);
5835                }
5836            }
5837        } else {
5838            throw new SecurityException(callerUid + " cannot kill app process: " +
5839                    processName);
5840        }
5841    }
5842
5843    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5844        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5845                false, true, false, false, UserHandle.getUserId(uid), reason);
5846    }
5847
5848    private void finishForceStopPackageLocked(final String packageName, int uid) {
5849        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5850                Uri.fromParts("package", packageName, null));
5851        if (!mProcessesReady) {
5852            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5853                    | Intent.FLAG_RECEIVER_FOREGROUND);
5854        }
5855        intent.putExtra(Intent.EXTRA_UID, uid);
5856        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5857        broadcastIntentLocked(null, null, intent,
5858                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5859                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5860    }
5861
5862
5863    private final boolean killPackageProcessesLocked(String packageName, int appId,
5864            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5865            boolean doit, boolean evenPersistent, String reason) {
5866        ArrayList<ProcessRecord> procs = new ArrayList<>();
5867
5868        // Remove all processes this package may have touched: all with the
5869        // same UID (except for the system or root user), and all whose name
5870        // matches the package name.
5871        final int NP = mProcessNames.getMap().size();
5872        for (int ip=0; ip<NP; ip++) {
5873            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5874            final int NA = apps.size();
5875            for (int ia=0; ia<NA; ia++) {
5876                ProcessRecord app = apps.valueAt(ia);
5877                if (app.persistent && !evenPersistent) {
5878                    // we don't kill persistent processes
5879                    continue;
5880                }
5881                if (app.removed) {
5882                    if (doit) {
5883                        procs.add(app);
5884                    }
5885                    continue;
5886                }
5887
5888                // Skip process if it doesn't meet our oom adj requirement.
5889                if (app.setAdj < minOomAdj) {
5890                    continue;
5891                }
5892
5893                // If no package is specified, we call all processes under the
5894                // give user id.
5895                if (packageName == null) {
5896                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5897                        continue;
5898                    }
5899                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5900                        continue;
5901                    }
5902                // Package has been specified, we want to hit all processes
5903                // that match it.  We need to qualify this by the processes
5904                // that are running under the specified app and user ID.
5905                } else {
5906                    final boolean isDep = app.pkgDeps != null
5907                            && app.pkgDeps.contains(packageName);
5908                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5909                        continue;
5910                    }
5911                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5912                        continue;
5913                    }
5914                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5915                        continue;
5916                    }
5917                }
5918
5919                // Process has passed all conditions, kill it!
5920                if (!doit) {
5921                    return true;
5922                }
5923                app.removed = true;
5924                procs.add(app);
5925            }
5926        }
5927
5928        int N = procs.size();
5929        for (int i=0; i<N; i++) {
5930            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5931        }
5932        updateOomAdjLocked();
5933        return N > 0;
5934    }
5935
5936    private void cleanupDisabledPackageComponentsLocked(
5937            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5938
5939        Set<String> disabledClasses = null;
5940        boolean packageDisabled = false;
5941        IPackageManager pm = AppGlobals.getPackageManager();
5942
5943        if (changedClasses == null) {
5944            // Nothing changed...
5945            return;
5946        }
5947
5948        // Determine enable/disable state of the package and its components.
5949        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5950        for (int i = changedClasses.length - 1; i >= 0; i--) {
5951            final String changedClass = changedClasses[i];
5952
5953            if (changedClass.equals(packageName)) {
5954                try {
5955                    // Entire package setting changed
5956                    enabled = pm.getApplicationEnabledSetting(packageName,
5957                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5958                } catch (Exception e) {
5959                    // No such package/component; probably racing with uninstall.  In any
5960                    // event it means we have nothing further to do here.
5961                    return;
5962                }
5963                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5964                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5965                if (packageDisabled) {
5966                    // Entire package is disabled.
5967                    // No need to continue to check component states.
5968                    disabledClasses = null;
5969                    break;
5970                }
5971            } else {
5972                try {
5973                    enabled = pm.getComponentEnabledSetting(
5974                            new ComponentName(packageName, changedClass),
5975                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5976                } catch (Exception e) {
5977                    // As above, probably racing with uninstall.
5978                    return;
5979                }
5980                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5981                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5982                    if (disabledClasses == null) {
5983                        disabledClasses = new ArraySet<>(changedClasses.length);
5984                    }
5985                    disabledClasses.add(changedClass);
5986                }
5987            }
5988        }
5989
5990        if (!packageDisabled && disabledClasses == null) {
5991            // Nothing to do here...
5992            return;
5993        }
5994
5995        // Clean-up disabled activities.
5996        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5997                packageName, disabledClasses, true, false, userId) && mBooted) {
5998            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5999            mStackSupervisor.scheduleIdleLocked();
6000        }
6001
6002        // Clean-up disabled tasks
6003        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6004
6005        // Clean-up disabled services.
6006        mServices.bringDownDisabledPackageServicesLocked(
6007                packageName, disabledClasses, userId, false, killProcess, true);
6008
6009        // Clean-up disabled providers.
6010        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6011        mProviderMap.collectPackageProvidersLocked(
6012                packageName, disabledClasses, true, false, userId, providers);
6013        for (int i = providers.size() - 1; i >= 0; i--) {
6014            removeDyingProviderLocked(null, providers.get(i), true);
6015        }
6016
6017        // Clean-up disabled broadcast receivers.
6018        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6019            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6020                    packageName, disabledClasses, userId, true);
6021        }
6022
6023    }
6024
6025    final boolean clearBroadcastQueueForUserLocked(int userId) {
6026        boolean didSomething = false;
6027        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6028            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6029                    null, null, userId, true);
6030        }
6031        return didSomething;
6032    }
6033
6034    final boolean forceStopPackageLocked(String packageName, int appId,
6035            boolean callerWillRestart, boolean purgeCache, boolean doit,
6036            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6037        int i;
6038
6039        if (userId == UserHandle.USER_ALL && packageName == null) {
6040            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6041        }
6042
6043        if (appId < 0 && packageName != null) {
6044            try {
6045                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6046                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6047            } catch (RemoteException e) {
6048            }
6049        }
6050
6051        if (doit) {
6052            if (packageName != null) {
6053                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6054                        + " user=" + userId + ": " + reason);
6055            } else {
6056                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6057            }
6058
6059            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6060        }
6061
6062        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6063                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6064                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6065
6066        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6067                packageName, null, doit, evenPersistent, userId)) {
6068            if (!doit) {
6069                return true;
6070            }
6071            didSomething = true;
6072        }
6073
6074        if (mServices.bringDownDisabledPackageServicesLocked(
6075                packageName, null, userId, evenPersistent, true, doit)) {
6076            if (!doit) {
6077                return true;
6078            }
6079            didSomething = true;
6080        }
6081
6082        if (packageName == null) {
6083            // Remove all sticky broadcasts from this user.
6084            mStickyBroadcasts.remove(userId);
6085        }
6086
6087        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6088        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6089                userId, providers)) {
6090            if (!doit) {
6091                return true;
6092            }
6093            didSomething = true;
6094        }
6095        for (i = providers.size() - 1; i >= 0; i--) {
6096            removeDyingProviderLocked(null, providers.get(i), true);
6097        }
6098
6099        // Remove transient permissions granted from/to this package/user
6100        removeUriPermissionsForPackageLocked(packageName, userId, false);
6101
6102        if (doit) {
6103            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6104                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6105                        packageName, null, userId, doit);
6106            }
6107        }
6108
6109        if (packageName == null || uninstalling) {
6110            // Remove pending intents.  For now we only do this when force
6111            // stopping users, because we have some problems when doing this
6112            // for packages -- app widgets are not currently cleaned up for
6113            // such packages, so they can be left with bad pending intents.
6114            if (mIntentSenderRecords.size() > 0) {
6115                Iterator<WeakReference<PendingIntentRecord>> it
6116                        = mIntentSenderRecords.values().iterator();
6117                while (it.hasNext()) {
6118                    WeakReference<PendingIntentRecord> wpir = it.next();
6119                    if (wpir == null) {
6120                        it.remove();
6121                        continue;
6122                    }
6123                    PendingIntentRecord pir = wpir.get();
6124                    if (pir == null) {
6125                        it.remove();
6126                        continue;
6127                    }
6128                    if (packageName == null) {
6129                        // Stopping user, remove all objects for the user.
6130                        if (pir.key.userId != userId) {
6131                            // Not the same user, skip it.
6132                            continue;
6133                        }
6134                    } else {
6135                        if (UserHandle.getAppId(pir.uid) != appId) {
6136                            // Different app id, skip it.
6137                            continue;
6138                        }
6139                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6140                            // Different user, skip it.
6141                            continue;
6142                        }
6143                        if (!pir.key.packageName.equals(packageName)) {
6144                            // Different package, skip it.
6145                            continue;
6146                        }
6147                    }
6148                    if (!doit) {
6149                        return true;
6150                    }
6151                    didSomething = true;
6152                    it.remove();
6153                    pir.canceled = true;
6154                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6155                        pir.key.activity.pendingResults.remove(pir.ref);
6156                    }
6157                }
6158            }
6159        }
6160
6161        if (doit) {
6162            if (purgeCache && packageName != null) {
6163                AttributeCache ac = AttributeCache.instance();
6164                if (ac != null) {
6165                    ac.removePackage(packageName);
6166                }
6167            }
6168            if (mBooted) {
6169                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6170                mStackSupervisor.scheduleIdleLocked();
6171            }
6172        }
6173
6174        return didSomething;
6175    }
6176
6177    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6178        ProcessRecord old = mProcessNames.remove(name, uid);
6179        if (old != null) {
6180            old.uidRecord.numProcs--;
6181            if (old.uidRecord.numProcs == 0) {
6182                // No more processes using this uid, tell clients it is gone.
6183                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6184                        "No more processes in " + old.uidRecord);
6185                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6186                mActiveUids.remove(uid);
6187                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6188            }
6189            old.uidRecord = null;
6190        }
6191        mIsolatedProcesses.remove(uid);
6192        return old;
6193    }
6194
6195    private final void addProcessNameLocked(ProcessRecord proc) {
6196        // We shouldn't already have a process under this name, but just in case we
6197        // need to clean up whatever may be there now.
6198        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6199        if (old == proc && proc.persistent) {
6200            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6201            Slog.w(TAG, "Re-adding persistent process " + proc);
6202        } else if (old != null) {
6203            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6204        }
6205        UidRecord uidRec = mActiveUids.get(proc.uid);
6206        if (uidRec == null) {
6207            uidRec = new UidRecord(proc.uid);
6208            // This is the first appearance of the uid, report it now!
6209            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6210                    "Creating new process uid: " + uidRec);
6211            mActiveUids.put(proc.uid, uidRec);
6212            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6213            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6214        }
6215        proc.uidRecord = uidRec;
6216        uidRec.numProcs++;
6217        mProcessNames.put(proc.processName, proc.uid, proc);
6218        if (proc.isolated) {
6219            mIsolatedProcesses.put(proc.uid, proc);
6220        }
6221    }
6222
6223    boolean removeProcessLocked(ProcessRecord app,
6224            boolean callerWillRestart, boolean allowRestart, String reason) {
6225        final String name = app.processName;
6226        final int uid = app.uid;
6227        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6228            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6229
6230        ProcessRecord old = mProcessNames.get(name, uid);
6231        if (old != app) {
6232            // This process is no longer active, so nothing to do.
6233            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6234            return false;
6235        }
6236        removeProcessNameLocked(name, uid);
6237        if (mHeavyWeightProcess == app) {
6238            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6239                    mHeavyWeightProcess.userId, 0));
6240            mHeavyWeightProcess = null;
6241        }
6242        boolean needRestart = false;
6243        if (app.pid > 0 && app.pid != MY_PID) {
6244            int pid = app.pid;
6245            synchronized (mPidsSelfLocked) {
6246                mPidsSelfLocked.remove(pid);
6247                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6248            }
6249            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6250            if (app.isolated) {
6251                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6252            }
6253            boolean willRestart = false;
6254            if (app.persistent && !app.isolated) {
6255                if (!callerWillRestart) {
6256                    willRestart = true;
6257                } else {
6258                    needRestart = true;
6259                }
6260            }
6261            app.kill(reason, true);
6262            handleAppDiedLocked(app, willRestart, allowRestart);
6263            if (willRestart) {
6264                removeLruProcessLocked(app);
6265                addAppLocked(app.info, false, null /* ABI override */);
6266            }
6267        } else {
6268            mRemovedProcesses.add(app);
6269        }
6270
6271        return needRestart;
6272    }
6273
6274    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6275        cleanupAppInLaunchingProvidersLocked(app, true);
6276        removeProcessLocked(app, false, true, "timeout publishing content providers");
6277    }
6278
6279    private final void processStartTimedOutLocked(ProcessRecord app) {
6280        final int pid = app.pid;
6281        boolean gone = false;
6282        synchronized (mPidsSelfLocked) {
6283            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6284            if (knownApp != null && knownApp.thread == null) {
6285                mPidsSelfLocked.remove(pid);
6286                gone = true;
6287            }
6288        }
6289
6290        if (gone) {
6291            Slog.w(TAG, "Process " + app + " failed to attach");
6292            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6293                    pid, app.uid, app.processName);
6294            removeProcessNameLocked(app.processName, app.uid);
6295            if (mHeavyWeightProcess == app) {
6296                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6297                        mHeavyWeightProcess.userId, 0));
6298                mHeavyWeightProcess = null;
6299            }
6300            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6301            if (app.isolated) {
6302                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6303            }
6304            // Take care of any launching providers waiting for this process.
6305            cleanupAppInLaunchingProvidersLocked(app, true);
6306            // Take care of any services that are waiting for the process.
6307            mServices.processStartTimedOutLocked(app);
6308            app.kill("start timeout", true);
6309            removeLruProcessLocked(app);
6310            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6311                Slog.w(TAG, "Unattached app died before backup, skipping");
6312                try {
6313                    IBackupManager bm = IBackupManager.Stub.asInterface(
6314                            ServiceManager.getService(Context.BACKUP_SERVICE));
6315                    bm.agentDisconnected(app.info.packageName);
6316                } catch (RemoteException e) {
6317                    // Can't happen; the backup manager is local
6318                }
6319            }
6320            if (isPendingBroadcastProcessLocked(pid)) {
6321                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6322                skipPendingBroadcastLocked(pid);
6323            }
6324        } else {
6325            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6326        }
6327    }
6328
6329    private final boolean attachApplicationLocked(IApplicationThread thread,
6330            int pid) {
6331
6332        // Find the application record that is being attached...  either via
6333        // the pid if we are running in multiple processes, or just pull the
6334        // next app record if we are emulating process with anonymous threads.
6335        ProcessRecord app;
6336        if (pid != MY_PID && pid >= 0) {
6337            synchronized (mPidsSelfLocked) {
6338                app = mPidsSelfLocked.get(pid);
6339            }
6340        } else {
6341            app = null;
6342        }
6343
6344        if (app == null) {
6345            Slog.w(TAG, "No pending application record for pid " + pid
6346                    + " (IApplicationThread " + thread + "); dropping process");
6347            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6348            if (pid > 0 && pid != MY_PID) {
6349                Process.killProcessQuiet(pid);
6350                //TODO: killProcessGroup(app.info.uid, pid);
6351            } else {
6352                try {
6353                    thread.scheduleExit();
6354                } catch (Exception e) {
6355                    // Ignore exceptions.
6356                }
6357            }
6358            return false;
6359        }
6360
6361        // If this application record is still attached to a previous
6362        // process, clean it up now.
6363        if (app.thread != null) {
6364            handleAppDiedLocked(app, true, true);
6365        }
6366
6367        // Tell the process all about itself.
6368
6369        if (DEBUG_ALL) Slog.v(
6370                TAG, "Binding process pid " + pid + " to record " + app);
6371
6372        final String processName = app.processName;
6373        try {
6374            AppDeathRecipient adr = new AppDeathRecipient(
6375                    app, pid, thread);
6376            thread.asBinder().linkToDeath(adr, 0);
6377            app.deathRecipient = adr;
6378        } catch (RemoteException e) {
6379            app.resetPackageList(mProcessStats);
6380            startProcessLocked(app, "link fail", processName);
6381            return false;
6382        }
6383
6384        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6385
6386        app.makeActive(thread, mProcessStats);
6387        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6388        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6389        app.forcingToForeground = null;
6390        updateProcessForegroundLocked(app, false, false);
6391        app.hasShownUi = false;
6392        app.debugging = false;
6393        app.cached = false;
6394        app.killedByAm = false;
6395
6396        // We carefully use the same state that PackageManager uses for
6397        // filtering, since we use this flag to decide if we need to install
6398        // providers when user is unlocked later
6399        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6400
6401        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6402
6403        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6404        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6405
6406        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6407            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6408            msg.obj = app;
6409            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6410        }
6411
6412        if (!normalMode) {
6413            Slog.i(TAG, "Launching preboot mode app: " + app);
6414        }
6415
6416        if (DEBUG_ALL) Slog.v(
6417            TAG, "New app record " + app
6418            + " thread=" + thread.asBinder() + " pid=" + pid);
6419        try {
6420            int testMode = IApplicationThread.DEBUG_OFF;
6421            if (mDebugApp != null && mDebugApp.equals(processName)) {
6422                testMode = mWaitForDebugger
6423                    ? IApplicationThread.DEBUG_WAIT
6424                    : IApplicationThread.DEBUG_ON;
6425                app.debugging = true;
6426                if (mDebugTransient) {
6427                    mDebugApp = mOrigDebugApp;
6428                    mWaitForDebugger = mOrigWaitForDebugger;
6429                }
6430            }
6431            String profileFile = app.instrumentationProfileFile;
6432            ParcelFileDescriptor profileFd = null;
6433            int samplingInterval = 0;
6434            boolean profileAutoStop = false;
6435            if (mProfileApp != null && mProfileApp.equals(processName)) {
6436                mProfileProc = app;
6437                profileFile = mProfileFile;
6438                profileFd = mProfileFd;
6439                samplingInterval = mSamplingInterval;
6440                profileAutoStop = mAutoStopProfiler;
6441            }
6442            boolean enableTrackAllocation = false;
6443            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6444                enableTrackAllocation = true;
6445                mTrackAllocationApp = null;
6446            }
6447
6448            // If the app is being launched for restore or full backup, set it up specially
6449            boolean isRestrictedBackupMode = false;
6450            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6451                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6452                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6453                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6454                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6455            }
6456
6457            if (app.instrumentationClass != null) {
6458                notifyPackageUse(app.instrumentationClass.getPackageName(),
6459                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6460            }
6461            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6462                    + processName + " with config " + mConfiguration);
6463            ApplicationInfo appInfo = app.instrumentationInfo != null
6464                    ? app.instrumentationInfo : app.info;
6465            app.compat = compatibilityInfoForPackageLocked(appInfo);
6466            if (profileFd != null) {
6467                profileFd = profileFd.dup();
6468            }
6469            ProfilerInfo profilerInfo = profileFile == null ? null
6470                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6471            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6472                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6473                    app.instrumentationUiAutomationConnection, testMode,
6474                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6475                    isRestrictedBackupMode || !normalMode, app.persistent,
6476                    new Configuration(mConfiguration), app.compat,
6477                    getCommonServicesLocked(app.isolated),
6478                    mCoreSettingsObserver.getCoreSettingsLocked());
6479            updateLruProcessLocked(app, false, null);
6480            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6481        } catch (Exception e) {
6482            // todo: Yikes!  What should we do?  For now we will try to
6483            // start another process, but that could easily get us in
6484            // an infinite loop of restarting processes...
6485            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6486
6487            app.resetPackageList(mProcessStats);
6488            app.unlinkDeathRecipient();
6489            startProcessLocked(app, "bind fail", processName);
6490            return false;
6491        }
6492
6493        // Remove this record from the list of starting applications.
6494        mPersistentStartingProcesses.remove(app);
6495        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6496                "Attach application locked removing on hold: " + app);
6497        mProcessesOnHold.remove(app);
6498
6499        boolean badApp = false;
6500        boolean didSomething = false;
6501
6502        // See if the top visible activity is waiting to run in this process...
6503        if (normalMode) {
6504            try {
6505                if (mStackSupervisor.attachApplicationLocked(app)) {
6506                    didSomething = true;
6507                }
6508            } catch (Exception e) {
6509                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6510                badApp = true;
6511            }
6512        }
6513
6514        // Find any services that should be running in this process...
6515        if (!badApp) {
6516            try {
6517                didSomething |= mServices.attachApplicationLocked(app, processName);
6518            } catch (Exception e) {
6519                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6520                badApp = true;
6521            }
6522        }
6523
6524        // Check if a next-broadcast receiver is in this process...
6525        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6526            try {
6527                didSomething |= sendPendingBroadcastsLocked(app);
6528            } catch (Exception e) {
6529                // If the app died trying to launch the receiver we declare it 'bad'
6530                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6531                badApp = true;
6532            }
6533        }
6534
6535        // Check whether the next backup agent is in this process...
6536        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6537            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6538                    "New app is backup target, launching agent for " + app);
6539            notifyPackageUse(mBackupTarget.appInfo.packageName,
6540                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6541            try {
6542                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6543                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6544                        mBackupTarget.backupMode);
6545            } catch (Exception e) {
6546                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6547                badApp = true;
6548            }
6549        }
6550
6551        if (badApp) {
6552            app.kill("error during init", true);
6553            handleAppDiedLocked(app, false, true);
6554            return false;
6555        }
6556
6557        if (!didSomething) {
6558            updateOomAdjLocked();
6559        }
6560
6561        return true;
6562    }
6563
6564    @Override
6565    public final void attachApplication(IApplicationThread thread) {
6566        synchronized (this) {
6567            int callingPid = Binder.getCallingPid();
6568            final long origId = Binder.clearCallingIdentity();
6569            attachApplicationLocked(thread, callingPid);
6570            Binder.restoreCallingIdentity(origId);
6571        }
6572    }
6573
6574    @Override
6575    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6576        final long origId = Binder.clearCallingIdentity();
6577        synchronized (this) {
6578            ActivityStack stack = ActivityRecord.getStackLocked(token);
6579            if (stack != null) {
6580                ActivityRecord r =
6581                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6582                if (stopProfiling) {
6583                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6584                        try {
6585                            mProfileFd.close();
6586                        } catch (IOException e) {
6587                        }
6588                        clearProfilerLocked();
6589                    }
6590                }
6591            }
6592        }
6593        Binder.restoreCallingIdentity(origId);
6594    }
6595
6596    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6597        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6598                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6599    }
6600
6601    void enableScreenAfterBoot() {
6602        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6603                SystemClock.uptimeMillis());
6604        mWindowManager.enableScreenAfterBoot();
6605
6606        synchronized (this) {
6607            updateEventDispatchingLocked();
6608        }
6609    }
6610
6611    @Override
6612    public void showBootMessage(final CharSequence msg, final boolean always) {
6613        if (Binder.getCallingUid() != Process.myUid()) {
6614            // These days only the core system can call this, so apps can't get in
6615            // the way of what we show about running them.
6616        }
6617        mWindowManager.showBootMessage(msg, always);
6618    }
6619
6620    @Override
6621    public void keyguardWaitingForActivityDrawn() {
6622        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6623        final long token = Binder.clearCallingIdentity();
6624        try {
6625            synchronized (this) {
6626                if (DEBUG_LOCKSCREEN) logLockScreen("");
6627                mWindowManager.keyguardWaitingForActivityDrawn();
6628                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6629                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6630                    updateSleepIfNeededLocked();
6631                }
6632            }
6633        } finally {
6634            Binder.restoreCallingIdentity(token);
6635        }
6636    }
6637
6638    @Override
6639    public void keyguardGoingAway(int flags) {
6640        enforceNotIsolatedCaller("keyguardGoingAway");
6641        final long token = Binder.clearCallingIdentity();
6642        try {
6643            synchronized (this) {
6644                if (DEBUG_LOCKSCREEN) logLockScreen("");
6645                mWindowManager.keyguardGoingAway(flags);
6646                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6647                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6648                    updateSleepIfNeededLocked();
6649
6650                    // Some stack visibility might change (e.g. docked stack)
6651                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6652                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6653                }
6654            }
6655        } finally {
6656            Binder.restoreCallingIdentity(token);
6657        }
6658    }
6659
6660    final void finishBooting() {
6661        synchronized (this) {
6662            if (!mBootAnimationComplete) {
6663                mCallFinishBooting = true;
6664                return;
6665            }
6666            mCallFinishBooting = false;
6667        }
6668
6669        ArraySet<String> completedIsas = new ArraySet<String>();
6670        for (String abi : Build.SUPPORTED_ABIS) {
6671            Process.establishZygoteConnectionForAbi(abi);
6672            final String instructionSet = VMRuntime.getInstructionSet(abi);
6673            if (!completedIsas.contains(instructionSet)) {
6674                try {
6675                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6676                } catch (InstallerException e) {
6677                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6678                            e.getMessage() +")");
6679                }
6680                completedIsas.add(instructionSet);
6681            }
6682        }
6683
6684        IntentFilter pkgFilter = new IntentFilter();
6685        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6686        pkgFilter.addDataScheme("package");
6687        mContext.registerReceiver(new BroadcastReceiver() {
6688            @Override
6689            public void onReceive(Context context, Intent intent) {
6690                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6691                if (pkgs != null) {
6692                    for (String pkg : pkgs) {
6693                        synchronized (ActivityManagerService.this) {
6694                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6695                                    0, "query restart")) {
6696                                setResultCode(Activity.RESULT_OK);
6697                                return;
6698                            }
6699                        }
6700                    }
6701                }
6702            }
6703        }, pkgFilter);
6704
6705        IntentFilter dumpheapFilter = new IntentFilter();
6706        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6707        mContext.registerReceiver(new BroadcastReceiver() {
6708            @Override
6709            public void onReceive(Context context, Intent intent) {
6710                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6711                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6712                } else {
6713                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6714                }
6715            }
6716        }, dumpheapFilter);
6717
6718        // Let system services know.
6719        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6720
6721        synchronized (this) {
6722            // Ensure that any processes we had put on hold are now started
6723            // up.
6724            final int NP = mProcessesOnHold.size();
6725            if (NP > 0) {
6726                ArrayList<ProcessRecord> procs =
6727                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6728                for (int ip=0; ip<NP; ip++) {
6729                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6730                            + procs.get(ip));
6731                    startProcessLocked(procs.get(ip), "on-hold", null);
6732                }
6733            }
6734
6735            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6736                // Start looking for apps that are abusing wake locks.
6737                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6738                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6739                // Tell anyone interested that we are done booting!
6740                SystemProperties.set("sys.boot_completed", "1");
6741
6742                // And trigger dev.bootcomplete if we are not showing encryption progress
6743                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6744                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6745                    SystemProperties.set("dev.bootcomplete", "1");
6746                }
6747                mUserController.sendBootCompletedLocked(
6748                        new IIntentReceiver.Stub() {
6749                            @Override
6750                            public void performReceive(Intent intent, int resultCode,
6751                                    String data, Bundle extras, boolean ordered,
6752                                    boolean sticky, int sendingUser) {
6753                                synchronized (ActivityManagerService.this) {
6754                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6755                                            true, false);
6756                                }
6757                            }
6758                        });
6759                scheduleStartProfilesLocked();
6760            }
6761        }
6762    }
6763
6764    @Override
6765    public void bootAnimationComplete() {
6766        final boolean callFinishBooting;
6767        synchronized (this) {
6768            callFinishBooting = mCallFinishBooting;
6769            mBootAnimationComplete = true;
6770        }
6771        if (callFinishBooting) {
6772            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6773            finishBooting();
6774            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6775        }
6776    }
6777
6778    final void ensureBootCompleted() {
6779        boolean booting;
6780        boolean enableScreen;
6781        synchronized (this) {
6782            booting = mBooting;
6783            mBooting = false;
6784            enableScreen = !mBooted;
6785            mBooted = true;
6786        }
6787
6788        if (booting) {
6789            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6790            finishBooting();
6791            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6792        }
6793
6794        if (enableScreen) {
6795            enableScreenAfterBoot();
6796        }
6797    }
6798
6799    @Override
6800    public final void activityResumed(IBinder token) {
6801        final long origId = Binder.clearCallingIdentity();
6802        synchronized(this) {
6803            ActivityStack stack = ActivityRecord.getStackLocked(token);
6804            if (stack != null) {
6805                stack.activityResumedLocked(token);
6806            }
6807        }
6808        Binder.restoreCallingIdentity(origId);
6809    }
6810
6811    @Override
6812    public final void activityPaused(IBinder token) {
6813        final long origId = Binder.clearCallingIdentity();
6814        synchronized(this) {
6815            ActivityStack stack = ActivityRecord.getStackLocked(token);
6816            if (stack != null) {
6817                stack.activityPausedLocked(token, false);
6818            }
6819        }
6820        Binder.restoreCallingIdentity(origId);
6821    }
6822
6823    @Override
6824    public final void activityStopped(IBinder token, Bundle icicle,
6825            PersistableBundle persistentState, CharSequence description) {
6826        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6827
6828        // Refuse possible leaked file descriptors
6829        if (icicle != null && icicle.hasFileDescriptors()) {
6830            throw new IllegalArgumentException("File descriptors passed in Bundle");
6831        }
6832
6833        final long origId = Binder.clearCallingIdentity();
6834
6835        synchronized (this) {
6836            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6837            if (r != null) {
6838                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6839            }
6840        }
6841
6842        trimApplications();
6843
6844        Binder.restoreCallingIdentity(origId);
6845    }
6846
6847    @Override
6848    public final void activityDestroyed(IBinder token) {
6849        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6850        synchronized (this) {
6851            ActivityStack stack = ActivityRecord.getStackLocked(token);
6852            if (stack != null) {
6853                stack.activityDestroyedLocked(token, "activityDestroyed");
6854            }
6855        }
6856    }
6857
6858    @Override
6859    public final void activityRelaunched(IBinder token) {
6860        final long origId = Binder.clearCallingIdentity();
6861        synchronized (this) {
6862            mStackSupervisor.activityRelaunchedLocked(token);
6863        }
6864        Binder.restoreCallingIdentity(origId);
6865    }
6866
6867    @Override
6868    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6869            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6870        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6871                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6872        synchronized (this) {
6873            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6874            if (record == null) {
6875                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6876                        + "found for: " + token);
6877            }
6878            record.setSizeConfigurations(horizontalSizeConfiguration,
6879                    verticalSizeConfigurations, smallestSizeConfigurations);
6880        }
6881    }
6882
6883    @Override
6884    public final void backgroundResourcesReleased(IBinder token) {
6885        final long origId = Binder.clearCallingIdentity();
6886        try {
6887            synchronized (this) {
6888                ActivityStack stack = ActivityRecord.getStackLocked(token);
6889                if (stack != null) {
6890                    stack.backgroundResourcesReleased();
6891                }
6892            }
6893        } finally {
6894            Binder.restoreCallingIdentity(origId);
6895        }
6896    }
6897
6898    @Override
6899    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6900        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6901    }
6902
6903    @Override
6904    public final void notifyEnterAnimationComplete(IBinder token) {
6905        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6906    }
6907
6908    @Override
6909    public String getCallingPackage(IBinder token) {
6910        synchronized (this) {
6911            ActivityRecord r = getCallingRecordLocked(token);
6912            return r != null ? r.info.packageName : null;
6913        }
6914    }
6915
6916    @Override
6917    public ComponentName getCallingActivity(IBinder token) {
6918        synchronized (this) {
6919            ActivityRecord r = getCallingRecordLocked(token);
6920            return r != null ? r.intent.getComponent() : null;
6921        }
6922    }
6923
6924    private ActivityRecord getCallingRecordLocked(IBinder token) {
6925        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926        if (r == null) {
6927            return null;
6928        }
6929        return r.resultTo;
6930    }
6931
6932    @Override
6933    public ComponentName getActivityClassForToken(IBinder token) {
6934        synchronized(this) {
6935            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6936            if (r == null) {
6937                return null;
6938            }
6939            return r.intent.getComponent();
6940        }
6941    }
6942
6943    @Override
6944    public String getPackageForToken(IBinder token) {
6945        synchronized(this) {
6946            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6947            if (r == null) {
6948                return null;
6949            }
6950            return r.packageName;
6951        }
6952    }
6953
6954    @Override
6955    public boolean isRootVoiceInteraction(IBinder token) {
6956        synchronized(this) {
6957            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6958            if (r == null) {
6959                return false;
6960            }
6961            return r.rootVoiceInteraction;
6962        }
6963    }
6964
6965    @Override
6966    public IIntentSender getIntentSender(int type,
6967            String packageName, IBinder token, String resultWho,
6968            int requestCode, Intent[] intents, String[] resolvedTypes,
6969            int flags, Bundle bOptions, int userId) {
6970        enforceNotIsolatedCaller("getIntentSender");
6971        // Refuse possible leaked file descriptors
6972        if (intents != null) {
6973            if (intents.length < 1) {
6974                throw new IllegalArgumentException("Intents array length must be >= 1");
6975            }
6976            for (int i=0; i<intents.length; i++) {
6977                Intent intent = intents[i];
6978                if (intent != null) {
6979                    if (intent.hasFileDescriptors()) {
6980                        throw new IllegalArgumentException("File descriptors passed in Intent");
6981                    }
6982                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6983                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6984                        throw new IllegalArgumentException(
6985                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6986                    }
6987                    intents[i] = new Intent(intent);
6988                }
6989            }
6990            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6991                throw new IllegalArgumentException(
6992                        "Intent array length does not match resolvedTypes length");
6993            }
6994        }
6995        if (bOptions != null) {
6996            if (bOptions.hasFileDescriptors()) {
6997                throw new IllegalArgumentException("File descriptors passed in options");
6998            }
6999        }
7000
7001        synchronized(this) {
7002            int callingUid = Binder.getCallingUid();
7003            int origUserId = userId;
7004            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7005                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7006                    ALLOW_NON_FULL, "getIntentSender", null);
7007            if (origUserId == UserHandle.USER_CURRENT) {
7008                // We don't want to evaluate this until the pending intent is
7009                // actually executed.  However, we do want to always do the
7010                // security checking for it above.
7011                userId = UserHandle.USER_CURRENT;
7012            }
7013            try {
7014                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7015                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7016                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7017                    if (!UserHandle.isSameApp(callingUid, uid)) {
7018                        String msg = "Permission Denial: getIntentSender() from pid="
7019                            + Binder.getCallingPid()
7020                            + ", uid=" + Binder.getCallingUid()
7021                            + ", (need uid=" + uid + ")"
7022                            + " is not allowed to send as package " + packageName;
7023                        Slog.w(TAG, msg);
7024                        throw new SecurityException(msg);
7025                    }
7026                }
7027
7028                return getIntentSenderLocked(type, packageName, callingUid, userId,
7029                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7030
7031            } catch (RemoteException e) {
7032                throw new SecurityException(e);
7033            }
7034        }
7035    }
7036
7037    IIntentSender getIntentSenderLocked(int type, String packageName,
7038            int callingUid, int userId, IBinder token, String resultWho,
7039            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7040            Bundle bOptions) {
7041        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7042        ActivityRecord activity = null;
7043        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7044            activity = ActivityRecord.isInStackLocked(token);
7045            if (activity == null) {
7046                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7047                return null;
7048            }
7049            if (activity.finishing) {
7050                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7051                return null;
7052            }
7053        }
7054
7055        // We're going to be splicing together extras before sending, so we're
7056        // okay poking into any contained extras.
7057        if (intents != null) {
7058            for (int i = 0; i < intents.length; i++) {
7059                intents[i].setDefusable(true);
7060            }
7061        }
7062        Bundle.setDefusable(bOptions, true);
7063
7064        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7065        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7066        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7067        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7068                |PendingIntent.FLAG_UPDATE_CURRENT);
7069
7070        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7071                type, packageName, activity, resultWho,
7072                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7073        WeakReference<PendingIntentRecord> ref;
7074        ref = mIntentSenderRecords.get(key);
7075        PendingIntentRecord rec = ref != null ? ref.get() : null;
7076        if (rec != null) {
7077            if (!cancelCurrent) {
7078                if (updateCurrent) {
7079                    if (rec.key.requestIntent != null) {
7080                        rec.key.requestIntent.replaceExtras(intents != null ?
7081                                intents[intents.length - 1] : null);
7082                    }
7083                    if (intents != null) {
7084                        intents[intents.length-1] = rec.key.requestIntent;
7085                        rec.key.allIntents = intents;
7086                        rec.key.allResolvedTypes = resolvedTypes;
7087                    } else {
7088                        rec.key.allIntents = null;
7089                        rec.key.allResolvedTypes = null;
7090                    }
7091                }
7092                return rec;
7093            }
7094            rec.canceled = true;
7095            mIntentSenderRecords.remove(key);
7096        }
7097        if (noCreate) {
7098            return rec;
7099        }
7100        rec = new PendingIntentRecord(this, key, callingUid);
7101        mIntentSenderRecords.put(key, rec.ref);
7102        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7103            if (activity.pendingResults == null) {
7104                activity.pendingResults
7105                        = new HashSet<WeakReference<PendingIntentRecord>>();
7106            }
7107            activity.pendingResults.add(rec.ref);
7108        }
7109        return rec;
7110    }
7111
7112    @Override
7113    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7114            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7115        if (target instanceof PendingIntentRecord) {
7116            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7117                    finishedReceiver, requiredPermission, options);
7118        } else {
7119            if (intent == null) {
7120                // Weird case: someone has given us their own custom IIntentSender, and now
7121                // they have someone else trying to send to it but of course this isn't
7122                // really a PendingIntent, so there is no base Intent, and the caller isn't
7123                // supplying an Intent... but we never want to dispatch a null Intent to
7124                // a receiver, so um...  let's make something up.
7125                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7126                intent = new Intent(Intent.ACTION_MAIN);
7127            }
7128            try {
7129                target.send(code, intent, resolvedType, null, requiredPermission, options);
7130            } catch (RemoteException e) {
7131            }
7132            // Platform code can rely on getting a result back when the send is done, but if
7133            // this intent sender is from outside of the system we can't rely on it doing that.
7134            // So instead we don't give it the result receiver, and instead just directly
7135            // report the finish immediately.
7136            if (finishedReceiver != null) {
7137                try {
7138                    finishedReceiver.performReceive(intent, 0,
7139                            null, null, false, false, UserHandle.getCallingUserId());
7140                } catch (RemoteException e) {
7141                }
7142            }
7143            return 0;
7144        }
7145    }
7146
7147    /**
7148     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7149     *
7150     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7151     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7152     */
7153    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7154        if (DEBUG_WHITELISTS) {
7155            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7156                    + targetUid + ", " + duration + ")");
7157        }
7158        synchronized (mPidsSelfLocked) {
7159            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7160            if (pr == null) {
7161                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7162                return;
7163            }
7164            if (!pr.whitelistManager) {
7165                if (DEBUG_WHITELISTS) {
7166                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7167                            + callerPid + " is not allowed");
7168                }
7169                return;
7170            }
7171        }
7172
7173        final long token = Binder.clearCallingIdentity();
7174        try {
7175            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7176                    true, "pe from uid:" + callerUid);
7177        } finally {
7178            Binder.restoreCallingIdentity(token);
7179        }
7180    }
7181
7182    @Override
7183    public void cancelIntentSender(IIntentSender sender) {
7184        if (!(sender instanceof PendingIntentRecord)) {
7185            return;
7186        }
7187        synchronized(this) {
7188            PendingIntentRecord rec = (PendingIntentRecord)sender;
7189            try {
7190                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7191                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7192                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7193                    String msg = "Permission Denial: cancelIntentSender() from pid="
7194                        + Binder.getCallingPid()
7195                        + ", uid=" + Binder.getCallingUid()
7196                        + " is not allowed to cancel packges "
7197                        + rec.key.packageName;
7198                    Slog.w(TAG, msg);
7199                    throw new SecurityException(msg);
7200                }
7201            } catch (RemoteException e) {
7202                throw new SecurityException(e);
7203            }
7204            cancelIntentSenderLocked(rec, true);
7205        }
7206    }
7207
7208    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7209        rec.canceled = true;
7210        mIntentSenderRecords.remove(rec.key);
7211        if (cleanActivity && rec.key.activity != null) {
7212            rec.key.activity.pendingResults.remove(rec.ref);
7213        }
7214    }
7215
7216    @Override
7217    public String getPackageForIntentSender(IIntentSender pendingResult) {
7218        if (!(pendingResult instanceof PendingIntentRecord)) {
7219            return null;
7220        }
7221        try {
7222            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7223            return res.key.packageName;
7224        } catch (ClassCastException e) {
7225        }
7226        return null;
7227    }
7228
7229    @Override
7230    public int getUidForIntentSender(IIntentSender sender) {
7231        if (sender instanceof PendingIntentRecord) {
7232            try {
7233                PendingIntentRecord res = (PendingIntentRecord)sender;
7234                return res.uid;
7235            } catch (ClassCastException e) {
7236            }
7237        }
7238        return -1;
7239    }
7240
7241    @Override
7242    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7243        if (!(pendingResult instanceof PendingIntentRecord)) {
7244            return false;
7245        }
7246        try {
7247            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7248            if (res.key.allIntents == null) {
7249                return false;
7250            }
7251            for (int i=0; i<res.key.allIntents.length; i++) {
7252                Intent intent = res.key.allIntents[i];
7253                if (intent.getPackage() != null && intent.getComponent() != null) {
7254                    return false;
7255                }
7256            }
7257            return true;
7258        } catch (ClassCastException e) {
7259        }
7260        return false;
7261    }
7262
7263    @Override
7264    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7265        if (!(pendingResult instanceof PendingIntentRecord)) {
7266            return false;
7267        }
7268        try {
7269            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7270            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7271                return true;
7272            }
7273            return false;
7274        } catch (ClassCastException e) {
7275        }
7276        return false;
7277    }
7278
7279    @Override
7280    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7281        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7282                "getIntentForIntentSender()");
7283        if (!(pendingResult instanceof PendingIntentRecord)) {
7284            return null;
7285        }
7286        try {
7287            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7288            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7289        } catch (ClassCastException e) {
7290        }
7291        return null;
7292    }
7293
7294    @Override
7295    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7296        if (!(pendingResult instanceof PendingIntentRecord)) {
7297            return null;
7298        }
7299        try {
7300            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7301            synchronized (this) {
7302                return getTagForIntentSenderLocked(res, prefix);
7303            }
7304        } catch (ClassCastException e) {
7305        }
7306        return null;
7307    }
7308
7309    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7310        final Intent intent = res.key.requestIntent;
7311        if (intent != null) {
7312            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7313                    || res.lastTagPrefix.equals(prefix))) {
7314                return res.lastTag;
7315            }
7316            res.lastTagPrefix = prefix;
7317            final StringBuilder sb = new StringBuilder(128);
7318            if (prefix != null) {
7319                sb.append(prefix);
7320            }
7321            if (intent.getAction() != null) {
7322                sb.append(intent.getAction());
7323            } else if (intent.getComponent() != null) {
7324                intent.getComponent().appendShortString(sb);
7325            } else {
7326                sb.append("?");
7327            }
7328            return res.lastTag = sb.toString();
7329        }
7330        return null;
7331    }
7332
7333    @Override
7334    public void setProcessLimit(int max) {
7335        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7336                "setProcessLimit()");
7337        synchronized (this) {
7338            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7339            mProcessLimitOverride = max;
7340        }
7341        trimApplications();
7342    }
7343
7344    @Override
7345    public int getProcessLimit() {
7346        synchronized (this) {
7347            return mProcessLimitOverride;
7348        }
7349    }
7350
7351    void foregroundTokenDied(ForegroundToken token) {
7352        synchronized (ActivityManagerService.this) {
7353            synchronized (mPidsSelfLocked) {
7354                ForegroundToken cur
7355                    = mForegroundProcesses.get(token.pid);
7356                if (cur != token) {
7357                    return;
7358                }
7359                mForegroundProcesses.remove(token.pid);
7360                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7361                if (pr == null) {
7362                    return;
7363                }
7364                pr.forcingToForeground = null;
7365                updateProcessForegroundLocked(pr, false, false);
7366            }
7367            updateOomAdjLocked();
7368        }
7369    }
7370
7371    @Override
7372    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7373        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7374                "setProcessForeground()");
7375        synchronized(this) {
7376            boolean changed = false;
7377
7378            synchronized (mPidsSelfLocked) {
7379                ProcessRecord pr = mPidsSelfLocked.get(pid);
7380                if (pr == null && isForeground) {
7381                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7382                    return;
7383                }
7384                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7385                if (oldToken != null) {
7386                    oldToken.token.unlinkToDeath(oldToken, 0);
7387                    mForegroundProcesses.remove(pid);
7388                    if (pr != null) {
7389                        pr.forcingToForeground = null;
7390                    }
7391                    changed = true;
7392                }
7393                if (isForeground && token != null) {
7394                    ForegroundToken newToken = new ForegroundToken() {
7395                        @Override
7396                        public void binderDied() {
7397                            foregroundTokenDied(this);
7398                        }
7399                    };
7400                    newToken.pid = pid;
7401                    newToken.token = token;
7402                    try {
7403                        token.linkToDeath(newToken, 0);
7404                        mForegroundProcesses.put(pid, newToken);
7405                        pr.forcingToForeground = token;
7406                        changed = true;
7407                    } catch (RemoteException e) {
7408                        // If the process died while doing this, we will later
7409                        // do the cleanup with the process death link.
7410                    }
7411                }
7412            }
7413
7414            if (changed) {
7415                updateOomAdjLocked();
7416            }
7417        }
7418    }
7419
7420    @Override
7421    public boolean isAppForeground(int uid) throws RemoteException {
7422        synchronized (this) {
7423            UidRecord uidRec = mActiveUids.get(uid);
7424            if (uidRec == null || uidRec.idle) {
7425                return false;
7426            }
7427            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7428        }
7429    }
7430
7431    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7432    // be guarded by permission checking.
7433    int getUidState(int uid) {
7434        synchronized (this) {
7435            UidRecord uidRec = mActiveUids.get(uid);
7436            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7437        }
7438    }
7439
7440    @Override
7441    public boolean isInMultiWindowMode(IBinder token) {
7442        final long origId = Binder.clearCallingIdentity();
7443        try {
7444            synchronized(this) {
7445                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7446                if (r == null) {
7447                    return false;
7448                }
7449                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7450                return !r.task.mFullscreen;
7451            }
7452        } finally {
7453            Binder.restoreCallingIdentity(origId);
7454        }
7455    }
7456
7457    @Override
7458    public boolean isInPictureInPictureMode(IBinder token) {
7459        final long origId = Binder.clearCallingIdentity();
7460        try {
7461            synchronized(this) {
7462                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7463                if (stack == null) {
7464                    return false;
7465                }
7466                return stack.mStackId == PINNED_STACK_ID;
7467            }
7468        } finally {
7469            Binder.restoreCallingIdentity(origId);
7470        }
7471    }
7472
7473    @Override
7474    public void enterPictureInPictureMode(IBinder token) {
7475        final long origId = Binder.clearCallingIdentity();
7476        try {
7477            synchronized(this) {
7478                if (!mSupportsPictureInPicture) {
7479                    throw new IllegalStateException("enterPictureInPictureMode: "
7480                            + "Device doesn't support picture-in-picture mode.");
7481                }
7482
7483                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7484
7485                if (r == null) {
7486                    throw new IllegalStateException("enterPictureInPictureMode: "
7487                            + "Can't find activity for token=" + token);
7488                }
7489
7490                if (!r.supportsPictureInPicture()) {
7491                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7492                            + "Picture-In-Picture not supported for r=" + r);
7493                }
7494
7495                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7496                // current bounds.
7497                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7498                final Rect bounds = (pinnedStack != null)
7499                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7500
7501                mStackSupervisor.moveActivityToPinnedStackLocked(
7502                        r, "enterPictureInPictureMode", bounds);
7503            }
7504        } finally {
7505            Binder.restoreCallingIdentity(origId);
7506        }
7507    }
7508
7509    // =========================================================
7510    // PROCESS INFO
7511    // =========================================================
7512
7513    static class ProcessInfoService extends IProcessInfoService.Stub {
7514        final ActivityManagerService mActivityManagerService;
7515        ProcessInfoService(ActivityManagerService activityManagerService) {
7516            mActivityManagerService = activityManagerService;
7517        }
7518
7519        @Override
7520        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7521            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7522                    /*in*/ pids, /*out*/ states, null);
7523        }
7524
7525        @Override
7526        public void getProcessStatesAndOomScoresFromPids(
7527                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7528            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7529                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7530        }
7531    }
7532
7533    /**
7534     * For each PID in the given input array, write the current process state
7535     * for that process into the states array, or -1 to indicate that no
7536     * process with the given PID exists. If scores array is provided, write
7537     * the oom score for the process into the scores array, with INVALID_ADJ
7538     * indicating the PID doesn't exist.
7539     */
7540    public void getProcessStatesAndOomScoresForPIDs(
7541            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7542        if (scores != null) {
7543            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7544                    "getProcessStatesAndOomScoresForPIDs()");
7545        }
7546
7547        if (pids == null) {
7548            throw new NullPointerException("pids");
7549        } else if (states == null) {
7550            throw new NullPointerException("states");
7551        } else if (pids.length != states.length) {
7552            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7553        } else if (scores != null && pids.length != scores.length) {
7554            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7555        }
7556
7557        synchronized (mPidsSelfLocked) {
7558            for (int i = 0; i < pids.length; i++) {
7559                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7560                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7561                        pr.curProcState;
7562                if (scores != null) {
7563                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7564                }
7565            }
7566        }
7567    }
7568
7569    // =========================================================
7570    // PERMISSIONS
7571    // =========================================================
7572
7573    static class PermissionController extends IPermissionController.Stub {
7574        ActivityManagerService mActivityManagerService;
7575        PermissionController(ActivityManagerService activityManagerService) {
7576            mActivityManagerService = activityManagerService;
7577        }
7578
7579        @Override
7580        public boolean checkPermission(String permission, int pid, int uid) {
7581            return mActivityManagerService.checkPermission(permission, pid,
7582                    uid) == PackageManager.PERMISSION_GRANTED;
7583        }
7584
7585        @Override
7586        public String[] getPackagesForUid(int uid) {
7587            return mActivityManagerService.mContext.getPackageManager()
7588                    .getPackagesForUid(uid);
7589        }
7590
7591        @Override
7592        public boolean isRuntimePermission(String permission) {
7593            try {
7594                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7595                        .getPermissionInfo(permission, 0);
7596                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7597            } catch (NameNotFoundException nnfe) {
7598                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7599            }
7600            return false;
7601        }
7602    }
7603
7604    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7605        @Override
7606        public int checkComponentPermission(String permission, int pid, int uid,
7607                int owningUid, boolean exported) {
7608            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7609                    owningUid, exported);
7610        }
7611
7612        @Override
7613        public Object getAMSLock() {
7614            return ActivityManagerService.this;
7615        }
7616    }
7617
7618    /**
7619     * This can be called with or without the global lock held.
7620     */
7621    int checkComponentPermission(String permission, int pid, int uid,
7622            int owningUid, boolean exported) {
7623        if (pid == MY_PID) {
7624            return PackageManager.PERMISSION_GRANTED;
7625        }
7626        return ActivityManager.checkComponentPermission(permission, uid,
7627                owningUid, exported);
7628    }
7629
7630    /**
7631     * As the only public entry point for permissions checking, this method
7632     * can enforce the semantic that requesting a check on a null global
7633     * permission is automatically denied.  (Internally a null permission
7634     * string is used when calling {@link #checkComponentPermission} in cases
7635     * when only uid-based security is needed.)
7636     *
7637     * This can be called with or without the global lock held.
7638     */
7639    @Override
7640    public int checkPermission(String permission, int pid, int uid) {
7641        if (permission == null) {
7642            return PackageManager.PERMISSION_DENIED;
7643        }
7644        return checkComponentPermission(permission, pid, uid, -1, true);
7645    }
7646
7647    @Override
7648    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7649        if (permission == null) {
7650            return PackageManager.PERMISSION_DENIED;
7651        }
7652
7653        // We might be performing an operation on behalf of an indirect binder
7654        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7655        // client identity accordingly before proceeding.
7656        Identity tlsIdentity = sCallerIdentity.get();
7657        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7658            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7659                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7660            uid = tlsIdentity.uid;
7661            pid = tlsIdentity.pid;
7662        }
7663
7664        return checkComponentPermission(permission, pid, uid, -1, true);
7665    }
7666
7667    /**
7668     * Binder IPC calls go through the public entry point.
7669     * This can be called with or without the global lock held.
7670     */
7671    int checkCallingPermission(String permission) {
7672        return checkPermission(permission,
7673                Binder.getCallingPid(),
7674                UserHandle.getAppId(Binder.getCallingUid()));
7675    }
7676
7677    /**
7678     * This can be called with or without the global lock held.
7679     */
7680    void enforceCallingPermission(String permission, String func) {
7681        if (checkCallingPermission(permission)
7682                == PackageManager.PERMISSION_GRANTED) {
7683            return;
7684        }
7685
7686        String msg = "Permission Denial: " + func + " from pid="
7687                + Binder.getCallingPid()
7688                + ", uid=" + Binder.getCallingUid()
7689                + " requires " + permission;
7690        Slog.w(TAG, msg);
7691        throw new SecurityException(msg);
7692    }
7693
7694    /**
7695     * Determine if UID is holding permissions required to access {@link Uri} in
7696     * the given {@link ProviderInfo}. Final permission checking is always done
7697     * in {@link ContentProvider}.
7698     */
7699    private final boolean checkHoldingPermissionsLocked(
7700            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7701        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7702                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7703        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7704            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7705                    != PERMISSION_GRANTED) {
7706                return false;
7707            }
7708        }
7709        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7710    }
7711
7712    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7713            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7714        if (pi.applicationInfo.uid == uid) {
7715            return true;
7716        } else if (!pi.exported) {
7717            return false;
7718        }
7719
7720        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7721        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7722        try {
7723            // check if target holds top-level <provider> permissions
7724            if (!readMet && pi.readPermission != null && considerUidPermissions
7725                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7726                readMet = true;
7727            }
7728            if (!writeMet && pi.writePermission != null && considerUidPermissions
7729                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7730                writeMet = true;
7731            }
7732
7733            // track if unprotected read/write is allowed; any denied
7734            // <path-permission> below removes this ability
7735            boolean allowDefaultRead = pi.readPermission == null;
7736            boolean allowDefaultWrite = pi.writePermission == null;
7737
7738            // check if target holds any <path-permission> that match uri
7739            final PathPermission[] pps = pi.pathPermissions;
7740            if (pps != null) {
7741                final String path = grantUri.uri.getPath();
7742                int i = pps.length;
7743                while (i > 0 && (!readMet || !writeMet)) {
7744                    i--;
7745                    PathPermission pp = pps[i];
7746                    if (pp.match(path)) {
7747                        if (!readMet) {
7748                            final String pprperm = pp.getReadPermission();
7749                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7750                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7751                                    + ": match=" + pp.match(path)
7752                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7753                            if (pprperm != null) {
7754                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7755                                        == PERMISSION_GRANTED) {
7756                                    readMet = true;
7757                                } else {
7758                                    allowDefaultRead = false;
7759                                }
7760                            }
7761                        }
7762                        if (!writeMet) {
7763                            final String ppwperm = pp.getWritePermission();
7764                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7765                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7766                                    + ": match=" + pp.match(path)
7767                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7768                            if (ppwperm != null) {
7769                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7770                                        == PERMISSION_GRANTED) {
7771                                    writeMet = true;
7772                                } else {
7773                                    allowDefaultWrite = false;
7774                                }
7775                            }
7776                        }
7777                    }
7778                }
7779            }
7780
7781            // grant unprotected <provider> read/write, if not blocked by
7782            // <path-permission> above
7783            if (allowDefaultRead) readMet = true;
7784            if (allowDefaultWrite) writeMet = true;
7785
7786        } catch (RemoteException e) {
7787            return false;
7788        }
7789
7790        return readMet && writeMet;
7791    }
7792
7793    public int getAppStartMode(int uid, String packageName) {
7794        synchronized (this) {
7795            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7796        }
7797    }
7798
7799    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7800            boolean allowWhenForeground) {
7801        UidRecord uidRec = mActiveUids.get(uid);
7802        if (!mLenientBackgroundCheck) {
7803            if (!allowWhenForeground || uidRec == null
7804                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7805                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7806                        packageName) != AppOpsManager.MODE_ALLOWED) {
7807                    return ActivityManager.APP_START_MODE_DELAYED;
7808                }
7809            }
7810
7811        } else if (uidRec == null || uidRec.idle) {
7812            if (callingPid >= 0) {
7813                ProcessRecord proc;
7814                synchronized (mPidsSelfLocked) {
7815                    proc = mPidsSelfLocked.get(callingPid);
7816                }
7817                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7818                    // Whoever is instigating this is in the foreground, so we will allow it
7819                    // to go through.
7820                    return ActivityManager.APP_START_MODE_NORMAL;
7821                }
7822            }
7823            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7824                    != AppOpsManager.MODE_ALLOWED) {
7825                return ActivityManager.APP_START_MODE_DELAYED;
7826            }
7827        }
7828        return ActivityManager.APP_START_MODE_NORMAL;
7829    }
7830
7831    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7832        ProviderInfo pi = null;
7833        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7834        if (cpr != null) {
7835            pi = cpr.info;
7836        } else {
7837            try {
7838                pi = AppGlobals.getPackageManager().resolveContentProvider(
7839                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7840                        userHandle);
7841            } catch (RemoteException ex) {
7842            }
7843        }
7844        return pi;
7845    }
7846
7847    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7848        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7849        if (targetUris != null) {
7850            return targetUris.get(grantUri);
7851        }
7852        return null;
7853    }
7854
7855    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7856            String targetPkg, int targetUid, GrantUri grantUri) {
7857        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7858        if (targetUris == null) {
7859            targetUris = Maps.newArrayMap();
7860            mGrantedUriPermissions.put(targetUid, targetUris);
7861        }
7862
7863        UriPermission perm = targetUris.get(grantUri);
7864        if (perm == null) {
7865            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7866            targetUris.put(grantUri, perm);
7867        }
7868
7869        return perm;
7870    }
7871
7872    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7873            final int modeFlags) {
7874        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7875        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7876                : UriPermission.STRENGTH_OWNED;
7877
7878        // Root gets to do everything.
7879        if (uid == 0) {
7880            return true;
7881        }
7882
7883        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7884        if (perms == null) return false;
7885
7886        // First look for exact match
7887        final UriPermission exactPerm = perms.get(grantUri);
7888        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7889            return true;
7890        }
7891
7892        // No exact match, look for prefixes
7893        final int N = perms.size();
7894        for (int i = 0; i < N; i++) {
7895            final UriPermission perm = perms.valueAt(i);
7896            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7897                    && perm.getStrength(modeFlags) >= minStrength) {
7898                return true;
7899            }
7900        }
7901
7902        return false;
7903    }
7904
7905    /**
7906     * @param uri This uri must NOT contain an embedded userId.
7907     * @param userId The userId in which the uri is to be resolved.
7908     */
7909    @Override
7910    public int checkUriPermission(Uri uri, int pid, int uid,
7911            final int modeFlags, int userId, IBinder callerToken) {
7912        enforceNotIsolatedCaller("checkUriPermission");
7913
7914        // Another redirected-binder-call permissions check as in
7915        // {@link checkPermissionWithToken}.
7916        Identity tlsIdentity = sCallerIdentity.get();
7917        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7918            uid = tlsIdentity.uid;
7919            pid = tlsIdentity.pid;
7920        }
7921
7922        // Our own process gets to do everything.
7923        if (pid == MY_PID) {
7924            return PackageManager.PERMISSION_GRANTED;
7925        }
7926        synchronized (this) {
7927            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7928                    ? PackageManager.PERMISSION_GRANTED
7929                    : PackageManager.PERMISSION_DENIED;
7930        }
7931    }
7932
7933    /**
7934     * Check if the targetPkg can be granted permission to access uri by
7935     * the callingUid using the given modeFlags.  Throws a security exception
7936     * if callingUid is not allowed to do this.  Returns the uid of the target
7937     * if the URI permission grant should be performed; returns -1 if it is not
7938     * needed (for example targetPkg already has permission to access the URI).
7939     * If you already know the uid of the target, you can supply it in
7940     * lastTargetUid else set that to -1.
7941     */
7942    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7943            final int modeFlags, int lastTargetUid) {
7944        if (!Intent.isAccessUriMode(modeFlags)) {
7945            return -1;
7946        }
7947
7948        if (targetPkg != null) {
7949            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                    "Checking grant " + targetPkg + " permission to " + grantUri);
7951        }
7952
7953        final IPackageManager pm = AppGlobals.getPackageManager();
7954
7955        // If this is not a content: uri, we can't do anything with it.
7956        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7957            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7958                    "Can't grant URI permission for non-content URI: " + grantUri);
7959            return -1;
7960        }
7961
7962        final String authority = grantUri.uri.getAuthority();
7963        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7964                MATCH_DEBUG_TRIAGED_MISSING);
7965        if (pi == null) {
7966            Slog.w(TAG, "No content provider found for permission check: " +
7967                    grantUri.uri.toSafeString());
7968            return -1;
7969        }
7970
7971        int targetUid = lastTargetUid;
7972        if (targetUid < 0 && targetPkg != null) {
7973            try {
7974                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7975                        UserHandle.getUserId(callingUid));
7976                if (targetUid < 0) {
7977                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7978                            "Can't grant URI permission no uid for: " + targetPkg);
7979                    return -1;
7980                }
7981            } catch (RemoteException ex) {
7982                return -1;
7983            }
7984        }
7985
7986        if (targetUid >= 0) {
7987            // First...  does the target actually need this permission?
7988            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7989                // No need to grant the target this permission.
7990                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7991                        "Target " + targetPkg + " already has full permission to " + grantUri);
7992                return -1;
7993            }
7994        } else {
7995            // First...  there is no target package, so can anyone access it?
7996            boolean allowed = pi.exported;
7997            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7998                if (pi.readPermission != null) {
7999                    allowed = false;
8000                }
8001            }
8002            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8003                if (pi.writePermission != null) {
8004                    allowed = false;
8005                }
8006            }
8007            if (allowed) {
8008                return -1;
8009            }
8010        }
8011
8012        /* There is a special cross user grant if:
8013         * - The target is on another user.
8014         * - Apps on the current user can access the uri without any uid permissions.
8015         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8016         * grant uri permissions.
8017         */
8018        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8019                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8020                modeFlags, false /*without considering the uid permissions*/);
8021
8022        // Second...  is the provider allowing granting of URI permissions?
8023        if (!specialCrossUserGrant) {
8024            if (!pi.grantUriPermissions) {
8025                throw new SecurityException("Provider " + pi.packageName
8026                        + "/" + pi.name
8027                        + " does not allow granting of Uri permissions (uri "
8028                        + grantUri + ")");
8029            }
8030            if (pi.uriPermissionPatterns != null) {
8031                final int N = pi.uriPermissionPatterns.length;
8032                boolean allowed = false;
8033                for (int i=0; i<N; i++) {
8034                    if (pi.uriPermissionPatterns[i] != null
8035                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8036                        allowed = true;
8037                        break;
8038                    }
8039                }
8040                if (!allowed) {
8041                    throw new SecurityException("Provider " + pi.packageName
8042                            + "/" + pi.name
8043                            + " does not allow granting of permission to path of Uri "
8044                            + grantUri);
8045                }
8046            }
8047        }
8048
8049        // Third...  does the caller itself have permission to access
8050        // this uri?
8051        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8052            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8053                // Require they hold a strong enough Uri permission
8054                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8055                    throw new SecurityException("Uid " + callingUid
8056                            + " does not have permission to uri " + grantUri);
8057                }
8058            }
8059        }
8060        return targetUid;
8061    }
8062
8063    /**
8064     * @param uri This uri must NOT contain an embedded userId.
8065     * @param userId The userId in which the uri is to be resolved.
8066     */
8067    @Override
8068    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8069            final int modeFlags, int userId) {
8070        enforceNotIsolatedCaller("checkGrantUriPermission");
8071        synchronized(this) {
8072            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8073                    new GrantUri(userId, uri, false), modeFlags, -1);
8074        }
8075    }
8076
8077    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8078            final int modeFlags, UriPermissionOwner owner) {
8079        if (!Intent.isAccessUriMode(modeFlags)) {
8080            return;
8081        }
8082
8083        // So here we are: the caller has the assumed permission
8084        // to the uri, and the target doesn't.  Let's now give this to
8085        // the target.
8086
8087        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8088                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8089
8090        final String authority = grantUri.uri.getAuthority();
8091        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8092                MATCH_DEBUG_TRIAGED_MISSING);
8093        if (pi == null) {
8094            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8095            return;
8096        }
8097
8098        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8099            grantUri.prefix = true;
8100        }
8101        final UriPermission perm = findOrCreateUriPermissionLocked(
8102                pi.packageName, targetPkg, targetUid, grantUri);
8103        perm.grantModes(modeFlags, owner);
8104    }
8105
8106    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8107            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8108        if (targetPkg == null) {
8109            throw new NullPointerException("targetPkg");
8110        }
8111        int targetUid;
8112        final IPackageManager pm = AppGlobals.getPackageManager();
8113        try {
8114            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8115        } catch (RemoteException ex) {
8116            return;
8117        }
8118
8119        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8120                targetUid);
8121        if (targetUid < 0) {
8122            return;
8123        }
8124
8125        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8126                owner);
8127    }
8128
8129    static class NeededUriGrants extends ArrayList<GrantUri> {
8130        final String targetPkg;
8131        final int targetUid;
8132        final int flags;
8133
8134        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8135            this.targetPkg = targetPkg;
8136            this.targetUid = targetUid;
8137            this.flags = flags;
8138        }
8139    }
8140
8141    /**
8142     * Like checkGrantUriPermissionLocked, but takes an Intent.
8143     */
8144    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8145            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8146        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8147                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8148                + " clip=" + (intent != null ? intent.getClipData() : null)
8149                + " from " + intent + "; flags=0x"
8150                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8151
8152        if (targetPkg == null) {
8153            throw new NullPointerException("targetPkg");
8154        }
8155
8156        if (intent == null) {
8157            return null;
8158        }
8159        Uri data = intent.getData();
8160        ClipData clip = intent.getClipData();
8161        if (data == null && clip == null) {
8162            return null;
8163        }
8164        // Default userId for uris in the intent (if they don't specify it themselves)
8165        int contentUserHint = intent.getContentUserHint();
8166        if (contentUserHint == UserHandle.USER_CURRENT) {
8167            contentUserHint = UserHandle.getUserId(callingUid);
8168        }
8169        final IPackageManager pm = AppGlobals.getPackageManager();
8170        int targetUid;
8171        if (needed != null) {
8172            targetUid = needed.targetUid;
8173        } else {
8174            try {
8175                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8176                        targetUserId);
8177            } catch (RemoteException ex) {
8178                return null;
8179            }
8180            if (targetUid < 0) {
8181                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8182                        "Can't grant URI permission no uid for: " + targetPkg
8183                        + " on user " + targetUserId);
8184                return null;
8185            }
8186        }
8187        if (data != null) {
8188            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8189            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8190                    targetUid);
8191            if (targetUid > 0) {
8192                if (needed == null) {
8193                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8194                }
8195                needed.add(grantUri);
8196            }
8197        }
8198        if (clip != null) {
8199            for (int i=0; i<clip.getItemCount(); i++) {
8200                Uri uri = clip.getItemAt(i).getUri();
8201                if (uri != null) {
8202                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8203                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8204                            targetUid);
8205                    if (targetUid > 0) {
8206                        if (needed == null) {
8207                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8208                        }
8209                        needed.add(grantUri);
8210                    }
8211                } else {
8212                    Intent clipIntent = clip.getItemAt(i).getIntent();
8213                    if (clipIntent != null) {
8214                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8215                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8216                        if (newNeeded != null) {
8217                            needed = newNeeded;
8218                        }
8219                    }
8220                }
8221            }
8222        }
8223
8224        return needed;
8225    }
8226
8227    /**
8228     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8229     */
8230    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8231            UriPermissionOwner owner) {
8232        if (needed != null) {
8233            for (int i=0; i<needed.size(); i++) {
8234                GrantUri grantUri = needed.get(i);
8235                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8236                        grantUri, needed.flags, owner);
8237            }
8238        }
8239    }
8240
8241    void grantUriPermissionFromIntentLocked(int callingUid,
8242            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8243        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8244                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8245        if (needed == null) {
8246            return;
8247        }
8248
8249        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8250    }
8251
8252    /**
8253     * @param uri This uri must NOT contain an embedded userId.
8254     * @param userId The userId in which the uri is to be resolved.
8255     */
8256    @Override
8257    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8258            final int modeFlags, int userId) {
8259        enforceNotIsolatedCaller("grantUriPermission");
8260        GrantUri grantUri = new GrantUri(userId, uri, false);
8261        synchronized(this) {
8262            final ProcessRecord r = getRecordForAppLocked(caller);
8263            if (r == null) {
8264                throw new SecurityException("Unable to find app for caller "
8265                        + caller
8266                        + " when granting permission to uri " + grantUri);
8267            }
8268            if (targetPkg == null) {
8269                throw new IllegalArgumentException("null target");
8270            }
8271            if (grantUri == null) {
8272                throw new IllegalArgumentException("null uri");
8273            }
8274
8275            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8276                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8277                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8278                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8279
8280            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8281                    UserHandle.getUserId(r.uid));
8282        }
8283    }
8284
8285    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8286        if (perm.modeFlags == 0) {
8287            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8288                    perm.targetUid);
8289            if (perms != null) {
8290                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8291                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8292
8293                perms.remove(perm.uri);
8294                if (perms.isEmpty()) {
8295                    mGrantedUriPermissions.remove(perm.targetUid);
8296                }
8297            }
8298        }
8299    }
8300
8301    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8302        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8303                "Revoking all granted permissions to " + grantUri);
8304
8305        final IPackageManager pm = AppGlobals.getPackageManager();
8306        final String authority = grantUri.uri.getAuthority();
8307        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8308                MATCH_DEBUG_TRIAGED_MISSING);
8309        if (pi == null) {
8310            Slog.w(TAG, "No content provider found for permission revoke: "
8311                    + grantUri.toSafeString());
8312            return;
8313        }
8314
8315        // Does the caller have this permission on the URI?
8316        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8317            // If they don't have direct access to the URI, then revoke any
8318            // ownerless URI permissions that have been granted to them.
8319            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8320            if (perms != null) {
8321                boolean persistChanged = false;
8322                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8323                    final UriPermission perm = it.next();
8324                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8325                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8326                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8327                                "Revoking non-owned " + perm.targetUid
8328                                + " permission to " + perm.uri);
8329                        persistChanged |= perm.revokeModes(
8330                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8331                        if (perm.modeFlags == 0) {
8332                            it.remove();
8333                        }
8334                    }
8335                }
8336                if (perms.isEmpty()) {
8337                    mGrantedUriPermissions.remove(callingUid);
8338                }
8339                if (persistChanged) {
8340                    schedulePersistUriGrants();
8341                }
8342            }
8343            return;
8344        }
8345
8346        boolean persistChanged = false;
8347
8348        // Go through all of the permissions and remove any that match.
8349        int N = mGrantedUriPermissions.size();
8350        for (int i = 0; i < N; i++) {
8351            final int targetUid = mGrantedUriPermissions.keyAt(i);
8352            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8353
8354            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8355                final UriPermission perm = it.next();
8356                if (perm.uri.sourceUserId == grantUri.sourceUserId
8357                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8358                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8359                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8360                    persistChanged |= perm.revokeModes(
8361                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8362                    if (perm.modeFlags == 0) {
8363                        it.remove();
8364                    }
8365                }
8366            }
8367
8368            if (perms.isEmpty()) {
8369                mGrantedUriPermissions.remove(targetUid);
8370                N--;
8371                i--;
8372            }
8373        }
8374
8375        if (persistChanged) {
8376            schedulePersistUriGrants();
8377        }
8378    }
8379
8380    /**
8381     * @param uri This uri must NOT contain an embedded userId.
8382     * @param userId The userId in which the uri is to be resolved.
8383     */
8384    @Override
8385    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8386            int userId) {
8387        enforceNotIsolatedCaller("revokeUriPermission");
8388        synchronized(this) {
8389            final ProcessRecord r = getRecordForAppLocked(caller);
8390            if (r == null) {
8391                throw new SecurityException("Unable to find app for caller "
8392                        + caller
8393                        + " when revoking permission to uri " + uri);
8394            }
8395            if (uri == null) {
8396                Slog.w(TAG, "revokeUriPermission: null uri");
8397                return;
8398            }
8399
8400            if (!Intent.isAccessUriMode(modeFlags)) {
8401                return;
8402            }
8403
8404            final String authority = uri.getAuthority();
8405            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8406                    MATCH_DEBUG_TRIAGED_MISSING);
8407            if (pi == null) {
8408                Slog.w(TAG, "No content provider found for permission revoke: "
8409                        + uri.toSafeString());
8410                return;
8411            }
8412
8413            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8414        }
8415    }
8416
8417    /**
8418     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8419     * given package.
8420     *
8421     * @param packageName Package name to match, or {@code null} to apply to all
8422     *            packages.
8423     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8424     *            to all users.
8425     * @param persistable If persistable grants should be removed.
8426     */
8427    private void removeUriPermissionsForPackageLocked(
8428            String packageName, int userHandle, boolean persistable) {
8429        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8430            throw new IllegalArgumentException("Must narrow by either package or user");
8431        }
8432
8433        boolean persistChanged = false;
8434
8435        int N = mGrantedUriPermissions.size();
8436        for (int i = 0; i < N; i++) {
8437            final int targetUid = mGrantedUriPermissions.keyAt(i);
8438            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8439
8440            // Only inspect grants matching user
8441            if (userHandle == UserHandle.USER_ALL
8442                    || userHandle == UserHandle.getUserId(targetUid)) {
8443                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8444                    final UriPermission perm = it.next();
8445
8446                    // Only inspect grants matching package
8447                    if (packageName == null || perm.sourcePkg.equals(packageName)
8448                            || perm.targetPkg.equals(packageName)) {
8449                        persistChanged |= perm.revokeModes(persistable
8450                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8451
8452                        // Only remove when no modes remain; any persisted grants
8453                        // will keep this alive.
8454                        if (perm.modeFlags == 0) {
8455                            it.remove();
8456                        }
8457                    }
8458                }
8459
8460                if (perms.isEmpty()) {
8461                    mGrantedUriPermissions.remove(targetUid);
8462                    N--;
8463                    i--;
8464                }
8465            }
8466        }
8467
8468        if (persistChanged) {
8469            schedulePersistUriGrants();
8470        }
8471    }
8472
8473    @Override
8474    public IBinder newUriPermissionOwner(String name) {
8475        enforceNotIsolatedCaller("newUriPermissionOwner");
8476        synchronized(this) {
8477            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8478            return owner.getExternalTokenLocked();
8479        }
8480    }
8481
8482    @Override
8483    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8484        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8485        synchronized(this) {
8486            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8487            if (r == null) {
8488                throw new IllegalArgumentException("Activity does not exist; token="
8489                        + activityToken);
8490            }
8491            return r.getUriPermissionsLocked().getExternalTokenLocked();
8492        }
8493    }
8494    /**
8495     * @param uri This uri must NOT contain an embedded userId.
8496     * @param sourceUserId The userId in which the uri is to be resolved.
8497     * @param targetUserId The userId of the app that receives the grant.
8498     */
8499    @Override
8500    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8501            final int modeFlags, int sourceUserId, int targetUserId) {
8502        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8503                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8504                "grantUriPermissionFromOwner", null);
8505        synchronized(this) {
8506            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8507            if (owner == null) {
8508                throw new IllegalArgumentException("Unknown owner: " + token);
8509            }
8510            if (fromUid != Binder.getCallingUid()) {
8511                if (Binder.getCallingUid() != Process.myUid()) {
8512                    // Only system code can grant URI permissions on behalf
8513                    // of other users.
8514                    throw new SecurityException("nice try");
8515                }
8516            }
8517            if (targetPkg == null) {
8518                throw new IllegalArgumentException("null target");
8519            }
8520            if (uri == null) {
8521                throw new IllegalArgumentException("null uri");
8522            }
8523
8524            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8525                    modeFlags, owner, targetUserId);
8526        }
8527    }
8528
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param userId The userId in which the uri is to be resolved.
8532     */
8533    @Override
8534    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8535        synchronized(this) {
8536            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8537            if (owner == null) {
8538                throw new IllegalArgumentException("Unknown owner: " + token);
8539            }
8540
8541            if (uri == null) {
8542                owner.removeUriPermissionsLocked(mode);
8543            } else {
8544                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8545            }
8546        }
8547    }
8548
8549    private void schedulePersistUriGrants() {
8550        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8551            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8552                    10 * DateUtils.SECOND_IN_MILLIS);
8553        }
8554    }
8555
8556    private void writeGrantedUriPermissions() {
8557        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8558
8559        // Snapshot permissions so we can persist without lock
8560        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8561        synchronized (this) {
8562            final int size = mGrantedUriPermissions.size();
8563            for (int i = 0; i < size; i++) {
8564                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8565                for (UriPermission perm : perms.values()) {
8566                    if (perm.persistedModeFlags != 0) {
8567                        persist.add(perm.snapshot());
8568                    }
8569                }
8570            }
8571        }
8572
8573        FileOutputStream fos = null;
8574        try {
8575            fos = mGrantFile.startWrite();
8576
8577            XmlSerializer out = new FastXmlSerializer();
8578            out.setOutput(fos, StandardCharsets.UTF_8.name());
8579            out.startDocument(null, true);
8580            out.startTag(null, TAG_URI_GRANTS);
8581            for (UriPermission.Snapshot perm : persist) {
8582                out.startTag(null, TAG_URI_GRANT);
8583                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8584                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8585                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8586                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8587                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8588                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8589                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8590                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8591                out.endTag(null, TAG_URI_GRANT);
8592            }
8593            out.endTag(null, TAG_URI_GRANTS);
8594            out.endDocument();
8595
8596            mGrantFile.finishWrite(fos);
8597        } catch (IOException e) {
8598            if (fos != null) {
8599                mGrantFile.failWrite(fos);
8600            }
8601        }
8602    }
8603
8604    private void readGrantedUriPermissionsLocked() {
8605        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8606
8607        final long now = System.currentTimeMillis();
8608
8609        FileInputStream fis = null;
8610        try {
8611            fis = mGrantFile.openRead();
8612            final XmlPullParser in = Xml.newPullParser();
8613            in.setInput(fis, StandardCharsets.UTF_8.name());
8614
8615            int type;
8616            while ((type = in.next()) != END_DOCUMENT) {
8617                final String tag = in.getName();
8618                if (type == START_TAG) {
8619                    if (TAG_URI_GRANT.equals(tag)) {
8620                        final int sourceUserId;
8621                        final int targetUserId;
8622                        final int userHandle = readIntAttribute(in,
8623                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8624                        if (userHandle != UserHandle.USER_NULL) {
8625                            // For backwards compatibility.
8626                            sourceUserId = userHandle;
8627                            targetUserId = userHandle;
8628                        } else {
8629                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8630                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8631                        }
8632                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8633                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8634                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8635                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8636                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8637                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8638
8639                        // Sanity check that provider still belongs to source package
8640                        // Both direct boot aware and unaware packages are fine as we
8641                        // will do filtering at query time to avoid multiple parsing.
8642                        final ProviderInfo pi = getProviderInfoLocked(
8643                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8644                                        | MATCH_DIRECT_BOOT_UNAWARE);
8645                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8646                            int targetUid = -1;
8647                            try {
8648                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8649                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8650                            } catch (RemoteException e) {
8651                            }
8652                            if (targetUid != -1) {
8653                                final UriPermission perm = findOrCreateUriPermissionLocked(
8654                                        sourcePkg, targetPkg, targetUid,
8655                                        new GrantUri(sourceUserId, uri, prefix));
8656                                perm.initPersistedModes(modeFlags, createdTime);
8657                            }
8658                        } else {
8659                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8660                                    + " but instead found " + pi);
8661                        }
8662                    }
8663                }
8664            }
8665        } catch (FileNotFoundException e) {
8666            // Missing grants is okay
8667        } catch (IOException e) {
8668            Slog.wtf(TAG, "Failed reading Uri grants", e);
8669        } catch (XmlPullParserException e) {
8670            Slog.wtf(TAG, "Failed reading Uri grants", e);
8671        } finally {
8672            IoUtils.closeQuietly(fis);
8673        }
8674    }
8675
8676    /**
8677     * @param uri This uri must NOT contain an embedded userId.
8678     * @param userId The userId in which the uri is to be resolved.
8679     */
8680    @Override
8681    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8682        enforceNotIsolatedCaller("takePersistableUriPermission");
8683
8684        Preconditions.checkFlagsArgument(modeFlags,
8685                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8686
8687        synchronized (this) {
8688            final int callingUid = Binder.getCallingUid();
8689            boolean persistChanged = false;
8690            GrantUri grantUri = new GrantUri(userId, uri, false);
8691
8692            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8693                    new GrantUri(userId, uri, false));
8694            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8695                    new GrantUri(userId, uri, true));
8696
8697            final boolean exactValid = (exactPerm != null)
8698                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8699            final boolean prefixValid = (prefixPerm != null)
8700                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8701
8702            if (!(exactValid || prefixValid)) {
8703                throw new SecurityException("No persistable permission grants found for UID "
8704                        + callingUid + " and Uri " + grantUri.toSafeString());
8705            }
8706
8707            if (exactValid) {
8708                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8709            }
8710            if (prefixValid) {
8711                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8712            }
8713
8714            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8715
8716            if (persistChanged) {
8717                schedulePersistUriGrants();
8718            }
8719        }
8720    }
8721
8722    /**
8723     * @param uri This uri must NOT contain an embedded userId.
8724     * @param userId The userId in which the uri is to be resolved.
8725     */
8726    @Override
8727    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8728        enforceNotIsolatedCaller("releasePersistableUriPermission");
8729
8730        Preconditions.checkFlagsArgument(modeFlags,
8731                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8732
8733        synchronized (this) {
8734            final int callingUid = Binder.getCallingUid();
8735            boolean persistChanged = false;
8736
8737            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8738                    new GrantUri(userId, uri, false));
8739            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8740                    new GrantUri(userId, uri, true));
8741            if (exactPerm == null && prefixPerm == null) {
8742                throw new SecurityException("No permission grants found for UID " + callingUid
8743                        + " and Uri " + uri.toSafeString());
8744            }
8745
8746            if (exactPerm != null) {
8747                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8748                removeUriPermissionIfNeededLocked(exactPerm);
8749            }
8750            if (prefixPerm != null) {
8751                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8752                removeUriPermissionIfNeededLocked(prefixPerm);
8753            }
8754
8755            if (persistChanged) {
8756                schedulePersistUriGrants();
8757            }
8758        }
8759    }
8760
8761    /**
8762     * Prune any older {@link UriPermission} for the given UID until outstanding
8763     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8764     *
8765     * @return if any mutations occured that require persisting.
8766     */
8767    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8768        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8769        if (perms == null) return false;
8770        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8771
8772        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8773        for (UriPermission perm : perms.values()) {
8774            if (perm.persistedModeFlags != 0) {
8775                persisted.add(perm);
8776            }
8777        }
8778
8779        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8780        if (trimCount <= 0) return false;
8781
8782        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8783        for (int i = 0; i < trimCount; i++) {
8784            final UriPermission perm = persisted.get(i);
8785
8786            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8787                    "Trimming grant created at " + perm.persistedCreateTime);
8788
8789            perm.releasePersistableModes(~0);
8790            removeUriPermissionIfNeededLocked(perm);
8791        }
8792
8793        return true;
8794    }
8795
8796    @Override
8797    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8798            String packageName, boolean incoming) {
8799        enforceNotIsolatedCaller("getPersistedUriPermissions");
8800        Preconditions.checkNotNull(packageName, "packageName");
8801
8802        final int callingUid = Binder.getCallingUid();
8803        final IPackageManager pm = AppGlobals.getPackageManager();
8804        try {
8805            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8806                    UserHandle.getUserId(callingUid));
8807            if (packageUid != callingUid) {
8808                throw new SecurityException(
8809                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8810            }
8811        } catch (RemoteException e) {
8812            throw new SecurityException("Failed to verify package name ownership");
8813        }
8814
8815        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8816        synchronized (this) {
8817            if (incoming) {
8818                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8819                        callingUid);
8820                if (perms == null) {
8821                    Slog.w(TAG, "No permission grants found for " + packageName);
8822                } else {
8823                    final int userId = UserHandle.getUserId(callingUid);
8824                    Set<String> existingAuthorities = null;
8825
8826                    for (UriPermission perm : perms.values()) {
8827                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8828                            // Is this provider available in the current boot state? If the user
8829                            // is not running and unlocked we check if the provider package exists.
8830                            if (!mUserController.isUserRunningLocked(userId,
8831                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8832                                String authority = perm.uri.uri.getAuthority();
8833                                if (existingAuthorities == null
8834                                        || !existingAuthorities.contains(authority)) {
8835                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8836                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8837                                    if (providerInfo != null) {
8838                                        if (existingAuthorities == null) {
8839                                            existingAuthorities = new ArraySet<>();
8840                                        }
8841                                        existingAuthorities.add(authority);
8842                                    } else {
8843                                        continue;
8844                                    }
8845                                }
8846                            }
8847                            result.add(perm.buildPersistedPublicApiObject());
8848                        }
8849                    }
8850                }
8851            } else {
8852                final int size = mGrantedUriPermissions.size();
8853                for (int i = 0; i < size; i++) {
8854                    final ArrayMap<GrantUri, UriPermission> perms =
8855                            mGrantedUriPermissions.valueAt(i);
8856                    for (UriPermission perm : perms.values()) {
8857                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8858                            result.add(perm.buildPersistedPublicApiObject());
8859                        }
8860                    }
8861                }
8862            }
8863        }
8864        return new ParceledListSlice<android.content.UriPermission>(result);
8865    }
8866
8867    @Override
8868    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8869            String packageName, int userId) {
8870        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8871                "getGrantedUriPermissions");
8872
8873        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8874        synchronized (this) {
8875            final int size = mGrantedUriPermissions.size();
8876            for (int i = 0; i < size; i++) {
8877                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8878                for (UriPermission perm : perms.values()) {
8879                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8880                            && perm.persistedModeFlags != 0) {
8881                        result.add(perm.buildPersistedPublicApiObject());
8882                    }
8883                }
8884            }
8885        }
8886        return new ParceledListSlice<android.content.UriPermission>(result);
8887    }
8888
8889    @Override
8890    public void clearGrantedUriPermissions(String packageName, int userId) {
8891        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8892                "clearGrantedUriPermissions");
8893        removeUriPermissionsForPackageLocked(packageName, userId, true);
8894    }
8895
8896    @Override
8897    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8898        synchronized (this) {
8899            ProcessRecord app =
8900                who != null ? getRecordForAppLocked(who) : null;
8901            if (app == null) return;
8902
8903            Message msg = Message.obtain();
8904            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8905            msg.obj = app;
8906            msg.arg1 = waiting ? 1 : 0;
8907            mUiHandler.sendMessage(msg);
8908        }
8909    }
8910
8911    @Override
8912    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8913        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8914        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8915        outInfo.availMem = Process.getFreeMemory();
8916        outInfo.totalMem = Process.getTotalMemory();
8917        outInfo.threshold = homeAppMem;
8918        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8919        outInfo.hiddenAppThreshold = cachedAppMem;
8920        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8921                ProcessList.SERVICE_ADJ);
8922        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8923                ProcessList.VISIBLE_APP_ADJ);
8924        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8925                ProcessList.FOREGROUND_APP_ADJ);
8926    }
8927
8928    // =========================================================
8929    // TASK MANAGEMENT
8930    // =========================================================
8931
8932    @Override
8933    public List<IAppTask> getAppTasks(String callingPackage) {
8934        int callingUid = Binder.getCallingUid();
8935        long ident = Binder.clearCallingIdentity();
8936
8937        synchronized(this) {
8938            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8939            try {
8940                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8941
8942                final int N = mRecentTasks.size();
8943                for (int i = 0; i < N; i++) {
8944                    TaskRecord tr = mRecentTasks.get(i);
8945                    // Skip tasks that do not match the caller.  We don't need to verify
8946                    // callingPackage, because we are also limiting to callingUid and know
8947                    // that will limit to the correct security sandbox.
8948                    if (tr.effectiveUid != callingUid) {
8949                        continue;
8950                    }
8951                    Intent intent = tr.getBaseIntent();
8952                    if (intent == null ||
8953                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8954                        continue;
8955                    }
8956                    ActivityManager.RecentTaskInfo taskInfo =
8957                            createRecentTaskInfoFromTaskRecord(tr);
8958                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8959                    list.add(taskImpl);
8960                }
8961            } finally {
8962                Binder.restoreCallingIdentity(ident);
8963            }
8964            return list;
8965        }
8966    }
8967
8968    @Override
8969    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8970        final int callingUid = Binder.getCallingUid();
8971        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8972
8973        synchronized(this) {
8974            if (DEBUG_ALL) Slog.v(
8975                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8976
8977            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8978                    callingUid);
8979
8980            // TODO: Improve with MRU list from all ActivityStacks.
8981            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8982        }
8983
8984        return list;
8985    }
8986
8987    /**
8988     * Creates a new RecentTaskInfo from a TaskRecord.
8989     */
8990    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8991        // Update the task description to reflect any changes in the task stack
8992        tr.updateTaskDescription();
8993
8994        // Compose the recent task info
8995        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8996        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8997        rti.persistentId = tr.taskId;
8998        rti.baseIntent = new Intent(tr.getBaseIntent());
8999        rti.origActivity = tr.origActivity;
9000        rti.realActivity = tr.realActivity;
9001        rti.description = tr.lastDescription;
9002        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9003        rti.userId = tr.userId;
9004        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9005        rti.firstActiveTime = tr.firstActiveTime;
9006        rti.lastActiveTime = tr.lastActiveTime;
9007        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9008        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9009        rti.numActivities = 0;
9010        if (tr.mBounds != null) {
9011            rti.bounds = new Rect(tr.mBounds);
9012        }
9013        rti.isDockable = tr.canGoInDockedStack();
9014        rti.resizeMode = tr.mResizeMode;
9015
9016        ActivityRecord base = null;
9017        ActivityRecord top = null;
9018        ActivityRecord tmp;
9019
9020        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9021            tmp = tr.mActivities.get(i);
9022            if (tmp.finishing) {
9023                continue;
9024            }
9025            base = tmp;
9026            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9027                top = base;
9028            }
9029            rti.numActivities++;
9030        }
9031
9032        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9033        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9034
9035        return rti;
9036    }
9037
9038    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9039        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9040                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9041        if (!allowed) {
9042            if (checkPermission(android.Manifest.permission.GET_TASKS,
9043                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9044                // Temporary compatibility: some existing apps on the system image may
9045                // still be requesting the old permission and not switched to the new
9046                // one; if so, we'll still allow them full access.  This means we need
9047                // to see if they are holding the old permission and are a system app.
9048                try {
9049                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9050                        allowed = true;
9051                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9052                                + " is using old GET_TASKS but privileged; allowing");
9053                    }
9054                } catch (RemoteException e) {
9055                }
9056            }
9057        }
9058        if (!allowed) {
9059            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9060                    + " does not hold REAL_GET_TASKS; limiting output");
9061        }
9062        return allowed;
9063    }
9064
9065    @Override
9066    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9067        final int callingUid = Binder.getCallingUid();
9068        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9069                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9070
9071        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9072        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9073        synchronized (this) {
9074            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9075                    callingUid);
9076            final boolean detailed = checkCallingPermission(
9077                    android.Manifest.permission.GET_DETAILED_TASKS)
9078                    == PackageManager.PERMISSION_GRANTED;
9079
9080            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9081                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9082                return Collections.emptyList();
9083            }
9084            mRecentTasks.loadUserRecentsLocked(userId);
9085
9086            final int recentsCount = mRecentTasks.size();
9087            ArrayList<ActivityManager.RecentTaskInfo> res =
9088                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9089
9090            final Set<Integer> includedUsers;
9091            if (includeProfiles) {
9092                includedUsers = mUserController.getProfileIds(userId);
9093            } else {
9094                includedUsers = new HashSet<>();
9095            }
9096            includedUsers.add(Integer.valueOf(userId));
9097
9098            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9099                TaskRecord tr = mRecentTasks.get(i);
9100                // Only add calling user or related users recent tasks
9101                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9102                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9103                    continue;
9104                }
9105
9106                if (tr.realActivitySuspended) {
9107                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9108                    continue;
9109                }
9110
9111                // Return the entry if desired by the caller.  We always return
9112                // the first entry, because callers always expect this to be the
9113                // foreground app.  We may filter others if the caller has
9114                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9115                // we should exclude the entry.
9116
9117                if (i == 0
9118                        || withExcluded
9119                        || (tr.intent == null)
9120                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9121                                == 0)) {
9122                    if (!allowed) {
9123                        // If the caller doesn't have the GET_TASKS permission, then only
9124                        // allow them to see a small subset of tasks -- their own and home.
9125                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9126                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9127                            continue;
9128                        }
9129                    }
9130                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9131                        if (tr.stack != null && tr.stack.isHomeStack()) {
9132                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9133                                    "Skipping, home stack task: " + tr);
9134                            continue;
9135                        }
9136                    }
9137                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9138                        final ActivityStack stack = tr.stack;
9139                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9140                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9141                                    "Skipping, top task in docked stack: " + tr);
9142                            continue;
9143                        }
9144                    }
9145                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9146                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9147                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9148                                    "Skipping, pinned stack task: " + tr);
9149                            continue;
9150                        }
9151                    }
9152                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9153                        // Don't include auto remove tasks that are finished or finishing.
9154                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9155                                "Skipping, auto-remove without activity: " + tr);
9156                        continue;
9157                    }
9158                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9159                            && !tr.isAvailable) {
9160                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9161                                "Skipping, unavail real act: " + tr);
9162                        continue;
9163                    }
9164
9165                    if (!tr.mUserSetupComplete) {
9166                        // Don't include task launched while user is not done setting-up.
9167                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9168                                "Skipping, user setup not complete: " + tr);
9169                        continue;
9170                    }
9171
9172                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9173                    if (!detailed) {
9174                        rti.baseIntent.replaceExtras((Bundle)null);
9175                    }
9176
9177                    res.add(rti);
9178                    maxNum--;
9179                }
9180            }
9181            return res;
9182        }
9183    }
9184
9185    @Override
9186    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9187        synchronized (this) {
9188            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9189                    "getTaskThumbnail()");
9190            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9191                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9192            if (tr != null) {
9193                return tr.getTaskThumbnailLocked();
9194            }
9195        }
9196        return null;
9197    }
9198
9199    @Override
9200    public int addAppTask(IBinder activityToken, Intent intent,
9201            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9202        final int callingUid = Binder.getCallingUid();
9203        final long callingIdent = Binder.clearCallingIdentity();
9204
9205        try {
9206            synchronized (this) {
9207                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9208                if (r == null) {
9209                    throw new IllegalArgumentException("Activity does not exist; token="
9210                            + activityToken);
9211                }
9212                ComponentName comp = intent.getComponent();
9213                if (comp == null) {
9214                    throw new IllegalArgumentException("Intent " + intent
9215                            + " must specify explicit component");
9216                }
9217                if (thumbnail.getWidth() != mThumbnailWidth
9218                        || thumbnail.getHeight() != mThumbnailHeight) {
9219                    throw new IllegalArgumentException("Bad thumbnail size: got "
9220                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9221                            + mThumbnailWidth + "x" + mThumbnailHeight);
9222                }
9223                if (intent.getSelector() != null) {
9224                    intent.setSelector(null);
9225                }
9226                if (intent.getSourceBounds() != null) {
9227                    intent.setSourceBounds(null);
9228                }
9229                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9230                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9231                        // The caller has added this as an auto-remove task...  that makes no
9232                        // sense, so turn off auto-remove.
9233                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9234                    }
9235                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9236                    // Must be a new task.
9237                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9238                }
9239                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9240                    mLastAddedTaskActivity = null;
9241                }
9242                ActivityInfo ainfo = mLastAddedTaskActivity;
9243                if (ainfo == null) {
9244                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9245                            comp, 0, UserHandle.getUserId(callingUid));
9246                    if (ainfo.applicationInfo.uid != callingUid) {
9247                        throw new SecurityException(
9248                                "Can't add task for another application: target uid="
9249                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9250                    }
9251                }
9252
9253                // Use the full screen as the context for the task thumbnail
9254                final Point displaySize = new Point();
9255                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9256                r.task.stack.getDisplaySize(displaySize);
9257                thumbnailInfo.taskWidth = displaySize.x;
9258                thumbnailInfo.taskHeight = displaySize.y;
9259                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9260
9261                TaskRecord task = new TaskRecord(this,
9262                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9263                        ainfo, intent, description, thumbnailInfo);
9264
9265                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9266                if (trimIdx >= 0) {
9267                    // If this would have caused a trim, then we'll abort because that
9268                    // means it would be added at the end of the list but then just removed.
9269                    return INVALID_TASK_ID;
9270                }
9271
9272                final int N = mRecentTasks.size();
9273                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9274                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9275                    tr.removedFromRecents();
9276                }
9277
9278                task.inRecents = true;
9279                mRecentTasks.add(task);
9280                r.task.stack.addTask(task, false, "addAppTask");
9281
9282                task.setLastThumbnailLocked(thumbnail);
9283                task.freeLastThumbnail();
9284
9285                return task.taskId;
9286            }
9287        } finally {
9288            Binder.restoreCallingIdentity(callingIdent);
9289        }
9290    }
9291
9292    @Override
9293    public Point getAppTaskThumbnailSize() {
9294        synchronized (this) {
9295            return new Point(mThumbnailWidth,  mThumbnailHeight);
9296        }
9297    }
9298
9299    @Override
9300    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9301        synchronized (this) {
9302            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9303            if (r != null) {
9304                r.setTaskDescription(td);
9305                r.task.updateTaskDescription();
9306            }
9307        }
9308    }
9309
9310    @Override
9311    public void setTaskResizeable(int taskId, int resizeableMode) {
9312        synchronized (this) {
9313            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9314                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9315            if (task == null) {
9316                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9317                return;
9318            }
9319            if (task.mResizeMode != resizeableMode) {
9320                task.mResizeMode = resizeableMode;
9321                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9322                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9323                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9324            }
9325        }
9326    }
9327
9328    @Override
9329    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9330        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9331        long ident = Binder.clearCallingIdentity();
9332        try {
9333            synchronized (this) {
9334                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9335                if (task == null) {
9336                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9337                    return;
9338                }
9339                int stackId = task.stack.mStackId;
9340                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9341                // in crop windows resize mode or if the task size is affected by the docked stack
9342                // changing size. No need to update configuration.
9343                if (bounds != null && task.inCropWindowsResizeMode()
9344                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9345                    mWindowManager.scrollTask(task.taskId, bounds);
9346                    return;
9347                }
9348
9349                // Place the task in the right stack if it isn't there already based on
9350                // the requested bounds.
9351                // The stack transition logic is:
9352                // - a null bounds on a freeform task moves that task to fullscreen
9353                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9354                //   that task to freeform
9355                // - otherwise the task is not moved
9356                if (!StackId.isTaskResizeAllowed(stackId)) {
9357                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9358                }
9359                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9360                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9361                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9362                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9363                }
9364                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9365                if (stackId != task.stack.mStackId) {
9366                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9367                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9368                    preserveWindow = false;
9369                }
9370
9371                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9372                        false /* deferResume */);
9373            }
9374        } finally {
9375            Binder.restoreCallingIdentity(ident);
9376        }
9377    }
9378
9379    @Override
9380    public Rect getTaskBounds(int taskId) {
9381        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9382        long ident = Binder.clearCallingIdentity();
9383        Rect rect = new Rect();
9384        try {
9385            synchronized (this) {
9386                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9387                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9388                if (task == null) {
9389                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9390                    return rect;
9391                }
9392                if (task.stack != null) {
9393                    // Return the bounds from window manager since it will be adjusted for various
9394                    // things like the presense of a docked stack for tasks that aren't resizeable.
9395                    mWindowManager.getTaskBounds(task.taskId, rect);
9396                } else {
9397                    // Task isn't in window manager yet since it isn't associated with a stack.
9398                    // Return the persist value from activity manager
9399                    if (task.mBounds != null) {
9400                        rect.set(task.mBounds);
9401                    } else if (task.mLastNonFullscreenBounds != null) {
9402                        rect.set(task.mLastNonFullscreenBounds);
9403                    }
9404                }
9405            }
9406        } finally {
9407            Binder.restoreCallingIdentity(ident);
9408        }
9409        return rect;
9410    }
9411
9412    @Override
9413    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9414        if (userId != UserHandle.getCallingUserId()) {
9415            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9416                    "getTaskDescriptionIcon");
9417        }
9418        final File passedIconFile = new File(filePath);
9419        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9420                passedIconFile.getName());
9421        if (!legitIconFile.getPath().equals(filePath)
9422                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9423            throw new IllegalArgumentException("Bad file path: " + filePath
9424                    + " passed for userId " + userId);
9425        }
9426        return mRecentTasks.getTaskDescriptionIcon(filePath);
9427    }
9428
9429    @Override
9430    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9431            throws RemoteException {
9432        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9433                opts.getCustomInPlaceResId() == 0) {
9434            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9435                    "with valid animation");
9436        }
9437        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9438        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9439                opts.getCustomInPlaceResId());
9440        mWindowManager.executeAppTransition();
9441    }
9442
9443    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9444            boolean removeFromRecents) {
9445        if (removeFromRecents) {
9446            mRecentTasks.remove(tr);
9447            tr.removedFromRecents();
9448        }
9449        ComponentName component = tr.getBaseIntent().getComponent();
9450        if (component == null) {
9451            Slog.w(TAG, "No component for base intent of task: " + tr);
9452            return;
9453        }
9454
9455        // Find any running services associated with this app and stop if needed.
9456        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9457
9458        if (!killProcess) {
9459            return;
9460        }
9461
9462        // Determine if the process(es) for this task should be killed.
9463        final String pkg = component.getPackageName();
9464        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9465        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9466        for (int i = 0; i < pmap.size(); i++) {
9467
9468            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9469            for (int j = 0; j < uids.size(); j++) {
9470                ProcessRecord proc = uids.valueAt(j);
9471                if (proc.userId != tr.userId) {
9472                    // Don't kill process for a different user.
9473                    continue;
9474                }
9475                if (proc == mHomeProcess) {
9476                    // Don't kill the home process along with tasks from the same package.
9477                    continue;
9478                }
9479                if (!proc.pkgList.containsKey(pkg)) {
9480                    // Don't kill process that is not associated with this task.
9481                    continue;
9482                }
9483
9484                for (int k = 0; k < proc.activities.size(); k++) {
9485                    TaskRecord otherTask = proc.activities.get(k).task;
9486                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9487                        // Don't kill process(es) that has an activity in a different task that is
9488                        // also in recents.
9489                        return;
9490                    }
9491                }
9492
9493                if (proc.foregroundServices) {
9494                    // Don't kill process(es) with foreground service.
9495                    return;
9496                }
9497
9498                // Add process to kill list.
9499                procsToKill.add(proc);
9500            }
9501        }
9502
9503        // Kill the running processes.
9504        for (int i = 0; i < procsToKill.size(); i++) {
9505            ProcessRecord pr = procsToKill.get(i);
9506            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9507                    && pr.curReceiver == null) {
9508                pr.kill("remove task", true);
9509            } else {
9510                // We delay killing processes that are not in the background or running a receiver.
9511                pr.waitingToKill = "remove task";
9512            }
9513        }
9514    }
9515
9516    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9517        // Remove all tasks with activities in the specified package from the list of recent tasks
9518        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9519            TaskRecord tr = mRecentTasks.get(i);
9520            if (tr.userId != userId) continue;
9521
9522            ComponentName cn = tr.intent.getComponent();
9523            if (cn != null && cn.getPackageName().equals(packageName)) {
9524                // If the package name matches, remove the task.
9525                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9526            }
9527        }
9528    }
9529
9530    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9531            int userId) {
9532
9533        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9534            TaskRecord tr = mRecentTasks.get(i);
9535            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9536                continue;
9537            }
9538
9539            ComponentName cn = tr.intent.getComponent();
9540            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9541                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9542            if (sameComponent) {
9543                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9544            }
9545        }
9546    }
9547
9548    /**
9549     * Removes the task with the specified task id.
9550     *
9551     * @param taskId Identifier of the task to be removed.
9552     * @param killProcess Kill any process associated with the task if possible.
9553     * @param removeFromRecents Whether to also remove the task from recents.
9554     * @return Returns true if the given task was found and removed.
9555     */
9556    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9557            boolean removeFromRecents) {
9558        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9559                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9560        if (tr != null) {
9561            tr.removeTaskActivitiesLocked();
9562            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9563            if (tr.isPersistable) {
9564                notifyTaskPersisterLocked(null, true);
9565            }
9566            return true;
9567        }
9568        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9569        return false;
9570    }
9571
9572    @Override
9573    public void removeStack(int stackId) {
9574        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9575        if (stackId == HOME_STACK_ID) {
9576            throw new IllegalArgumentException("Removing home stack is not allowed.");
9577        }
9578
9579        synchronized (this) {
9580            final long ident = Binder.clearCallingIdentity();
9581            try {
9582                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9583                if (stack == null) {
9584                    return;
9585                }
9586                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9587                for (int i = tasks.size() - 1; i >= 0; i--) {
9588                    removeTaskByIdLocked(
9589                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9590                }
9591            } finally {
9592                Binder.restoreCallingIdentity(ident);
9593            }
9594        }
9595    }
9596
9597    @Override
9598    public boolean removeTask(int taskId) {
9599        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9600        synchronized (this) {
9601            final long ident = Binder.clearCallingIdentity();
9602            try {
9603                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9604            } finally {
9605                Binder.restoreCallingIdentity(ident);
9606            }
9607        }
9608    }
9609
9610    /**
9611     * TODO: Add mController hook
9612     */
9613    @Override
9614    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9615        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9616
9617        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9618        synchronized(this) {
9619            moveTaskToFrontLocked(taskId, flags, bOptions);
9620        }
9621    }
9622
9623    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9624        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9625
9626        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9627                Binder.getCallingUid(), -1, -1, "Task to front")) {
9628            ActivityOptions.abort(options);
9629            return;
9630        }
9631        final long origId = Binder.clearCallingIdentity();
9632        try {
9633            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9634            if (task == null) {
9635                Slog.d(TAG, "Could not find task for id: "+ taskId);
9636                return;
9637            }
9638            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9639                mStackSupervisor.showLockTaskToast();
9640                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9641                return;
9642            }
9643            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9644            if (prev != null && prev.isRecentsActivity()) {
9645                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9646            }
9647            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9648                    false /* forceNonResizable */);
9649        } finally {
9650            Binder.restoreCallingIdentity(origId);
9651        }
9652        ActivityOptions.abort(options);
9653    }
9654
9655    /**
9656     * Moves an activity, and all of the other activities within the same task, to the bottom
9657     * of the history stack.  The activity's order within the task is unchanged.
9658     *
9659     * @param token A reference to the activity we wish to move
9660     * @param nonRoot If false then this only works if the activity is the root
9661     *                of a task; if true it will work for any activity in a task.
9662     * @return Returns true if the move completed, false if not.
9663     */
9664    @Override
9665    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9666        enforceNotIsolatedCaller("moveActivityTaskToBack");
9667        synchronized(this) {
9668            final long origId = Binder.clearCallingIdentity();
9669            try {
9670                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9671                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9672                if (task != null) {
9673                    if (mStackSupervisor.isLockedTask(task)) {
9674                        mStackSupervisor.showLockTaskToast();
9675                        return false;
9676                    }
9677                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9678                }
9679            } finally {
9680                Binder.restoreCallingIdentity(origId);
9681            }
9682        }
9683        return false;
9684    }
9685
9686    @Override
9687    public void moveTaskBackwards(int task) {
9688        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9689                "moveTaskBackwards()");
9690
9691        synchronized(this) {
9692            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9693                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9694                return;
9695            }
9696            final long origId = Binder.clearCallingIdentity();
9697            moveTaskBackwardsLocked(task);
9698            Binder.restoreCallingIdentity(origId);
9699        }
9700    }
9701
9702    private final void moveTaskBackwardsLocked(int task) {
9703        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9704    }
9705
9706    @Override
9707    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9708            IActivityContainerCallback callback) throws RemoteException {
9709        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9710        synchronized (this) {
9711            if (parentActivityToken == null) {
9712                throw new IllegalArgumentException("parent token must not be null");
9713            }
9714            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9715            if (r == null) {
9716                return null;
9717            }
9718            if (callback == null) {
9719                throw new IllegalArgumentException("callback must not be null");
9720            }
9721            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9722        }
9723    }
9724
9725    @Override
9726    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9727        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9728        synchronized (this) {
9729            mStackSupervisor.deleteActivityContainer(container);
9730        }
9731    }
9732
9733    @Override
9734    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9735        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9736        synchronized (this) {
9737            final int stackId = mStackSupervisor.getNextStackId();
9738            final ActivityStack stack =
9739                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9740            if (stack == null) {
9741                return null;
9742            }
9743            return stack.mActivityContainer;
9744        }
9745    }
9746
9747    @Override
9748    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9749        synchronized (this) {
9750            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9751            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9752                return stack.mActivityContainer.getDisplayId();
9753            }
9754            return Display.DEFAULT_DISPLAY;
9755        }
9756    }
9757
9758    @Override
9759    public int getActivityStackId(IBinder token) throws RemoteException {
9760        synchronized (this) {
9761            ActivityStack stack = ActivityRecord.getStackLocked(token);
9762            if (stack == null) {
9763                return INVALID_STACK_ID;
9764            }
9765            return stack.mStackId;
9766        }
9767    }
9768
9769    @Override
9770    public void exitFreeformMode(IBinder token) throws RemoteException {
9771        synchronized (this) {
9772            long ident = Binder.clearCallingIdentity();
9773            try {
9774                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9775                if (r == null) {
9776                    throw new IllegalArgumentException(
9777                            "exitFreeformMode: No activity record matching token=" + token);
9778                }
9779                final ActivityStack stack = r.getStackLocked(token);
9780                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9781                    throw new IllegalStateException(
9782                            "exitFreeformMode: You can only go fullscreen from freeform.");
9783                }
9784                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9785                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9786                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9787            } finally {
9788                Binder.restoreCallingIdentity(ident);
9789            }
9790        }
9791    }
9792
9793    @Override
9794    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9795        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9796        if (stackId == HOME_STACK_ID) {
9797            throw new IllegalArgumentException(
9798                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9799        }
9800        synchronized (this) {
9801            long ident = Binder.clearCallingIdentity();
9802            try {
9803                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9804                        + " to stackId=" + stackId + " toTop=" + toTop);
9805                if (stackId == DOCKED_STACK_ID) {
9806                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9807                            null /* initialBounds */);
9808                }
9809                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9810                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9811                if (result && stackId == DOCKED_STACK_ID) {
9812                    // If task moved to docked stack - show recents if needed.
9813                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9814                            "moveTaskToDockedStack");
9815                }
9816            } finally {
9817                Binder.restoreCallingIdentity(ident);
9818            }
9819        }
9820    }
9821
9822    @Override
9823    public void swapDockedAndFullscreenStack() throws RemoteException {
9824        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9825        synchronized (this) {
9826            long ident = Binder.clearCallingIdentity();
9827            try {
9828                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9829                        FULLSCREEN_WORKSPACE_STACK_ID);
9830                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9831                        : null;
9832                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9833                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9834                        : null;
9835                if (topTask == null || tasks == null || tasks.size() == 0) {
9836                    Slog.w(TAG,
9837                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9838                    return;
9839                }
9840
9841                // TODO: App transition
9842                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9843
9844                // Defer the resume so resume/pausing while moving stacks is dangerous.
9845                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9846                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9847                        ANIMATE, true /* deferResume */);
9848                final int size = tasks.size();
9849                for (int i = 0; i < size; i++) {
9850                    final int id = tasks.get(i).taskId;
9851                    if (id == topTask.taskId) {
9852                        continue;
9853                    }
9854                    mStackSupervisor.moveTaskToStackLocked(id,
9855                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9856                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9857                }
9858
9859                // Because we deferred the resume, to avoid conflicts with stack switches while
9860                // resuming, we need to do it after all the tasks are moved.
9861                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9862                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9863
9864                mWindowManager.executeAppTransition();
9865            } finally {
9866                Binder.restoreCallingIdentity(ident);
9867            }
9868        }
9869    }
9870
9871    /**
9872     * Moves the input task to the docked stack.
9873     *
9874     * @param taskId Id of task to move.
9875     * @param createMode The mode the docked stack should be created in if it doesn't exist
9876     *                   already. See
9877     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9878     *                   and
9879     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9880     * @param toTop If the task and stack should be moved to the top.
9881     * @param animate Whether we should play an animation for the moving the task
9882     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9883     *                      docked stack. Pass {@code null} to use default bounds.
9884     */
9885    @Override
9886    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9887            Rect initialBounds, boolean moveHomeStackFront) {
9888        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9889        synchronized (this) {
9890            long ident = Binder.clearCallingIdentity();
9891            try {
9892                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9893                        + " to createMode=" + createMode + " toTop=" + toTop);
9894                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9895                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9896                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9897                        animate, DEFER_RESUME);
9898                if (moved) {
9899                    if (moveHomeStackFront) {
9900                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9901                    }
9902                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9903                }
9904                return moved;
9905            } finally {
9906                Binder.restoreCallingIdentity(ident);
9907            }
9908        }
9909    }
9910
9911    /**
9912     * Moves the top activity in the input stackId to the pinned stack.
9913     *
9914     * @param stackId Id of stack to move the top activity to pinned stack.
9915     * @param bounds Bounds to use for pinned stack.
9916     *
9917     * @return True if the top activity of the input stack was successfully moved to the pinned
9918     *          stack.
9919     */
9920    @Override
9921    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9922        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9923        synchronized (this) {
9924            if (!mSupportsPictureInPicture) {
9925                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9926                        + "Device doesn't support picture-in-pciture mode");
9927            }
9928
9929            long ident = Binder.clearCallingIdentity();
9930            try {
9931                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9932            } finally {
9933                Binder.restoreCallingIdentity(ident);
9934            }
9935        }
9936    }
9937
9938    @Override
9939    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9940            boolean preserveWindows, boolean animate, int animationDuration) {
9941        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9942        long ident = Binder.clearCallingIdentity();
9943        try {
9944            synchronized (this) {
9945                if (animate) {
9946                    if (stackId == PINNED_STACK_ID) {
9947                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9948                    } else {
9949                        throw new IllegalArgumentException("Stack: " + stackId
9950                                + " doesn't support animated resize.");
9951                    }
9952                } else {
9953                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9954                            null /* tempTaskInsetBounds */, preserveWindows,
9955                            allowResizeInDockedMode, !DEFER_RESUME);
9956                }
9957            }
9958        } finally {
9959            Binder.restoreCallingIdentity(ident);
9960        }
9961    }
9962
9963    @Override
9964    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9965            Rect tempDockedTaskInsetBounds,
9966            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9967        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9968                "resizeDockedStack()");
9969        long ident = Binder.clearCallingIdentity();
9970        try {
9971            synchronized (this) {
9972                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9973                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9974                        PRESERVE_WINDOWS);
9975            }
9976        } finally {
9977            Binder.restoreCallingIdentity(ident);
9978        }
9979    }
9980
9981    @Override
9982    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9983        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9984                "resizePinnedStack()");
9985        final long ident = Binder.clearCallingIdentity();
9986        try {
9987            synchronized (this) {
9988                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9989            }
9990        } finally {
9991            Binder.restoreCallingIdentity(ident);
9992        }
9993    }
9994
9995    @Override
9996    public void positionTaskInStack(int taskId, int stackId, int position) {
9997        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9998        if (stackId == HOME_STACK_ID) {
9999            throw new IllegalArgumentException(
10000                    "positionTaskInStack: Attempt to change the position of task "
10001                    + taskId + " in/to home stack");
10002        }
10003        synchronized (this) {
10004            long ident = Binder.clearCallingIdentity();
10005            try {
10006                if (DEBUG_STACK) Slog.d(TAG_STACK,
10007                        "positionTaskInStack: positioning task=" + taskId
10008                        + " in stackId=" + stackId + " at position=" + position);
10009                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10010            } finally {
10011                Binder.restoreCallingIdentity(ident);
10012            }
10013        }
10014    }
10015
10016    @Override
10017    public List<StackInfo> getAllStackInfos() {
10018        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10019        long ident = Binder.clearCallingIdentity();
10020        try {
10021            synchronized (this) {
10022                return mStackSupervisor.getAllStackInfosLocked();
10023            }
10024        } finally {
10025            Binder.restoreCallingIdentity(ident);
10026        }
10027    }
10028
10029    @Override
10030    public StackInfo getStackInfo(int stackId) {
10031        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10032        long ident = Binder.clearCallingIdentity();
10033        try {
10034            synchronized (this) {
10035                return mStackSupervisor.getStackInfoLocked(stackId);
10036            }
10037        } finally {
10038            Binder.restoreCallingIdentity(ident);
10039        }
10040    }
10041
10042    @Override
10043    public boolean isInHomeStack(int taskId) {
10044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10045        long ident = Binder.clearCallingIdentity();
10046        try {
10047            synchronized (this) {
10048                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10049                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10050                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10051            }
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10059        synchronized(this) {
10060            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10061        }
10062    }
10063
10064    @Override
10065    public void updateDeviceOwner(String packageName) {
10066        final int callingUid = Binder.getCallingUid();
10067        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10068            throw new SecurityException("updateDeviceOwner called from non-system process");
10069        }
10070        synchronized (this) {
10071            mDeviceOwnerName = packageName;
10072        }
10073    }
10074
10075    @Override
10076    public void updateLockTaskPackages(int userId, String[] packages) {
10077        final int callingUid = Binder.getCallingUid();
10078        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10079            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10080                    "updateLockTaskPackages()");
10081        }
10082        synchronized (this) {
10083            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10084                    Arrays.toString(packages));
10085            mLockTaskPackages.put(userId, packages);
10086            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10087        }
10088    }
10089
10090
10091    void startLockTaskModeLocked(TaskRecord task) {
10092        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10093        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10094            return;
10095        }
10096
10097        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10098        // is initiated by system after the pinning request was shown and locked mode is initiated
10099        // by an authorized app directly
10100        final int callingUid = Binder.getCallingUid();
10101        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10102        long ident = Binder.clearCallingIdentity();
10103        try {
10104            if (!isSystemInitiated) {
10105                task.mLockTaskUid = callingUid;
10106                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10107                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10108                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10109                    StatusBarManagerInternal statusBarManager =
10110                            LocalServices.getService(StatusBarManagerInternal.class);
10111                    if (statusBarManager != null) {
10112                        statusBarManager.showScreenPinningRequest(task.taskId);
10113                    }
10114                    return;
10115                }
10116
10117                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10118                if (stack == null || task != stack.topTask()) {
10119                    throw new IllegalArgumentException("Invalid task, not in foreground");
10120                }
10121            }
10122            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10123                    "Locking fully");
10124            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10125                    ActivityManager.LOCK_TASK_MODE_PINNED :
10126                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10127                    "startLockTask", true);
10128        } finally {
10129            Binder.restoreCallingIdentity(ident);
10130        }
10131    }
10132
10133    @Override
10134    public void startLockTaskMode(int taskId) {
10135        synchronized (this) {
10136            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10137            if (task != null) {
10138                startLockTaskModeLocked(task);
10139            }
10140        }
10141    }
10142
10143    @Override
10144    public void startLockTaskMode(IBinder token) {
10145        synchronized (this) {
10146            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10147            if (r == null) {
10148                return;
10149            }
10150            final TaskRecord task = r.task;
10151            if (task != null) {
10152                startLockTaskModeLocked(task);
10153            }
10154        }
10155    }
10156
10157    @Override
10158    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10159        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10160        // This makes inner call to look as if it was initiated by system.
10161        long ident = Binder.clearCallingIdentity();
10162        try {
10163            synchronized (this) {
10164                startLockTaskMode(taskId);
10165            }
10166        } finally {
10167            Binder.restoreCallingIdentity(ident);
10168        }
10169    }
10170
10171    @Override
10172    public void stopLockTaskMode() {
10173        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10174        if (lockTask == null) {
10175            // Our work here is done.
10176            return;
10177        }
10178
10179        final int callingUid = Binder.getCallingUid();
10180        final int lockTaskUid = lockTask.mLockTaskUid;
10181        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10182        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10183            // Done.
10184            return;
10185        } else {
10186            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10187            // It is possible lockTaskMode was started by the system process because
10188            // android:lockTaskMode is set to a locking value in the application manifest
10189            // instead of the app calling startLockTaskMode. In this case
10190            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10191            // {@link TaskRecord.effectiveUid} instead. Also caller with
10192            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10193            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10194                    && callingUid != lockTaskUid
10195                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10196                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10197                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10198            }
10199        }
10200        long ident = Binder.clearCallingIdentity();
10201        try {
10202            Log.d(TAG, "stopLockTaskMode");
10203            // Stop lock task
10204            synchronized (this) {
10205                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10206                        "stopLockTask", true);
10207            }
10208            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10209            if (tm != null) {
10210                tm.showInCallScreen(false);
10211            }
10212        } finally {
10213            Binder.restoreCallingIdentity(ident);
10214        }
10215    }
10216
10217    /**
10218     * This API should be called by SystemUI only when user perform certain action to dismiss
10219     * lock task mode. We should only dismiss pinned lock task mode in this case.
10220     */
10221    @Override
10222    public void stopSystemLockTaskMode() throws RemoteException {
10223        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10224            stopLockTaskMode();
10225        } else {
10226            mStackSupervisor.showLockTaskToast();
10227        }
10228    }
10229
10230    @Override
10231    public boolean isInLockTaskMode() {
10232        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10233    }
10234
10235    @Override
10236    public int getLockTaskModeState() {
10237        synchronized (this) {
10238            return mStackSupervisor.getLockTaskModeState();
10239        }
10240    }
10241
10242    @Override
10243    public void showLockTaskEscapeMessage(IBinder token) {
10244        synchronized (this) {
10245            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10246            if (r == null) {
10247                return;
10248            }
10249            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10250        }
10251    }
10252
10253    // =========================================================
10254    // CONTENT PROVIDERS
10255    // =========================================================
10256
10257    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10258        List<ProviderInfo> providers = null;
10259        try {
10260            providers = AppGlobals.getPackageManager()
10261                    .queryContentProviders(app.processName, app.uid,
10262                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10263                                    | MATCH_DEBUG_TRIAGED_MISSING)
10264                    .getList();
10265        } catch (RemoteException ex) {
10266        }
10267        if (DEBUG_MU) Slog.v(TAG_MU,
10268                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10269        int userId = app.userId;
10270        if (providers != null) {
10271            int N = providers.size();
10272            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10273            for (int i=0; i<N; i++) {
10274                // TODO: keep logic in sync with installEncryptionUnawareProviders
10275                ProviderInfo cpi =
10276                    (ProviderInfo)providers.get(i);
10277                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10278                        cpi.name, cpi.flags);
10279                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10280                    // This is a singleton provider, but a user besides the
10281                    // default user is asking to initialize a process it runs
10282                    // in...  well, no, it doesn't actually run in this process,
10283                    // it runs in the process of the default user.  Get rid of it.
10284                    providers.remove(i);
10285                    N--;
10286                    i--;
10287                    continue;
10288                }
10289
10290                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10291                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10292                if (cpr == null) {
10293                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10294                    mProviderMap.putProviderByClass(comp, cpr);
10295                }
10296                if (DEBUG_MU) Slog.v(TAG_MU,
10297                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10298                app.pubProviders.put(cpi.name, cpr);
10299                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10300                    // Don't add this if it is a platform component that is marked
10301                    // to run in multiple processes, because this is actually
10302                    // part of the framework so doesn't make sense to track as a
10303                    // separate apk in the process.
10304                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10305                            mProcessStats);
10306                }
10307                notifyPackageUse(cpi.applicationInfo.packageName,
10308                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10309            }
10310        }
10311        return providers;
10312    }
10313
10314    /**
10315     * Check if {@link ProcessRecord} has a possible chance at accessing the
10316     * given {@link ProviderInfo}. Final permission checking is always done
10317     * in {@link ContentProvider}.
10318     */
10319    private final String checkContentProviderPermissionLocked(
10320            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10321        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10322        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10323        boolean checkedGrants = false;
10324        if (checkUser) {
10325            // Looking for cross-user grants before enforcing the typical cross-users permissions
10326            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10327            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10328                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10329                    return null;
10330                }
10331                checkedGrants = true;
10332            }
10333            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10334                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10335            if (userId != tmpTargetUserId) {
10336                // When we actually went to determine the final targer user ID, this ended
10337                // up different than our initial check for the authority.  This is because
10338                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10339                // SELF.  So we need to re-check the grants again.
10340                checkedGrants = false;
10341            }
10342        }
10343        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10344                cpi.applicationInfo.uid, cpi.exported)
10345                == PackageManager.PERMISSION_GRANTED) {
10346            return null;
10347        }
10348        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10349                cpi.applicationInfo.uid, cpi.exported)
10350                == PackageManager.PERMISSION_GRANTED) {
10351            return null;
10352        }
10353
10354        PathPermission[] pps = cpi.pathPermissions;
10355        if (pps != null) {
10356            int i = pps.length;
10357            while (i > 0) {
10358                i--;
10359                PathPermission pp = pps[i];
10360                String pprperm = pp.getReadPermission();
10361                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10362                        cpi.applicationInfo.uid, cpi.exported)
10363                        == PackageManager.PERMISSION_GRANTED) {
10364                    return null;
10365                }
10366                String ppwperm = pp.getWritePermission();
10367                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10368                        cpi.applicationInfo.uid, cpi.exported)
10369                        == PackageManager.PERMISSION_GRANTED) {
10370                    return null;
10371                }
10372            }
10373        }
10374        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10375            return null;
10376        }
10377
10378        String msg;
10379        if (!cpi.exported) {
10380            msg = "Permission Denial: opening provider " + cpi.name
10381                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10382                    + ", uid=" + callingUid + ") that is not exported from uid "
10383                    + cpi.applicationInfo.uid;
10384        } else {
10385            msg = "Permission Denial: opening provider " + cpi.name
10386                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10387                    + ", uid=" + callingUid + ") requires "
10388                    + cpi.readPermission + " or " + cpi.writePermission;
10389        }
10390        Slog.w(TAG, msg);
10391        return msg;
10392    }
10393
10394    /**
10395     * Returns if the ContentProvider has granted a uri to callingUid
10396     */
10397    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10398        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10399        if (perms != null) {
10400            for (int i=perms.size()-1; i>=0; i--) {
10401                GrantUri grantUri = perms.keyAt(i);
10402                if (grantUri.sourceUserId == userId || !checkUser) {
10403                    if (matchesProvider(grantUri.uri, cpi)) {
10404                        return true;
10405                    }
10406                }
10407            }
10408        }
10409        return false;
10410    }
10411
10412    /**
10413     * Returns true if the uri authority is one of the authorities specified in the provider.
10414     */
10415    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10416        String uriAuth = uri.getAuthority();
10417        String cpiAuth = cpi.authority;
10418        if (cpiAuth.indexOf(';') == -1) {
10419            return cpiAuth.equals(uriAuth);
10420        }
10421        String[] cpiAuths = cpiAuth.split(";");
10422        int length = cpiAuths.length;
10423        for (int i = 0; i < length; i++) {
10424            if (cpiAuths[i].equals(uriAuth)) return true;
10425        }
10426        return false;
10427    }
10428
10429    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10430            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10431        if (r != null) {
10432            for (int i=0; i<r.conProviders.size(); i++) {
10433                ContentProviderConnection conn = r.conProviders.get(i);
10434                if (conn.provider == cpr) {
10435                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10436                            "Adding provider requested by "
10437                            + r.processName + " from process "
10438                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10439                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10440                    if (stable) {
10441                        conn.stableCount++;
10442                        conn.numStableIncs++;
10443                    } else {
10444                        conn.unstableCount++;
10445                        conn.numUnstableIncs++;
10446                    }
10447                    return conn;
10448                }
10449            }
10450            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10451            if (stable) {
10452                conn.stableCount = 1;
10453                conn.numStableIncs = 1;
10454            } else {
10455                conn.unstableCount = 1;
10456                conn.numUnstableIncs = 1;
10457            }
10458            cpr.connections.add(conn);
10459            r.conProviders.add(conn);
10460            startAssociationLocked(r.uid, r.processName, r.curProcState,
10461                    cpr.uid, cpr.name, cpr.info.processName);
10462            return conn;
10463        }
10464        cpr.addExternalProcessHandleLocked(externalProcessToken);
10465        return null;
10466    }
10467
10468    boolean decProviderCountLocked(ContentProviderConnection conn,
10469            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10470        if (conn != null) {
10471            cpr = conn.provider;
10472            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10473                    "Removing provider requested by "
10474                    + conn.client.processName + " from process "
10475                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10476                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10477            if (stable) {
10478                conn.stableCount--;
10479            } else {
10480                conn.unstableCount--;
10481            }
10482            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10483                cpr.connections.remove(conn);
10484                conn.client.conProviders.remove(conn);
10485                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10486                    // The client is more important than last activity -- note the time this
10487                    // is happening, so we keep the old provider process around a bit as last
10488                    // activity to avoid thrashing it.
10489                    if (cpr.proc != null) {
10490                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10491                    }
10492                }
10493                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10494                return true;
10495            }
10496            return false;
10497        }
10498        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10499        return false;
10500    }
10501
10502    private void checkTime(long startTime, String where) {
10503        long now = SystemClock.uptimeMillis();
10504        if ((now-startTime) > 50) {
10505            // If we are taking more than 50ms, log about it.
10506            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10507        }
10508    }
10509
10510    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10511            String name, IBinder token, boolean stable, int userId) {
10512        ContentProviderRecord cpr;
10513        ContentProviderConnection conn = null;
10514        ProviderInfo cpi = null;
10515
10516        synchronized(this) {
10517            long startTime = SystemClock.uptimeMillis();
10518
10519            ProcessRecord r = null;
10520            if (caller != null) {
10521                r = getRecordForAppLocked(caller);
10522                if (r == null) {
10523                    throw new SecurityException(
10524                            "Unable to find app for caller " + caller
10525                          + " (pid=" + Binder.getCallingPid()
10526                          + ") when getting content provider " + name);
10527                }
10528            }
10529
10530            boolean checkCrossUser = true;
10531
10532            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10533
10534            // First check if this content provider has been published...
10535            cpr = mProviderMap.getProviderByName(name, userId);
10536            // If that didn't work, check if it exists for user 0 and then
10537            // verify that it's a singleton provider before using it.
10538            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10539                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10540                if (cpr != null) {
10541                    cpi = cpr.info;
10542                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10543                            cpi.name, cpi.flags)
10544                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10545                        userId = UserHandle.USER_SYSTEM;
10546                        checkCrossUser = false;
10547                    } else {
10548                        cpr = null;
10549                        cpi = null;
10550                    }
10551                }
10552            }
10553
10554            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10555            if (providerRunning) {
10556                cpi = cpr.info;
10557                String msg;
10558                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10559                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10560                        != null) {
10561                    throw new SecurityException(msg);
10562                }
10563                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10564
10565                if (r != null && cpr.canRunHere(r)) {
10566                    // This provider has been published or is in the process
10567                    // of being published...  but it is also allowed to run
10568                    // in the caller's process, so don't make a connection
10569                    // and just let the caller instantiate its own instance.
10570                    ContentProviderHolder holder = cpr.newHolder(null);
10571                    // don't give caller the provider object, it needs
10572                    // to make its own.
10573                    holder.provider = null;
10574                    return holder;
10575                }
10576
10577                final long origId = Binder.clearCallingIdentity();
10578
10579                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10580
10581                // In this case the provider instance already exists, so we can
10582                // return it right away.
10583                conn = incProviderCountLocked(r, cpr, token, stable);
10584                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10585                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10586                        // If this is a perceptible app accessing the provider,
10587                        // make sure to count it as being accessed and thus
10588                        // back up on the LRU list.  This is good because
10589                        // content providers are often expensive to start.
10590                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10591                        updateLruProcessLocked(cpr.proc, false, null);
10592                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10593                    }
10594                }
10595
10596                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10597                boolean success = updateOomAdjLocked(cpr.proc);
10598                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10599                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10600                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10601                // NOTE: there is still a race here where a signal could be
10602                // pending on the process even though we managed to update its
10603                // adj level.  Not sure what to do about this, but at least
10604                // the race is now smaller.
10605                if (!success) {
10606                    // Uh oh...  it looks like the provider's process
10607                    // has been killed on us.  We need to wait for a new
10608                    // process to be started, and make sure its death
10609                    // doesn't kill our process.
10610                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10611                            + " is crashing; detaching " + r);
10612                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10613                    checkTime(startTime, "getContentProviderImpl: before appDied");
10614                    appDiedLocked(cpr.proc);
10615                    checkTime(startTime, "getContentProviderImpl: after appDied");
10616                    if (!lastRef) {
10617                        // This wasn't the last ref our process had on
10618                        // the provider...  we have now been killed, bail.
10619                        return null;
10620                    }
10621                    providerRunning = false;
10622                    conn = null;
10623                }
10624
10625                Binder.restoreCallingIdentity(origId);
10626            }
10627
10628            if (!providerRunning) {
10629                try {
10630                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10631                    cpi = AppGlobals.getPackageManager().
10632                        resolveContentProvider(name,
10633                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10634                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10635                } catch (RemoteException ex) {
10636                }
10637                if (cpi == null) {
10638                    return null;
10639                }
10640                // If the provider is a singleton AND
10641                // (it's a call within the same user || the provider is a
10642                // privileged app)
10643                // Then allow connecting to the singleton provider
10644                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10645                        cpi.name, cpi.flags)
10646                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10647                if (singleton) {
10648                    userId = UserHandle.USER_SYSTEM;
10649                }
10650                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10651                checkTime(startTime, "getContentProviderImpl: got app info for user");
10652
10653                String msg;
10654                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10655                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10656                        != null) {
10657                    throw new SecurityException(msg);
10658                }
10659                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10660
10661                if (!mProcessesReady
10662                        && !cpi.processName.equals("system")) {
10663                    // If this content provider does not run in the system
10664                    // process, and the system is not yet ready to run other
10665                    // processes, then fail fast instead of hanging.
10666                    throw new IllegalArgumentException(
10667                            "Attempt to launch content provider before system ready");
10668                }
10669
10670                // Make sure that the user who owns this provider is running.  If not,
10671                // we don't want to allow it to run.
10672                if (!mUserController.isUserRunningLocked(userId, 0)) {
10673                    Slog.w(TAG, "Unable to launch app "
10674                            + cpi.applicationInfo.packageName + "/"
10675                            + cpi.applicationInfo.uid + " for provider "
10676                            + name + ": user " + userId + " is stopped");
10677                    return null;
10678                }
10679
10680                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10681                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10682                cpr = mProviderMap.getProviderByClass(comp, userId);
10683                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10684                final boolean firstClass = cpr == null;
10685                if (firstClass) {
10686                    final long ident = Binder.clearCallingIdentity();
10687
10688                    // If permissions need a review before any of the app components can run,
10689                    // we return no provider and launch a review activity if the calling app
10690                    // is in the foreground.
10691                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10692                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10693                            return null;
10694                        }
10695                    }
10696
10697                    try {
10698                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10699                        ApplicationInfo ai =
10700                            AppGlobals.getPackageManager().
10701                                getApplicationInfo(
10702                                        cpi.applicationInfo.packageName,
10703                                        STOCK_PM_FLAGS, userId);
10704                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10705                        if (ai == null) {
10706                            Slog.w(TAG, "No package info for content provider "
10707                                    + cpi.name);
10708                            return null;
10709                        }
10710                        ai = getAppInfoForUser(ai, userId);
10711                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10712                    } catch (RemoteException ex) {
10713                        // pm is in same process, this will never happen.
10714                    } finally {
10715                        Binder.restoreCallingIdentity(ident);
10716                    }
10717                }
10718
10719                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10720
10721                if (r != null && cpr.canRunHere(r)) {
10722                    // If this is a multiprocess provider, then just return its
10723                    // info and allow the caller to instantiate it.  Only do
10724                    // this if the provider is the same user as the caller's
10725                    // process, or can run as root (so can be in any process).
10726                    return cpr.newHolder(null);
10727                }
10728
10729                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10730                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10731                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10732
10733                // This is single process, and our app is now connecting to it.
10734                // See if we are already in the process of launching this
10735                // provider.
10736                final int N = mLaunchingProviders.size();
10737                int i;
10738                for (i = 0; i < N; i++) {
10739                    if (mLaunchingProviders.get(i) == cpr) {
10740                        break;
10741                    }
10742                }
10743
10744                // If the provider is not already being launched, then get it
10745                // started.
10746                if (i >= N) {
10747                    final long origId = Binder.clearCallingIdentity();
10748
10749                    try {
10750                        // Content provider is now in use, its package can't be stopped.
10751                        try {
10752                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10753                            AppGlobals.getPackageManager().setPackageStoppedState(
10754                                    cpr.appInfo.packageName, false, userId);
10755                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10756                        } catch (RemoteException e) {
10757                        } catch (IllegalArgumentException e) {
10758                            Slog.w(TAG, "Failed trying to unstop package "
10759                                    + cpr.appInfo.packageName + ": " + e);
10760                        }
10761
10762                        // Use existing process if already started
10763                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10764                        ProcessRecord proc = getProcessRecordLocked(
10765                                cpi.processName, cpr.appInfo.uid, false);
10766                        if (proc != null && proc.thread != null && !proc.killed) {
10767                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10768                                    "Installing in existing process " + proc);
10769                            if (!proc.pubProviders.containsKey(cpi.name)) {
10770                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10771                                proc.pubProviders.put(cpi.name, cpr);
10772                                try {
10773                                    proc.thread.scheduleInstallProvider(cpi);
10774                                } catch (RemoteException e) {
10775                                }
10776                            }
10777                        } else {
10778                            checkTime(startTime, "getContentProviderImpl: before start process");
10779                            proc = startProcessLocked(cpi.processName,
10780                                    cpr.appInfo, false, 0, "content provider",
10781                                    new ComponentName(cpi.applicationInfo.packageName,
10782                                            cpi.name), false, false, false);
10783                            checkTime(startTime, "getContentProviderImpl: after start process");
10784                            if (proc == null) {
10785                                Slog.w(TAG, "Unable to launch app "
10786                                        + cpi.applicationInfo.packageName + "/"
10787                                        + cpi.applicationInfo.uid + " for provider "
10788                                        + name + ": process is bad");
10789                                return null;
10790                            }
10791                        }
10792                        cpr.launchingApp = proc;
10793                        mLaunchingProviders.add(cpr);
10794                    } finally {
10795                        Binder.restoreCallingIdentity(origId);
10796                    }
10797                }
10798
10799                checkTime(startTime, "getContentProviderImpl: updating data structures");
10800
10801                // Make sure the provider is published (the same provider class
10802                // may be published under multiple names).
10803                if (firstClass) {
10804                    mProviderMap.putProviderByClass(comp, cpr);
10805                }
10806
10807                mProviderMap.putProviderByName(name, cpr);
10808                conn = incProviderCountLocked(r, cpr, token, stable);
10809                if (conn != null) {
10810                    conn.waiting = true;
10811                }
10812            }
10813            checkTime(startTime, "getContentProviderImpl: done!");
10814        }
10815
10816        // Wait for the provider to be published...
10817        synchronized (cpr) {
10818            while (cpr.provider == null) {
10819                if (cpr.launchingApp == null) {
10820                    Slog.w(TAG, "Unable to launch app "
10821                            + cpi.applicationInfo.packageName + "/"
10822                            + cpi.applicationInfo.uid + " for provider "
10823                            + name + ": launching app became null");
10824                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10825                            UserHandle.getUserId(cpi.applicationInfo.uid),
10826                            cpi.applicationInfo.packageName,
10827                            cpi.applicationInfo.uid, name);
10828                    return null;
10829                }
10830                try {
10831                    if (DEBUG_MU) Slog.v(TAG_MU,
10832                            "Waiting to start provider " + cpr
10833                            + " launchingApp=" + cpr.launchingApp);
10834                    if (conn != null) {
10835                        conn.waiting = true;
10836                    }
10837                    cpr.wait();
10838                } catch (InterruptedException ex) {
10839                } finally {
10840                    if (conn != null) {
10841                        conn.waiting = false;
10842                    }
10843                }
10844            }
10845        }
10846        return cpr != null ? cpr.newHolder(conn) : null;
10847    }
10848
10849    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10850            ProcessRecord r, final int userId) {
10851        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10852                cpi.packageName, userId)) {
10853
10854            final boolean callerForeground = r == null || r.setSchedGroup
10855                    != ProcessList.SCHED_GROUP_BACKGROUND;
10856
10857            // Show a permission review UI only for starting from a foreground app
10858            if (!callerForeground) {
10859                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10860                        + cpi.packageName + " requires a permissions review");
10861                return false;
10862            }
10863
10864            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10865            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10866                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10867            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10868
10869            if (DEBUG_PERMISSIONS_REVIEW) {
10870                Slog.i(TAG, "u" + userId + " Launching permission review "
10871                        + "for package " + cpi.packageName);
10872            }
10873
10874            final UserHandle userHandle = new UserHandle(userId);
10875            mHandler.post(new Runnable() {
10876                @Override
10877                public void run() {
10878                    mContext.startActivityAsUser(intent, userHandle);
10879                }
10880            });
10881
10882            return false;
10883        }
10884
10885        return true;
10886    }
10887
10888    PackageManagerInternal getPackageManagerInternalLocked() {
10889        if (mPackageManagerInt == null) {
10890            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10891        }
10892        return mPackageManagerInt;
10893    }
10894
10895    @Override
10896    public final ContentProviderHolder getContentProvider(
10897            IApplicationThread caller, String name, int userId, boolean stable) {
10898        enforceNotIsolatedCaller("getContentProvider");
10899        if (caller == null) {
10900            String msg = "null IApplicationThread when getting content provider "
10901                    + name;
10902            Slog.w(TAG, msg);
10903            throw new SecurityException(msg);
10904        }
10905        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10906        // with cross-user grant.
10907        return getContentProviderImpl(caller, name, null, stable, userId);
10908    }
10909
10910    public ContentProviderHolder getContentProviderExternal(
10911            String name, int userId, IBinder token) {
10912        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10913            "Do not have permission in call getContentProviderExternal()");
10914        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10915                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10916        return getContentProviderExternalUnchecked(name, token, userId);
10917    }
10918
10919    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10920            IBinder token, int userId) {
10921        return getContentProviderImpl(null, name, token, true, userId);
10922    }
10923
10924    /**
10925     * Drop a content provider from a ProcessRecord's bookkeeping
10926     */
10927    public void removeContentProvider(IBinder connection, boolean stable) {
10928        enforceNotIsolatedCaller("removeContentProvider");
10929        long ident = Binder.clearCallingIdentity();
10930        try {
10931            synchronized (this) {
10932                ContentProviderConnection conn;
10933                try {
10934                    conn = (ContentProviderConnection)connection;
10935                } catch (ClassCastException e) {
10936                    String msg ="removeContentProvider: " + connection
10937                            + " not a ContentProviderConnection";
10938                    Slog.w(TAG, msg);
10939                    throw new IllegalArgumentException(msg);
10940                }
10941                if (conn == null) {
10942                    throw new NullPointerException("connection is null");
10943                }
10944                if (decProviderCountLocked(conn, null, null, stable)) {
10945                    updateOomAdjLocked();
10946                }
10947            }
10948        } finally {
10949            Binder.restoreCallingIdentity(ident);
10950        }
10951    }
10952
10953    public void removeContentProviderExternal(String name, IBinder token) {
10954        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10955            "Do not have permission in call removeContentProviderExternal()");
10956        int userId = UserHandle.getCallingUserId();
10957        long ident = Binder.clearCallingIdentity();
10958        try {
10959            removeContentProviderExternalUnchecked(name, token, userId);
10960        } finally {
10961            Binder.restoreCallingIdentity(ident);
10962        }
10963    }
10964
10965    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10966        synchronized (this) {
10967            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10968            if(cpr == null) {
10969                //remove from mProvidersByClass
10970                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10971                return;
10972            }
10973
10974            //update content provider record entry info
10975            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10976            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10977            if (localCpr.hasExternalProcessHandles()) {
10978                if (localCpr.removeExternalProcessHandleLocked(token)) {
10979                    updateOomAdjLocked();
10980                } else {
10981                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10982                            + " with no external reference for token: "
10983                            + token + ".");
10984                }
10985            } else {
10986                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10987                        + " with no external references.");
10988            }
10989        }
10990    }
10991
10992    public final void publishContentProviders(IApplicationThread caller,
10993            List<ContentProviderHolder> providers) {
10994        if (providers == null) {
10995            return;
10996        }
10997
10998        enforceNotIsolatedCaller("publishContentProviders");
10999        synchronized (this) {
11000            final ProcessRecord r = getRecordForAppLocked(caller);
11001            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11002            if (r == null) {
11003                throw new SecurityException(
11004                        "Unable to find app for caller " + caller
11005                      + " (pid=" + Binder.getCallingPid()
11006                      + ") when publishing content providers");
11007            }
11008
11009            final long origId = Binder.clearCallingIdentity();
11010
11011            final int N = providers.size();
11012            for (int i = 0; i < N; i++) {
11013                ContentProviderHolder src = providers.get(i);
11014                if (src == null || src.info == null || src.provider == null) {
11015                    continue;
11016                }
11017                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11018                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11019                if (dst != null) {
11020                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11021                    mProviderMap.putProviderByClass(comp, dst);
11022                    String names[] = dst.info.authority.split(";");
11023                    for (int j = 0; j < names.length; j++) {
11024                        mProviderMap.putProviderByName(names[j], dst);
11025                    }
11026
11027                    int launchingCount = mLaunchingProviders.size();
11028                    int j;
11029                    boolean wasInLaunchingProviders = false;
11030                    for (j = 0; j < launchingCount; j++) {
11031                        if (mLaunchingProviders.get(j) == dst) {
11032                            mLaunchingProviders.remove(j);
11033                            wasInLaunchingProviders = true;
11034                            j--;
11035                            launchingCount--;
11036                        }
11037                    }
11038                    if (wasInLaunchingProviders) {
11039                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11040                    }
11041                    synchronized (dst) {
11042                        dst.provider = src.provider;
11043                        dst.proc = r;
11044                        dst.notifyAll();
11045                    }
11046                    updateOomAdjLocked(r);
11047                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11048                            src.info.authority);
11049                }
11050            }
11051
11052            Binder.restoreCallingIdentity(origId);
11053        }
11054    }
11055
11056    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11057        ContentProviderConnection conn;
11058        try {
11059            conn = (ContentProviderConnection)connection;
11060        } catch (ClassCastException e) {
11061            String msg ="refContentProvider: " + connection
11062                    + " not a ContentProviderConnection";
11063            Slog.w(TAG, msg);
11064            throw new IllegalArgumentException(msg);
11065        }
11066        if (conn == null) {
11067            throw new NullPointerException("connection is null");
11068        }
11069
11070        synchronized (this) {
11071            if (stable > 0) {
11072                conn.numStableIncs += stable;
11073            }
11074            stable = conn.stableCount + stable;
11075            if (stable < 0) {
11076                throw new IllegalStateException("stableCount < 0: " + stable);
11077            }
11078
11079            if (unstable > 0) {
11080                conn.numUnstableIncs += unstable;
11081            }
11082            unstable = conn.unstableCount + unstable;
11083            if (unstable < 0) {
11084                throw new IllegalStateException("unstableCount < 0: " + unstable);
11085            }
11086
11087            if ((stable+unstable) <= 0) {
11088                throw new IllegalStateException("ref counts can't go to zero here: stable="
11089                        + stable + " unstable=" + unstable);
11090            }
11091            conn.stableCount = stable;
11092            conn.unstableCount = unstable;
11093            return !conn.dead;
11094        }
11095    }
11096
11097    public void unstableProviderDied(IBinder connection) {
11098        ContentProviderConnection conn;
11099        try {
11100            conn = (ContentProviderConnection)connection;
11101        } catch (ClassCastException e) {
11102            String msg ="refContentProvider: " + connection
11103                    + " not a ContentProviderConnection";
11104            Slog.w(TAG, msg);
11105            throw new IllegalArgumentException(msg);
11106        }
11107        if (conn == null) {
11108            throw new NullPointerException("connection is null");
11109        }
11110
11111        // Safely retrieve the content provider associated with the connection.
11112        IContentProvider provider;
11113        synchronized (this) {
11114            provider = conn.provider.provider;
11115        }
11116
11117        if (provider == null) {
11118            // Um, yeah, we're way ahead of you.
11119            return;
11120        }
11121
11122        // Make sure the caller is being honest with us.
11123        if (provider.asBinder().pingBinder()) {
11124            // Er, no, still looks good to us.
11125            synchronized (this) {
11126                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11127                        + " says " + conn + " died, but we don't agree");
11128                return;
11129            }
11130        }
11131
11132        // Well look at that!  It's dead!
11133        synchronized (this) {
11134            if (conn.provider.provider != provider) {
11135                // But something changed...  good enough.
11136                return;
11137            }
11138
11139            ProcessRecord proc = conn.provider.proc;
11140            if (proc == null || proc.thread == null) {
11141                // Seems like the process is already cleaned up.
11142                return;
11143            }
11144
11145            // As far as we're concerned, this is just like receiving a
11146            // death notification...  just a bit prematurely.
11147            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11148                    + ") early provider death");
11149            final long ident = Binder.clearCallingIdentity();
11150            try {
11151                appDiedLocked(proc);
11152            } finally {
11153                Binder.restoreCallingIdentity(ident);
11154            }
11155        }
11156    }
11157
11158    @Override
11159    public void appNotRespondingViaProvider(IBinder connection) {
11160        enforceCallingPermission(
11161                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11162
11163        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11164        if (conn == null) {
11165            Slog.w(TAG, "ContentProviderConnection is null");
11166            return;
11167        }
11168
11169        final ProcessRecord host = conn.provider.proc;
11170        if (host == null) {
11171            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11172            return;
11173        }
11174
11175        mHandler.post(new Runnable() {
11176            @Override
11177            public void run() {
11178                mAppErrors.appNotResponding(host, null, null, false,
11179                        "ContentProvider not responding");
11180            }
11181        });
11182    }
11183
11184    public final void installSystemProviders() {
11185        List<ProviderInfo> providers;
11186        synchronized (this) {
11187            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11188            providers = generateApplicationProvidersLocked(app);
11189            if (providers != null) {
11190                for (int i=providers.size()-1; i>=0; i--) {
11191                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11192                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11193                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11194                                + ": not system .apk");
11195                        providers.remove(i);
11196                    }
11197                }
11198            }
11199        }
11200        if (providers != null) {
11201            mSystemThread.installSystemProviders(providers);
11202        }
11203
11204        mCoreSettingsObserver = new CoreSettingsObserver(this);
11205        mFontScaleSettingObserver = new FontScaleSettingObserver();
11206
11207        //mUsageStatsService.monitorPackages();
11208    }
11209
11210    private void startPersistentApps(int matchFlags) {
11211        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11212
11213        synchronized (this) {
11214            try {
11215                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11216                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11217                for (ApplicationInfo app : apps) {
11218                    if (!"android".equals(app.packageName)) {
11219                        addAppLocked(app, false, null /* ABI override */);
11220                    }
11221                }
11222            } catch (RemoteException ex) {
11223            }
11224        }
11225    }
11226
11227    /**
11228     * When a user is unlocked, we need to install encryption-unaware providers
11229     * belonging to any running apps.
11230     */
11231    private void installEncryptionUnawareProviders(int userId) {
11232        // We're only interested in providers that are encryption unaware, and
11233        // we don't care about uninstalled apps, since there's no way they're
11234        // running at this point.
11235        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11236
11237        synchronized (this) {
11238            final int NP = mProcessNames.getMap().size();
11239            for (int ip = 0; ip < NP; ip++) {
11240                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11241                final int NA = apps.size();
11242                for (int ia = 0; ia < NA; ia++) {
11243                    final ProcessRecord app = apps.valueAt(ia);
11244                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11245
11246                    final int NG = app.pkgList.size();
11247                    for (int ig = 0; ig < NG; ig++) {
11248                        try {
11249                            final String pkgName = app.pkgList.keyAt(ig);
11250                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11251                                    .getPackageInfo(pkgName, matchFlags, userId);
11252                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11253                                for (ProviderInfo pi : pkgInfo.providers) {
11254                                    // TODO: keep in sync with generateApplicationProvidersLocked
11255                                    final boolean processMatch = Objects.equals(pi.processName,
11256                                            app.processName) || pi.multiprocess;
11257                                    final boolean userMatch = isSingleton(pi.processName,
11258                                            pi.applicationInfo, pi.name, pi.flags)
11259                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11260                                    if (processMatch && userMatch) {
11261                                        Log.v(TAG, "Installing " + pi);
11262                                        app.thread.scheduleInstallProvider(pi);
11263                                    } else {
11264                                        Log.v(TAG, "Skipping " + pi);
11265                                    }
11266                                }
11267                            }
11268                        } catch (RemoteException ignored) {
11269                        }
11270                    }
11271                }
11272            }
11273        }
11274    }
11275
11276    /**
11277     * Allows apps to retrieve the MIME type of a URI.
11278     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11279     * users, then it does not need permission to access the ContentProvider.
11280     * Either, it needs cross-user uri grants.
11281     *
11282     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11283     *
11284     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11285     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11286     */
11287    public String getProviderMimeType(Uri uri, int userId) {
11288        enforceNotIsolatedCaller("getProviderMimeType");
11289        final String name = uri.getAuthority();
11290        int callingUid = Binder.getCallingUid();
11291        int callingPid = Binder.getCallingPid();
11292        long ident = 0;
11293        boolean clearedIdentity = false;
11294        synchronized (this) {
11295            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11296        }
11297        if (canClearIdentity(callingPid, callingUid, userId)) {
11298            clearedIdentity = true;
11299            ident = Binder.clearCallingIdentity();
11300        }
11301        ContentProviderHolder holder = null;
11302        try {
11303            holder = getContentProviderExternalUnchecked(name, null, userId);
11304            if (holder != null) {
11305                return holder.provider.getType(uri);
11306            }
11307        } catch (RemoteException e) {
11308            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11309            return null;
11310        } catch (Exception e) {
11311            Log.w(TAG, "Exception while determining type of " + uri, e);
11312            return null;
11313        } finally {
11314            // We need to clear the identity to call removeContentProviderExternalUnchecked
11315            if (!clearedIdentity) {
11316                ident = Binder.clearCallingIdentity();
11317            }
11318            try {
11319                if (holder != null) {
11320                    removeContentProviderExternalUnchecked(name, null, userId);
11321                }
11322            } finally {
11323                Binder.restoreCallingIdentity(ident);
11324            }
11325        }
11326
11327        return null;
11328    }
11329
11330    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11331        if (UserHandle.getUserId(callingUid) == userId) {
11332            return true;
11333        }
11334        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11335                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11336                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11337                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11338                return true;
11339        }
11340        return false;
11341    }
11342
11343    // =========================================================
11344    // GLOBAL MANAGEMENT
11345    // =========================================================
11346
11347    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11348            boolean isolated, int isolatedUid) {
11349        String proc = customProcess != null ? customProcess : info.processName;
11350        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11351        final int userId = UserHandle.getUserId(info.uid);
11352        int uid = info.uid;
11353        if (isolated) {
11354            if (isolatedUid == 0) {
11355                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11356                while (true) {
11357                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11358                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11359                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11360                    }
11361                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11362                    mNextIsolatedProcessUid++;
11363                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11364                        // No process for this uid, use it.
11365                        break;
11366                    }
11367                    stepsLeft--;
11368                    if (stepsLeft <= 0) {
11369                        return null;
11370                    }
11371                }
11372            } else {
11373                // Special case for startIsolatedProcess (internal only), where
11374                // the uid of the isolated process is specified by the caller.
11375                uid = isolatedUid;
11376            }
11377        }
11378        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11379        if (!mBooted && !mBooting
11380                && userId == UserHandle.USER_SYSTEM
11381                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11382            r.persistent = true;
11383        }
11384        addProcessNameLocked(r);
11385        return r;
11386    }
11387
11388    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11389            String abiOverride) {
11390        ProcessRecord app;
11391        if (!isolated) {
11392            app = getProcessRecordLocked(info.processName, info.uid, true);
11393        } else {
11394            app = null;
11395        }
11396
11397        if (app == null) {
11398            app = newProcessRecordLocked(info, null, isolated, 0);
11399            updateLruProcessLocked(app, false, null);
11400            updateOomAdjLocked();
11401        }
11402
11403        // This package really, really can not be stopped.
11404        try {
11405            AppGlobals.getPackageManager().setPackageStoppedState(
11406                    info.packageName, false, UserHandle.getUserId(app.uid));
11407        } catch (RemoteException e) {
11408        } catch (IllegalArgumentException e) {
11409            Slog.w(TAG, "Failed trying to unstop package "
11410                    + info.packageName + ": " + e);
11411        }
11412
11413        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11414            app.persistent = true;
11415            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11416        }
11417        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11418            mPersistentStartingProcesses.add(app);
11419            startProcessLocked(app, "added application", app.processName, abiOverride,
11420                    null /* entryPoint */, null /* entryPointArgs */);
11421        }
11422
11423        return app;
11424    }
11425
11426    public void unhandledBack() {
11427        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11428                "unhandledBack()");
11429
11430        synchronized(this) {
11431            final long origId = Binder.clearCallingIdentity();
11432            try {
11433                getFocusedStack().unhandledBackLocked();
11434            } finally {
11435                Binder.restoreCallingIdentity(origId);
11436            }
11437        }
11438    }
11439
11440    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11441        enforceNotIsolatedCaller("openContentUri");
11442        final int userId = UserHandle.getCallingUserId();
11443        String name = uri.getAuthority();
11444        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11445        ParcelFileDescriptor pfd = null;
11446        if (cph != null) {
11447            // We record the binder invoker's uid in thread-local storage before
11448            // going to the content provider to open the file.  Later, in the code
11449            // that handles all permissions checks, we look for this uid and use
11450            // that rather than the Activity Manager's own uid.  The effect is that
11451            // we do the check against the caller's permissions even though it looks
11452            // to the content provider like the Activity Manager itself is making
11453            // the request.
11454            Binder token = new Binder();
11455            sCallerIdentity.set(new Identity(
11456                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11457            try {
11458                pfd = cph.provider.openFile(null, uri, "r", null, token);
11459            } catch (FileNotFoundException e) {
11460                // do nothing; pfd will be returned null
11461            } finally {
11462                // Ensure that whatever happens, we clean up the identity state
11463                sCallerIdentity.remove();
11464                // Ensure we're done with the provider.
11465                removeContentProviderExternalUnchecked(name, null, userId);
11466            }
11467        } else {
11468            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11469        }
11470        return pfd;
11471    }
11472
11473    // Actually is sleeping or shutting down or whatever else in the future
11474    // is an inactive state.
11475    public boolean isSleepingOrShuttingDown() {
11476        return isSleeping() || mShuttingDown;
11477    }
11478
11479    public boolean isSleeping() {
11480        return mSleeping;
11481    }
11482
11483    void onWakefulnessChanged(int wakefulness) {
11484        synchronized(this) {
11485            mWakefulness = wakefulness;
11486            updateSleepIfNeededLocked();
11487        }
11488    }
11489
11490    void finishRunningVoiceLocked() {
11491        if (mRunningVoice != null) {
11492            mRunningVoice = null;
11493            mVoiceWakeLock.release();
11494            updateSleepIfNeededLocked();
11495        }
11496    }
11497
11498    void startTimeTrackingFocusedActivityLocked() {
11499        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11500            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11501        }
11502    }
11503
11504    void updateSleepIfNeededLocked() {
11505        if (mSleeping && !shouldSleepLocked()) {
11506            mSleeping = false;
11507            startTimeTrackingFocusedActivityLocked();
11508            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11509            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11510            updateOomAdjLocked();
11511        } else if (!mSleeping && shouldSleepLocked()) {
11512            mSleeping = true;
11513            if (mCurAppTimeTracker != null) {
11514                mCurAppTimeTracker.stop();
11515            }
11516            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11517            mStackSupervisor.goingToSleepLocked();
11518            updateOomAdjLocked();
11519
11520            // Initialize the wake times of all processes.
11521            checkExcessivePowerUsageLocked(false);
11522            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11523            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11524            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11525        }
11526    }
11527
11528    private boolean shouldSleepLocked() {
11529        // Resume applications while running a voice interactor.
11530        if (mRunningVoice != null) {
11531            return false;
11532        }
11533
11534        // TODO: Transform the lock screen state into a sleep token instead.
11535        switch (mWakefulness) {
11536            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11537            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11538            case PowerManagerInternal.WAKEFULNESS_DOZING:
11539                // Pause applications whenever the lock screen is shown or any sleep
11540                // tokens have been acquired.
11541                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11542            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11543            default:
11544                // If we're asleep then pause applications unconditionally.
11545                return true;
11546        }
11547    }
11548
11549    /** Pokes the task persister. */
11550    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11551        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11552    }
11553
11554    /** Notifies all listeners when the task stack has changed. */
11555    void notifyTaskStackChangedLocked() {
11556        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11557        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11558        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11559        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11560    }
11561
11562    /** Notifies all listeners when an Activity is pinned. */
11563    void notifyActivityPinnedLocked() {
11564        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11565        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11566    }
11567
11568    /**
11569     * Notifies all listeners when an attempt was made to start an an activity that is already
11570     * running in the pinned stack and the activity was not actually started, but the task is
11571     * either brought to the front or a new Intent is delivered to it.
11572     */
11573    void notifyPinnedActivityRestartAttemptLocked() {
11574        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11575        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11576    }
11577
11578    /** Notifies all listeners when the pinned stack animation ends. */
11579    @Override
11580    public void notifyPinnedStackAnimationEnded() {
11581        synchronized (this) {
11582            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11583            mHandler.obtainMessage(
11584                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11585        }
11586    }
11587
11588    @Override
11589    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11590        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11591    }
11592
11593    @Override
11594    public boolean shutdown(int timeout) {
11595        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11596                != PackageManager.PERMISSION_GRANTED) {
11597            throw new SecurityException("Requires permission "
11598                    + android.Manifest.permission.SHUTDOWN);
11599        }
11600
11601        boolean timedout = false;
11602
11603        synchronized(this) {
11604            mShuttingDown = true;
11605            updateEventDispatchingLocked();
11606            timedout = mStackSupervisor.shutdownLocked(timeout);
11607        }
11608
11609        mAppOpsService.shutdown();
11610        if (mUsageStatsService != null) {
11611            mUsageStatsService.prepareShutdown();
11612        }
11613        mBatteryStatsService.shutdown();
11614        synchronized (this) {
11615            mProcessStats.shutdownLocked();
11616            notifyTaskPersisterLocked(null, true);
11617        }
11618
11619        return timedout;
11620    }
11621
11622    public final void activitySlept(IBinder token) {
11623        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11624
11625        final long origId = Binder.clearCallingIdentity();
11626
11627        synchronized (this) {
11628            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11629            if (r != null) {
11630                mStackSupervisor.activitySleptLocked(r);
11631            }
11632        }
11633
11634        Binder.restoreCallingIdentity(origId);
11635    }
11636
11637    private String lockScreenShownToString() {
11638        switch (mLockScreenShown) {
11639            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11640            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11641            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11642            default: return "Unknown=" + mLockScreenShown;
11643        }
11644    }
11645
11646    void logLockScreen(String msg) {
11647        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11648                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11649                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11650                + " mSleeping=" + mSleeping);
11651    }
11652
11653    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11654        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11655        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11656        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11657            boolean wasRunningVoice = mRunningVoice != null;
11658            mRunningVoice = session;
11659            if (!wasRunningVoice) {
11660                mVoiceWakeLock.acquire();
11661                updateSleepIfNeededLocked();
11662            }
11663        }
11664    }
11665
11666    private void updateEventDispatchingLocked() {
11667        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11668    }
11669
11670    public void setLockScreenShown(boolean showing, boolean occluded) {
11671        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11672                != PackageManager.PERMISSION_GRANTED) {
11673            throw new SecurityException("Requires permission "
11674                    + android.Manifest.permission.DEVICE_POWER);
11675        }
11676
11677        synchronized(this) {
11678            long ident = Binder.clearCallingIdentity();
11679            try {
11680                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11681                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11682                if (showing && occluded) {
11683                    // The lock screen is currently showing, but is occluded by a window that can
11684                    // show on top of the lock screen. In this can we want to dismiss the docked
11685                    // stack since it will be complicated/risky to try to put the activity on top
11686                    // of the lock screen in the right fullscreen configuration.
11687                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11688                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11689                }
11690
11691                updateSleepIfNeededLocked();
11692            } finally {
11693                Binder.restoreCallingIdentity(ident);
11694            }
11695        }
11696    }
11697
11698    @Override
11699    public void notifyLockedProfile(@UserIdInt int userId) {
11700        try {
11701            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11702                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11703            }
11704        } catch (RemoteException ex) {
11705            throw new SecurityException("Fail to check is caller a privileged app", ex);
11706        }
11707
11708        synchronized (this) {
11709            if (mStackSupervisor.isUserLockedProfile(userId)) {
11710                final long ident = Binder.clearCallingIdentity();
11711                try {
11712                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11713                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11714                        // If there is no device lock, we will show the profile's credential page.
11715                        mActivityStarter.showConfirmDeviceCredential(userId);
11716                    } else {
11717                        // Showing launcher to avoid user entering credential twice.
11718                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11719                    }
11720                } finally {
11721                    Binder.restoreCallingIdentity(ident);
11722                }
11723            }
11724        }
11725    }
11726
11727    @Override
11728    public void startConfirmDeviceCredentialIntent(Intent intent) {
11729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11730        synchronized (this) {
11731            final long ident = Binder.clearCallingIdentity();
11732            try {
11733                mActivityStarter.startConfirmCredentialIntent(intent);
11734            } finally {
11735                Binder.restoreCallingIdentity(ident);
11736            }
11737        }
11738    }
11739
11740    @Override
11741    public void stopAppSwitches() {
11742        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11743                != PackageManager.PERMISSION_GRANTED) {
11744            throw new SecurityException("viewquires permission "
11745                    + android.Manifest.permission.STOP_APP_SWITCHES);
11746        }
11747
11748        synchronized(this) {
11749            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11750                    + APP_SWITCH_DELAY_TIME;
11751            mDidAppSwitch = false;
11752            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11753            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11754            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11755        }
11756    }
11757
11758    public void resumeAppSwitches() {
11759        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11760                != PackageManager.PERMISSION_GRANTED) {
11761            throw new SecurityException("Requires permission "
11762                    + android.Manifest.permission.STOP_APP_SWITCHES);
11763        }
11764
11765        synchronized(this) {
11766            // Note that we don't execute any pending app switches... we will
11767            // let those wait until either the timeout, or the next start
11768            // activity request.
11769            mAppSwitchesAllowedTime = 0;
11770        }
11771    }
11772
11773    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11774            int callingPid, int callingUid, String name) {
11775        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11776            return true;
11777        }
11778
11779        int perm = checkComponentPermission(
11780                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11781                sourceUid, -1, true);
11782        if (perm == PackageManager.PERMISSION_GRANTED) {
11783            return true;
11784        }
11785
11786        // If the actual IPC caller is different from the logical source, then
11787        // also see if they are allowed to control app switches.
11788        if (callingUid != -1 && callingUid != sourceUid) {
11789            perm = checkComponentPermission(
11790                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11791                    callingUid, -1, true);
11792            if (perm == PackageManager.PERMISSION_GRANTED) {
11793                return true;
11794            }
11795        }
11796
11797        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11798        return false;
11799    }
11800
11801    public void setDebugApp(String packageName, boolean waitForDebugger,
11802            boolean persistent) {
11803        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11804                "setDebugApp()");
11805
11806        long ident = Binder.clearCallingIdentity();
11807        try {
11808            // Note that this is not really thread safe if there are multiple
11809            // callers into it at the same time, but that's not a situation we
11810            // care about.
11811            if (persistent) {
11812                final ContentResolver resolver = mContext.getContentResolver();
11813                Settings.Global.putString(
11814                    resolver, Settings.Global.DEBUG_APP,
11815                    packageName);
11816                Settings.Global.putInt(
11817                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11818                    waitForDebugger ? 1 : 0);
11819            }
11820
11821            synchronized (this) {
11822                if (!persistent) {
11823                    mOrigDebugApp = mDebugApp;
11824                    mOrigWaitForDebugger = mWaitForDebugger;
11825                }
11826                mDebugApp = packageName;
11827                mWaitForDebugger = waitForDebugger;
11828                mDebugTransient = !persistent;
11829                if (packageName != null) {
11830                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11831                            false, UserHandle.USER_ALL, "set debug app");
11832                }
11833            }
11834        } finally {
11835            Binder.restoreCallingIdentity(ident);
11836        }
11837    }
11838
11839    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11840        synchronized (this) {
11841            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11842            if (!isDebuggable) {
11843                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11844                    throw new SecurityException("Process not debuggable: " + app.packageName);
11845                }
11846            }
11847
11848            mTrackAllocationApp = processName;
11849        }
11850    }
11851
11852    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11853        synchronized (this) {
11854            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11855            if (!isDebuggable) {
11856                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11857                    throw new SecurityException("Process not debuggable: " + app.packageName);
11858                }
11859            }
11860            mProfileApp = processName;
11861            mProfileFile = profilerInfo.profileFile;
11862            if (mProfileFd != null) {
11863                try {
11864                    mProfileFd.close();
11865                } catch (IOException e) {
11866                }
11867                mProfileFd = null;
11868            }
11869            mProfileFd = profilerInfo.profileFd;
11870            mSamplingInterval = profilerInfo.samplingInterval;
11871            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11872            mProfileType = 0;
11873        }
11874    }
11875
11876    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11877        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11878        if (!isDebuggable) {
11879            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11880                throw new SecurityException("Process not debuggable: " + app.packageName);
11881            }
11882        }
11883        mNativeDebuggingApp = processName;
11884    }
11885
11886    @Override
11887    public void setAlwaysFinish(boolean enabled) {
11888        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11889                "setAlwaysFinish()");
11890
11891        long ident = Binder.clearCallingIdentity();
11892        try {
11893            Settings.Global.putInt(
11894                    mContext.getContentResolver(),
11895                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11896
11897            synchronized (this) {
11898                mAlwaysFinishActivities = enabled;
11899            }
11900        } finally {
11901            Binder.restoreCallingIdentity(ident);
11902        }
11903    }
11904
11905    @Override
11906    public void setLenientBackgroundCheck(boolean enabled) {
11907        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11908                "setLenientBackgroundCheck()");
11909
11910        long ident = Binder.clearCallingIdentity();
11911        try {
11912            Settings.Global.putInt(
11913                    mContext.getContentResolver(),
11914                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11915
11916            synchronized (this) {
11917                mLenientBackgroundCheck = enabled;
11918            }
11919        } finally {
11920            Binder.restoreCallingIdentity(ident);
11921        }
11922    }
11923
11924    @Override
11925    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11926        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11927                "setActivityController()");
11928        synchronized (this) {
11929            mController = controller;
11930            mControllerIsAMonkey = imAMonkey;
11931            Watchdog.getInstance().setActivityController(controller);
11932        }
11933    }
11934
11935    @Override
11936    public void setUserIsMonkey(boolean userIsMonkey) {
11937        synchronized (this) {
11938            synchronized (mPidsSelfLocked) {
11939                final int callingPid = Binder.getCallingPid();
11940                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11941                if (precessRecord == null) {
11942                    throw new SecurityException("Unknown process: " + callingPid);
11943                }
11944                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11945                    throw new SecurityException("Only an instrumentation process "
11946                            + "with a UiAutomation can call setUserIsMonkey");
11947                }
11948            }
11949            mUserIsMonkey = userIsMonkey;
11950        }
11951    }
11952
11953    @Override
11954    public boolean isUserAMonkey() {
11955        synchronized (this) {
11956            // If there is a controller also implies the user is a monkey.
11957            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11958        }
11959    }
11960
11961    public void requestBugReport(int bugreportType) {
11962        String service = null;
11963        switch (bugreportType) {
11964            case ActivityManager.BUGREPORT_OPTION_FULL:
11965                service = "bugreport";
11966                break;
11967            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11968                service = "bugreportplus";
11969                break;
11970            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11971                service = "bugreportremote";
11972                break;
11973        }
11974        if (service == null) {
11975            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11976                    + bugreportType);
11977        }
11978        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11979        SystemProperties.set("ctl.start", service);
11980    }
11981
11982    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11983        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11984    }
11985
11986    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11987        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11988            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11989        }
11990        return KEY_DISPATCHING_TIMEOUT;
11991    }
11992
11993    @Override
11994    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11995        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11996                != PackageManager.PERMISSION_GRANTED) {
11997            throw new SecurityException("Requires permission "
11998                    + android.Manifest.permission.FILTER_EVENTS);
11999        }
12000        ProcessRecord proc;
12001        long timeout;
12002        synchronized (this) {
12003            synchronized (mPidsSelfLocked) {
12004                proc = mPidsSelfLocked.get(pid);
12005            }
12006            timeout = getInputDispatchingTimeoutLocked(proc);
12007        }
12008
12009        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12010            return -1;
12011        }
12012
12013        return timeout;
12014    }
12015
12016    /**
12017     * Handle input dispatching timeouts.
12018     * Returns whether input dispatching should be aborted or not.
12019     */
12020    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12021            final ActivityRecord activity, final ActivityRecord parent,
12022            final boolean aboveSystem, String reason) {
12023        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12024                != PackageManager.PERMISSION_GRANTED) {
12025            throw new SecurityException("Requires permission "
12026                    + android.Manifest.permission.FILTER_EVENTS);
12027        }
12028
12029        final String annotation;
12030        if (reason == null) {
12031            annotation = "Input dispatching timed out";
12032        } else {
12033            annotation = "Input dispatching timed out (" + reason + ")";
12034        }
12035
12036        if (proc != null) {
12037            synchronized (this) {
12038                if (proc.debugging) {
12039                    return false;
12040                }
12041
12042                if (mDidDexOpt) {
12043                    // Give more time since we were dexopting.
12044                    mDidDexOpt = false;
12045                    return false;
12046                }
12047
12048                if (proc.instrumentationClass != null) {
12049                    Bundle info = new Bundle();
12050                    info.putString("shortMsg", "keyDispatchingTimedOut");
12051                    info.putString("longMsg", annotation);
12052                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12053                    return true;
12054                }
12055            }
12056            mHandler.post(new Runnable() {
12057                @Override
12058                public void run() {
12059                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12060                }
12061            });
12062        }
12063
12064        return true;
12065    }
12066
12067    @Override
12068    public Bundle getAssistContextExtras(int requestType) {
12069        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12070                null, null, true /* focused */, true /* newSessionId */,
12071                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12072        if (pae == null) {
12073            return null;
12074        }
12075        synchronized (pae) {
12076            while (!pae.haveResult) {
12077                try {
12078                    pae.wait();
12079                } catch (InterruptedException e) {
12080                }
12081            }
12082        }
12083        synchronized (this) {
12084            buildAssistBundleLocked(pae, pae.result);
12085            mPendingAssistExtras.remove(pae);
12086            mUiHandler.removeCallbacks(pae);
12087        }
12088        return pae.extras;
12089    }
12090
12091    @Override
12092    public boolean isAssistDataAllowedOnCurrentActivity() {
12093        int userId;
12094        synchronized (this) {
12095            userId = mUserController.getCurrentUserIdLocked();
12096            ActivityRecord activity = getFocusedStack().topActivity();
12097            if (activity == null) {
12098                return false;
12099            }
12100            userId = activity.userId;
12101        }
12102        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12103                Context.DEVICE_POLICY_SERVICE);
12104        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12105    }
12106
12107    @Override
12108    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12109        long ident = Binder.clearCallingIdentity();
12110        try {
12111            synchronized (this) {
12112                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12113                ActivityRecord top = getFocusedStack().topActivity();
12114                if (top != caller) {
12115                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12116                            + " is not current top " + top);
12117                    return false;
12118                }
12119                if (!top.nowVisible) {
12120                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12121                            + " is not visible");
12122                    return false;
12123                }
12124            }
12125            AssistUtils utils = new AssistUtils(mContext);
12126            return utils.showSessionForActiveService(args,
12127                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12128        } finally {
12129            Binder.restoreCallingIdentity(ident);
12130        }
12131    }
12132
12133    @Override
12134    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12135            Bundle receiverExtras,
12136            IBinder activityToken, boolean focused, boolean newSessionId) {
12137        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12138                activityToken, focused, newSessionId,
12139                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12140                != null;
12141    }
12142
12143    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12144            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12145            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12146        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12147                "enqueueAssistContext()");
12148        synchronized (this) {
12149            ActivityRecord activity = getFocusedStack().topActivity();
12150            if (activity == null) {
12151                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12152                return null;
12153            }
12154            if (activity.app == null || activity.app.thread == null) {
12155                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12156                return null;
12157            }
12158            if (focused) {
12159                if (activityToken != null) {
12160                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12161                    if (activity != caller) {
12162                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12163                                + " is not current top " + activity);
12164                        return null;
12165                    }
12166                }
12167            } else {
12168                activity = ActivityRecord.forTokenLocked(activityToken);
12169                if (activity == null) {
12170                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12171                            + " couldn't be found");
12172                    return null;
12173                }
12174            }
12175
12176            PendingAssistExtras pae;
12177            Bundle extras = new Bundle();
12178            if (args != null) {
12179                extras.putAll(args);
12180            }
12181            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12182            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12183            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12184                    userHandle);
12185            // Increment the sessionId if necessary
12186            if (newSessionId) {
12187                mViSessionId++;
12188            }
12189            try {
12190                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12191                        requestType, mViSessionId);
12192                mPendingAssistExtras.add(pae);
12193                mUiHandler.postDelayed(pae, timeout);
12194            } catch (RemoteException e) {
12195                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12196                return null;
12197            }
12198            return pae;
12199        }
12200    }
12201
12202    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12203        IResultReceiver receiver;
12204        synchronized (this) {
12205            mPendingAssistExtras.remove(pae);
12206            receiver = pae.receiver;
12207        }
12208        if (receiver != null) {
12209            // Caller wants result sent back to them.
12210            Bundle sendBundle = new Bundle();
12211            // At least return the receiver extras
12212            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12213                    pae.receiverExtras);
12214            try {
12215                pae.receiver.send(0, sendBundle);
12216            } catch (RemoteException e) {
12217            }
12218        }
12219    }
12220
12221    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12222        if (result != null) {
12223            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12224        }
12225        if (pae.hint != null) {
12226            pae.extras.putBoolean(pae.hint, true);
12227        }
12228    }
12229
12230    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12231            AssistContent content, Uri referrer) {
12232        PendingAssistExtras pae = (PendingAssistExtras)token;
12233        synchronized (pae) {
12234            pae.result = extras;
12235            pae.structure = structure;
12236            pae.content = content;
12237            if (referrer != null) {
12238                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12239            }
12240            pae.haveResult = true;
12241            pae.notifyAll();
12242            if (pae.intent == null && pae.receiver == null) {
12243                // Caller is just waiting for the result.
12244                return;
12245            }
12246        }
12247
12248        // We are now ready to launch the assist activity.
12249        IResultReceiver sendReceiver = null;
12250        Bundle sendBundle = null;
12251        synchronized (this) {
12252            buildAssistBundleLocked(pae, extras);
12253            boolean exists = mPendingAssistExtras.remove(pae);
12254            mUiHandler.removeCallbacks(pae);
12255            if (!exists) {
12256                // Timed out.
12257                return;
12258            }
12259            if ((sendReceiver=pae.receiver) != null) {
12260                // Caller wants result sent back to them.
12261                sendBundle = new Bundle();
12262                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12263                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12264                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12265                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12266                        pae.receiverExtras);
12267            }
12268        }
12269        if (sendReceiver != null) {
12270            try {
12271                sendReceiver.send(0, sendBundle);
12272            } catch (RemoteException e) {
12273            }
12274            return;
12275        }
12276
12277        long ident = Binder.clearCallingIdentity();
12278        try {
12279            pae.intent.replaceExtras(pae.extras);
12280            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12281                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12282                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12283            closeSystemDialogs("assist");
12284            try {
12285                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12286            } catch (ActivityNotFoundException e) {
12287                Slog.w(TAG, "No activity to handle assist action.", e);
12288            }
12289        } finally {
12290            Binder.restoreCallingIdentity(ident);
12291        }
12292    }
12293
12294    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12295            Bundle args) {
12296        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12297                true /* focused */, true /* newSessionId */,
12298                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12299    }
12300
12301    public void registerProcessObserver(IProcessObserver observer) {
12302        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12303                "registerProcessObserver()");
12304        synchronized (this) {
12305            mProcessObservers.register(observer);
12306        }
12307    }
12308
12309    @Override
12310    public void unregisterProcessObserver(IProcessObserver observer) {
12311        synchronized (this) {
12312            mProcessObservers.unregister(observer);
12313        }
12314    }
12315
12316    @Override
12317    public void registerUidObserver(IUidObserver observer, int which) {
12318        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12319                "registerUidObserver()");
12320        synchronized (this) {
12321            mUidObservers.register(observer, which);
12322        }
12323    }
12324
12325    @Override
12326    public void unregisterUidObserver(IUidObserver observer) {
12327        synchronized (this) {
12328            mUidObservers.unregister(observer);
12329        }
12330    }
12331
12332    @Override
12333    public boolean convertFromTranslucent(IBinder token) {
12334        final long origId = Binder.clearCallingIdentity();
12335        try {
12336            synchronized (this) {
12337                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12338                if (r == null) {
12339                    return false;
12340                }
12341                final boolean translucentChanged = r.changeWindowTranslucency(true);
12342                if (translucentChanged) {
12343                    r.task.stack.releaseBackgroundResources(r);
12344                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12345                }
12346                mWindowManager.setAppFullscreen(token, true);
12347                return translucentChanged;
12348            }
12349        } finally {
12350            Binder.restoreCallingIdentity(origId);
12351        }
12352    }
12353
12354    @Override
12355    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12356        final long origId = Binder.clearCallingIdentity();
12357        try {
12358            synchronized (this) {
12359                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12360                if (r == null) {
12361                    return false;
12362                }
12363                int index = r.task.mActivities.lastIndexOf(r);
12364                if (index > 0) {
12365                    ActivityRecord under = r.task.mActivities.get(index - 1);
12366                    under.returningOptions = options;
12367                }
12368                final boolean translucentChanged = r.changeWindowTranslucency(false);
12369                if (translucentChanged) {
12370                    r.task.stack.convertActivityToTranslucent(r);
12371                }
12372                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12373                mWindowManager.setAppFullscreen(token, false);
12374                return translucentChanged;
12375            }
12376        } finally {
12377            Binder.restoreCallingIdentity(origId);
12378        }
12379    }
12380
12381    @Override
12382    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12383        final long origId = Binder.clearCallingIdentity();
12384        try {
12385            synchronized (this) {
12386                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12387                if (r != null) {
12388                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12389                }
12390            }
12391            return false;
12392        } finally {
12393            Binder.restoreCallingIdentity(origId);
12394        }
12395    }
12396
12397    @Override
12398    public boolean isBackgroundVisibleBehind(IBinder token) {
12399        final long origId = Binder.clearCallingIdentity();
12400        try {
12401            synchronized (this) {
12402                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12403                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12404                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12405                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12406                return visible;
12407            }
12408        } finally {
12409            Binder.restoreCallingIdentity(origId);
12410        }
12411    }
12412
12413    @Override
12414    public ActivityOptions getActivityOptions(IBinder token) {
12415        final long origId = Binder.clearCallingIdentity();
12416        try {
12417            synchronized (this) {
12418                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12419                if (r != null) {
12420                    final ActivityOptions activityOptions = r.pendingOptions;
12421                    r.pendingOptions = null;
12422                    return activityOptions;
12423                }
12424                return null;
12425            }
12426        } finally {
12427            Binder.restoreCallingIdentity(origId);
12428        }
12429    }
12430
12431    @Override
12432    public void setImmersive(IBinder token, boolean immersive) {
12433        synchronized(this) {
12434            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12435            if (r == null) {
12436                throw new IllegalArgumentException();
12437            }
12438            r.immersive = immersive;
12439
12440            // update associated state if we're frontmost
12441            if (r == mFocusedActivity) {
12442                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12443                applyUpdateLockStateLocked(r);
12444            }
12445        }
12446    }
12447
12448    @Override
12449    public boolean isImmersive(IBinder token) {
12450        synchronized (this) {
12451            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12452            if (r == null) {
12453                throw new IllegalArgumentException();
12454            }
12455            return r.immersive;
12456        }
12457    }
12458
12459    @Override
12460    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12461        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12462            throw new UnsupportedOperationException("VR mode not supported on this device!");
12463        }
12464
12465        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12466
12467        ActivityRecord r;
12468        synchronized (this) {
12469            r = ActivityRecord.isInStackLocked(token);
12470        }
12471
12472        if (r == null) {
12473            throw new IllegalArgumentException();
12474        }
12475
12476        int err;
12477        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12478                VrManagerInternal.NO_ERROR) {
12479            return err;
12480        }
12481
12482        synchronized(this) {
12483            r.requestedVrComponent = (enabled) ? packageName : null;
12484
12485            // Update associated state if this activity is currently focused
12486            if (r == mFocusedActivity) {
12487                applyUpdateVrModeLocked(r);
12488            }
12489            return 0;
12490        }
12491    }
12492
12493    @Override
12494    public boolean isVrModePackageEnabled(ComponentName packageName) {
12495        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12496            throw new UnsupportedOperationException("VR mode not supported on this device!");
12497        }
12498
12499        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12500
12501        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12502                VrManagerInternal.NO_ERROR;
12503    }
12504
12505    public boolean isTopActivityImmersive() {
12506        enforceNotIsolatedCaller("startActivity");
12507        synchronized (this) {
12508            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12509            return (r != null) ? r.immersive : false;
12510        }
12511    }
12512
12513    @Override
12514    public boolean isTopOfTask(IBinder token) {
12515        synchronized (this) {
12516            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12517            if (r == null) {
12518                throw new IllegalArgumentException();
12519            }
12520            return r.task.getTopActivity() == r;
12521        }
12522    }
12523
12524    public final void enterSafeMode() {
12525        synchronized(this) {
12526            // It only makes sense to do this before the system is ready
12527            // and started launching other packages.
12528            if (!mSystemReady) {
12529                try {
12530                    AppGlobals.getPackageManager().enterSafeMode();
12531                } catch (RemoteException e) {
12532                }
12533            }
12534
12535            mSafeMode = true;
12536        }
12537    }
12538
12539    public final void showSafeModeOverlay() {
12540        View v = LayoutInflater.from(mContext).inflate(
12541                com.android.internal.R.layout.safe_mode, null);
12542        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12543        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12544        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12545        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12546        lp.gravity = Gravity.BOTTOM | Gravity.START;
12547        lp.format = v.getBackground().getOpacity();
12548        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12549                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12550        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12551        ((WindowManager)mContext.getSystemService(
12552                Context.WINDOW_SERVICE)).addView(v, lp);
12553    }
12554
12555    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12556        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12557            return;
12558        }
12559        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12560        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12561        synchronized (stats) {
12562            if (mBatteryStatsService.isOnBattery()) {
12563                mBatteryStatsService.enforceCallingPermission();
12564                int MY_UID = Binder.getCallingUid();
12565                final int uid;
12566                if (sender == null) {
12567                    uid = sourceUid;
12568                } else {
12569                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12570                }
12571                BatteryStatsImpl.Uid.Pkg pkg =
12572                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12573                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12574                pkg.noteWakeupAlarmLocked(tag);
12575            }
12576        }
12577    }
12578
12579    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12580        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12581            return;
12582        }
12583        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12584        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12585        synchronized (stats) {
12586            mBatteryStatsService.enforceCallingPermission();
12587            int MY_UID = Binder.getCallingUid();
12588            final int uid;
12589            if (sender == null) {
12590                uid = sourceUid;
12591            } else {
12592                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12593            }
12594            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12595        }
12596    }
12597
12598    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12599        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12600            return;
12601        }
12602        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12603        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12604        synchronized (stats) {
12605            mBatteryStatsService.enforceCallingPermission();
12606            int MY_UID = Binder.getCallingUid();
12607            final int uid;
12608            if (sender == null) {
12609                uid = sourceUid;
12610            } else {
12611                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12612            }
12613            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12614        }
12615    }
12616
12617    public boolean killPids(int[] pids, String pReason, boolean secure) {
12618        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12619            throw new SecurityException("killPids only available to the system");
12620        }
12621        String reason = (pReason == null) ? "Unknown" : pReason;
12622        // XXX Note: don't acquire main activity lock here, because the window
12623        // manager calls in with its locks held.
12624
12625        boolean killed = false;
12626        synchronized (mPidsSelfLocked) {
12627            int worstType = 0;
12628            for (int i=0; i<pids.length; i++) {
12629                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12630                if (proc != null) {
12631                    int type = proc.setAdj;
12632                    if (type > worstType) {
12633                        worstType = type;
12634                    }
12635                }
12636            }
12637
12638            // If the worst oom_adj is somewhere in the cached proc LRU range,
12639            // then constrain it so we will kill all cached procs.
12640            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12641                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12642                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12643            }
12644
12645            // If this is not a secure call, don't let it kill processes that
12646            // are important.
12647            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12648                worstType = ProcessList.SERVICE_ADJ;
12649            }
12650
12651            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12652            for (int i=0; i<pids.length; i++) {
12653                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12654                if (proc == null) {
12655                    continue;
12656                }
12657                int adj = proc.setAdj;
12658                if (adj >= worstType && !proc.killedByAm) {
12659                    proc.kill(reason, true);
12660                    killed = true;
12661                }
12662            }
12663        }
12664        return killed;
12665    }
12666
12667    @Override
12668    public void killUid(int appId, int userId, String reason) {
12669        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12670        synchronized (this) {
12671            final long identity = Binder.clearCallingIdentity();
12672            try {
12673                killPackageProcessesLocked(null, appId, userId,
12674                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12675                        reason != null ? reason : "kill uid");
12676            } finally {
12677                Binder.restoreCallingIdentity(identity);
12678            }
12679        }
12680    }
12681
12682    @Override
12683    public boolean killProcessesBelowForeground(String reason) {
12684        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12685            throw new SecurityException("killProcessesBelowForeground() only available to system");
12686        }
12687
12688        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12689    }
12690
12691    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12692        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12693            throw new SecurityException("killProcessesBelowAdj() only available to system");
12694        }
12695
12696        boolean killed = false;
12697        synchronized (mPidsSelfLocked) {
12698            final int size = mPidsSelfLocked.size();
12699            for (int i = 0; i < size; i++) {
12700                final int pid = mPidsSelfLocked.keyAt(i);
12701                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12702                if (proc == null) continue;
12703
12704                final int adj = proc.setAdj;
12705                if (adj > belowAdj && !proc.killedByAm) {
12706                    proc.kill(reason, true);
12707                    killed = true;
12708                }
12709            }
12710        }
12711        return killed;
12712    }
12713
12714    @Override
12715    public void hang(final IBinder who, boolean allowRestart) {
12716        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12717                != PackageManager.PERMISSION_GRANTED) {
12718            throw new SecurityException("Requires permission "
12719                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12720        }
12721
12722        final IBinder.DeathRecipient death = new DeathRecipient() {
12723            @Override
12724            public void binderDied() {
12725                synchronized (this) {
12726                    notifyAll();
12727                }
12728            }
12729        };
12730
12731        try {
12732            who.linkToDeath(death, 0);
12733        } catch (RemoteException e) {
12734            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12735            return;
12736        }
12737
12738        synchronized (this) {
12739            Watchdog.getInstance().setAllowRestart(allowRestart);
12740            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12741            synchronized (death) {
12742                while (who.isBinderAlive()) {
12743                    try {
12744                        death.wait();
12745                    } catch (InterruptedException e) {
12746                    }
12747                }
12748            }
12749            Watchdog.getInstance().setAllowRestart(true);
12750        }
12751    }
12752
12753    @Override
12754    public void restart() {
12755        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12756                != PackageManager.PERMISSION_GRANTED) {
12757            throw new SecurityException("Requires permission "
12758                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12759        }
12760
12761        Log.i(TAG, "Sending shutdown broadcast...");
12762
12763        BroadcastReceiver br = new BroadcastReceiver() {
12764            @Override public void onReceive(Context context, Intent intent) {
12765                // Now the broadcast is done, finish up the low-level shutdown.
12766                Log.i(TAG, "Shutting down activity manager...");
12767                shutdown(10000);
12768                Log.i(TAG, "Shutdown complete, restarting!");
12769                Process.killProcess(Process.myPid());
12770                System.exit(10);
12771            }
12772        };
12773
12774        // First send the high-level shut down broadcast.
12775        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12776        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12777        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12778        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12779        mContext.sendOrderedBroadcastAsUser(intent,
12780                UserHandle.ALL, null, br, mHandler, 0, null, null);
12781        */
12782        br.onReceive(mContext, intent);
12783    }
12784
12785    private long getLowRamTimeSinceIdle(long now) {
12786        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12787    }
12788
12789    @Override
12790    public void performIdleMaintenance() {
12791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12792                != PackageManager.PERMISSION_GRANTED) {
12793            throw new SecurityException("Requires permission "
12794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12795        }
12796
12797        synchronized (this) {
12798            final long now = SystemClock.uptimeMillis();
12799            final long timeSinceLastIdle = now - mLastIdleTime;
12800            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12801            mLastIdleTime = now;
12802            mLowRamTimeSinceLastIdle = 0;
12803            if (mLowRamStartTime != 0) {
12804                mLowRamStartTime = now;
12805            }
12806
12807            StringBuilder sb = new StringBuilder(128);
12808            sb.append("Idle maintenance over ");
12809            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12810            sb.append(" low RAM for ");
12811            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12812            Slog.i(TAG, sb.toString());
12813
12814            // If at least 1/3 of our time since the last idle period has been spent
12815            // with RAM low, then we want to kill processes.
12816            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12817
12818            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12819                ProcessRecord proc = mLruProcesses.get(i);
12820                if (proc.notCachedSinceIdle) {
12821                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12822                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12823                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12824                        if (doKilling && proc.initialIdlePss != 0
12825                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12826                            sb = new StringBuilder(128);
12827                            sb.append("Kill");
12828                            sb.append(proc.processName);
12829                            sb.append(" in idle maint: pss=");
12830                            sb.append(proc.lastPss);
12831                            sb.append(", swapPss=");
12832                            sb.append(proc.lastSwapPss);
12833                            sb.append(", initialPss=");
12834                            sb.append(proc.initialIdlePss);
12835                            sb.append(", period=");
12836                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12837                            sb.append(", lowRamPeriod=");
12838                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12839                            Slog.wtfQuiet(TAG, sb.toString());
12840                            proc.kill("idle maint (pss " + proc.lastPss
12841                                    + " from " + proc.initialIdlePss + ")", true);
12842                        }
12843                    }
12844                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12845                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12846                    proc.notCachedSinceIdle = true;
12847                    proc.initialIdlePss = 0;
12848                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12849                            mTestPssMode, isSleeping(), now);
12850                }
12851            }
12852
12853            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12854            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12855        }
12856    }
12857
12858    @Override
12859    public void sendIdleJobTrigger() {
12860        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12861                != PackageManager.PERMISSION_GRANTED) {
12862            throw new SecurityException("Requires permission "
12863                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12864        }
12865
12866        final long ident = Binder.clearCallingIdentity();
12867        try {
12868            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12869                    .setPackage("android")
12870                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12871            broadcastIntent(null, intent, null, null, 0, null, null, null,
12872                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12873        } finally {
12874            Binder.restoreCallingIdentity(ident);
12875        }
12876    }
12877
12878    private void retrieveSettings() {
12879        final ContentResolver resolver = mContext.getContentResolver();
12880        final boolean freeformWindowManagement =
12881                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12882                        || Settings.Global.getInt(
12883                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12884        final boolean supportsPictureInPicture =
12885                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12886
12887        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12888        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12889        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12890        final boolean alwaysFinishActivities =
12891                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12892        final boolean lenientBackgroundCheck =
12893                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12894        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12895        final boolean forceResizable = Settings.Global.getInt(
12896                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12897        final boolean supportsLeanbackOnly =
12898                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12899
12900        // Transfer any global setting for forcing RTL layout, into a System Property
12901        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12902
12903        final Configuration configuration = new Configuration();
12904        Settings.System.getConfiguration(resolver, configuration);
12905        if (forceRtl) {
12906            // This will take care of setting the correct layout direction flags
12907            configuration.setLayoutDirection(configuration.locale);
12908        }
12909
12910        synchronized (this) {
12911            mDebugApp = mOrigDebugApp = debugApp;
12912            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12913            mAlwaysFinishActivities = alwaysFinishActivities;
12914            mLenientBackgroundCheck = lenientBackgroundCheck;
12915            mSupportsLeanbackOnly = supportsLeanbackOnly;
12916            mForceResizableActivities = forceResizable;
12917            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12918            if (supportsMultiWindow || forceResizable) {
12919                mSupportsMultiWindow = true;
12920                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12921                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12922            } else {
12923                mSupportsMultiWindow = false;
12924                mSupportsFreeformWindowManagement = false;
12925                mSupportsPictureInPicture = false;
12926            }
12927            // This happens before any activities are started, so we can
12928            // change mConfiguration in-place.
12929            updateConfigurationLocked(configuration, null, true);
12930            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12931                    "Initial config: " + mConfiguration);
12932
12933            // Load resources only after the current configuration has been set.
12934            final Resources res = mContext.getResources();
12935            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12936            mThumbnailWidth = res.getDimensionPixelSize(
12937                    com.android.internal.R.dimen.thumbnail_width);
12938            mThumbnailHeight = res.getDimensionPixelSize(
12939                    com.android.internal.R.dimen.thumbnail_height);
12940            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12941                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12942            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12943                    com.android.internal.R.string.config_appsNotReportingCrashes));
12944            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12945                mFullscreenThumbnailScale = (float) res
12946                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12947                    (float) mConfiguration.screenWidthDp;
12948            } else {
12949                mFullscreenThumbnailScale = res.getFraction(
12950                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12951            }
12952        }
12953    }
12954
12955    public boolean testIsSystemReady() {
12956        // no need to synchronize(this) just to read & return the value
12957        return mSystemReady;
12958    }
12959
12960    public void systemReady(final Runnable goingCallback) {
12961        synchronized(this) {
12962            if (mSystemReady) {
12963                // If we're done calling all the receivers, run the next "boot phase" passed in
12964                // by the SystemServer
12965                if (goingCallback != null) {
12966                    goingCallback.run();
12967                }
12968                return;
12969            }
12970
12971            mLocalDeviceIdleController
12972                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12973
12974            // Make sure we have the current profile info, since it is needed for security checks.
12975            mUserController.onSystemReady();
12976            mRecentTasks.onSystemReadyLocked();
12977            mAppOpsService.systemReady();
12978            mSystemReady = true;
12979        }
12980
12981        ArrayList<ProcessRecord> procsToKill = null;
12982        synchronized(mPidsSelfLocked) {
12983            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12984                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12985                if (!isAllowedWhileBooting(proc.info)){
12986                    if (procsToKill == null) {
12987                        procsToKill = new ArrayList<ProcessRecord>();
12988                    }
12989                    procsToKill.add(proc);
12990                }
12991            }
12992        }
12993
12994        synchronized(this) {
12995            if (procsToKill != null) {
12996                for (int i=procsToKill.size()-1; i>=0; i--) {
12997                    ProcessRecord proc = procsToKill.get(i);
12998                    Slog.i(TAG, "Removing system update proc: " + proc);
12999                    removeProcessLocked(proc, true, false, "system update done");
13000                }
13001            }
13002
13003            // Now that we have cleaned up any update processes, we
13004            // are ready to start launching real processes and know that
13005            // we won't trample on them any more.
13006            mProcessesReady = true;
13007        }
13008
13009        Slog.i(TAG, "System now ready");
13010        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13011            SystemClock.uptimeMillis());
13012
13013        synchronized(this) {
13014            // Make sure we have no pre-ready processes sitting around.
13015
13016            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13017                ResolveInfo ri = mContext.getPackageManager()
13018                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13019                                STOCK_PM_FLAGS);
13020                CharSequence errorMsg = null;
13021                if (ri != null) {
13022                    ActivityInfo ai = ri.activityInfo;
13023                    ApplicationInfo app = ai.applicationInfo;
13024                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13025                        mTopAction = Intent.ACTION_FACTORY_TEST;
13026                        mTopData = null;
13027                        mTopComponent = new ComponentName(app.packageName,
13028                                ai.name);
13029                    } else {
13030                        errorMsg = mContext.getResources().getText(
13031                                com.android.internal.R.string.factorytest_not_system);
13032                    }
13033                } else {
13034                    errorMsg = mContext.getResources().getText(
13035                            com.android.internal.R.string.factorytest_no_action);
13036                }
13037                if (errorMsg != null) {
13038                    mTopAction = null;
13039                    mTopData = null;
13040                    mTopComponent = null;
13041                    Message msg = Message.obtain();
13042                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13043                    msg.getData().putCharSequence("msg", errorMsg);
13044                    mUiHandler.sendMessage(msg);
13045                }
13046            }
13047        }
13048
13049        retrieveSettings();
13050        final int currentUserId;
13051        synchronized (this) {
13052            currentUserId = mUserController.getCurrentUserIdLocked();
13053            readGrantedUriPermissionsLocked();
13054        }
13055
13056        if (goingCallback != null) goingCallback.run();
13057
13058        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13059                Integer.toString(currentUserId), currentUserId);
13060        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13061                Integer.toString(currentUserId), currentUserId);
13062        mSystemServiceManager.startUser(currentUserId);
13063
13064        synchronized (this) {
13065            // Only start up encryption-aware persistent apps; once user is
13066            // unlocked we'll come back around and start unaware apps
13067            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13068
13069            // Start up initial activity.
13070            mBooting = true;
13071            // Enable home activity for system user, so that the system can always boot
13072            if (UserManager.isSplitSystemUser()) {
13073                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13074                try {
13075                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13076                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13077                            UserHandle.USER_SYSTEM);
13078                } catch (RemoteException e) {
13079                    throw e.rethrowAsRuntimeException();
13080                }
13081            }
13082            startHomeActivityLocked(currentUserId, "systemReady");
13083
13084            try {
13085                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13086                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13087                            + " data partition or your device will be unstable.");
13088                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13089                }
13090            } catch (RemoteException e) {
13091            }
13092
13093            if (!Build.isBuildConsistent()) {
13094                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13095                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13096            }
13097
13098            long ident = Binder.clearCallingIdentity();
13099            try {
13100                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13101                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13102                        | Intent.FLAG_RECEIVER_FOREGROUND);
13103                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13104                broadcastIntentLocked(null, null, intent,
13105                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13106                        null, false, false, MY_PID, Process.SYSTEM_UID,
13107                        currentUserId);
13108                intent = new Intent(Intent.ACTION_USER_STARTING);
13109                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13110                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13111                broadcastIntentLocked(null, null, intent,
13112                        null, new IIntentReceiver.Stub() {
13113                            @Override
13114                            public void performReceive(Intent intent, int resultCode, String data,
13115                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13116                                    throws RemoteException {
13117                            }
13118                        }, 0, null, null,
13119                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13120                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13121            } catch (Throwable t) {
13122                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13123            } finally {
13124                Binder.restoreCallingIdentity(ident);
13125            }
13126            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13127            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13128        }
13129    }
13130
13131    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13132        synchronized (this) {
13133            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13134        }
13135    }
13136
13137    void skipCurrentReceiverLocked(ProcessRecord app) {
13138        for (BroadcastQueue queue : mBroadcastQueues) {
13139            queue.skipCurrentReceiverLocked(app);
13140        }
13141    }
13142
13143    /**
13144     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13145     * The application process will exit immediately after this call returns.
13146     * @param app object of the crashing app, null for the system server
13147     * @param crashInfo describing the exception
13148     */
13149    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13150        ProcessRecord r = findAppProcess(app, "Crash");
13151        final String processName = app == null ? "system_server"
13152                : (r == null ? "unknown" : r.processName);
13153
13154        handleApplicationCrashInner("crash", r, processName, crashInfo);
13155    }
13156
13157    /* Native crash reporting uses this inner version because it needs to be somewhat
13158     * decoupled from the AM-managed cleanup lifecycle
13159     */
13160    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13161            ApplicationErrorReport.CrashInfo crashInfo) {
13162        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13163                UserHandle.getUserId(Binder.getCallingUid()), processName,
13164                r == null ? -1 : r.info.flags,
13165                crashInfo.exceptionClassName,
13166                crashInfo.exceptionMessage,
13167                crashInfo.throwFileName,
13168                crashInfo.throwLineNumber);
13169
13170        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13171
13172        mAppErrors.crashApplication(r, crashInfo);
13173    }
13174
13175    public void handleApplicationStrictModeViolation(
13176            IBinder app,
13177            int violationMask,
13178            StrictMode.ViolationInfo info) {
13179        ProcessRecord r = findAppProcess(app, "StrictMode");
13180        if (r == null) {
13181            return;
13182        }
13183
13184        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13185            Integer stackFingerprint = info.hashCode();
13186            boolean logIt = true;
13187            synchronized (mAlreadyLoggedViolatedStacks) {
13188                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13189                    logIt = false;
13190                    // TODO: sub-sample into EventLog for these, with
13191                    // the info.durationMillis?  Then we'd get
13192                    // the relative pain numbers, without logging all
13193                    // the stack traces repeatedly.  We'd want to do
13194                    // likewise in the client code, which also does
13195                    // dup suppression, before the Binder call.
13196                } else {
13197                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13198                        mAlreadyLoggedViolatedStacks.clear();
13199                    }
13200                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13201                }
13202            }
13203            if (logIt) {
13204                logStrictModeViolationToDropBox(r, info);
13205            }
13206        }
13207
13208        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13209            AppErrorResult result = new AppErrorResult();
13210            synchronized (this) {
13211                final long origId = Binder.clearCallingIdentity();
13212
13213                Message msg = Message.obtain();
13214                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13215                HashMap<String, Object> data = new HashMap<String, Object>();
13216                data.put("result", result);
13217                data.put("app", r);
13218                data.put("violationMask", violationMask);
13219                data.put("info", info);
13220                msg.obj = data;
13221                mUiHandler.sendMessage(msg);
13222
13223                Binder.restoreCallingIdentity(origId);
13224            }
13225            int res = result.get();
13226            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13227        }
13228    }
13229
13230    // Depending on the policy in effect, there could be a bunch of
13231    // these in quick succession so we try to batch these together to
13232    // minimize disk writes, number of dropbox entries, and maximize
13233    // compression, by having more fewer, larger records.
13234    private void logStrictModeViolationToDropBox(
13235            ProcessRecord process,
13236            StrictMode.ViolationInfo info) {
13237        if (info == null) {
13238            return;
13239        }
13240        final boolean isSystemApp = process == null ||
13241                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13242                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13243        final String processName = process == null ? "unknown" : process.processName;
13244        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13245        final DropBoxManager dbox = (DropBoxManager)
13246                mContext.getSystemService(Context.DROPBOX_SERVICE);
13247
13248        // Exit early if the dropbox isn't configured to accept this report type.
13249        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13250
13251        boolean bufferWasEmpty;
13252        boolean needsFlush;
13253        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13254        synchronized (sb) {
13255            bufferWasEmpty = sb.length() == 0;
13256            appendDropBoxProcessHeaders(process, processName, sb);
13257            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13258            sb.append("System-App: ").append(isSystemApp).append("\n");
13259            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13260            if (info.violationNumThisLoop != 0) {
13261                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13262            }
13263            if (info.numAnimationsRunning != 0) {
13264                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13265            }
13266            if (info.broadcastIntentAction != null) {
13267                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13268            }
13269            if (info.durationMillis != -1) {
13270                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13271            }
13272            if (info.numInstances != -1) {
13273                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13274            }
13275            if (info.tags != null) {
13276                for (String tag : info.tags) {
13277                    sb.append("Span-Tag: ").append(tag).append("\n");
13278                }
13279            }
13280            sb.append("\n");
13281            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13282                sb.append(info.crashInfo.stackTrace);
13283                sb.append("\n");
13284            }
13285            if (info.message != null) {
13286                sb.append(info.message);
13287                sb.append("\n");
13288            }
13289
13290            // Only buffer up to ~64k.  Various logging bits truncate
13291            // things at 128k.
13292            needsFlush = (sb.length() > 64 * 1024);
13293        }
13294
13295        // Flush immediately if the buffer's grown too large, or this
13296        // is a non-system app.  Non-system apps are isolated with a
13297        // different tag & policy and not batched.
13298        //
13299        // Batching is useful during internal testing with
13300        // StrictMode settings turned up high.  Without batching,
13301        // thousands of separate files could be created on boot.
13302        if (!isSystemApp || needsFlush) {
13303            new Thread("Error dump: " + dropboxTag) {
13304                @Override
13305                public void run() {
13306                    String report;
13307                    synchronized (sb) {
13308                        report = sb.toString();
13309                        sb.delete(0, sb.length());
13310                        sb.trimToSize();
13311                    }
13312                    if (report.length() != 0) {
13313                        dbox.addText(dropboxTag, report);
13314                    }
13315                }
13316            }.start();
13317            return;
13318        }
13319
13320        // System app batching:
13321        if (!bufferWasEmpty) {
13322            // An existing dropbox-writing thread is outstanding, so
13323            // we don't need to start it up.  The existing thread will
13324            // catch the buffer appends we just did.
13325            return;
13326        }
13327
13328        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13329        // (After this point, we shouldn't access AMS internal data structures.)
13330        new Thread("Error dump: " + dropboxTag) {
13331            @Override
13332            public void run() {
13333                // 5 second sleep to let stacks arrive and be batched together
13334                try {
13335                    Thread.sleep(5000);  // 5 seconds
13336                } catch (InterruptedException e) {}
13337
13338                String errorReport;
13339                synchronized (mStrictModeBuffer) {
13340                    errorReport = mStrictModeBuffer.toString();
13341                    if (errorReport.length() == 0) {
13342                        return;
13343                    }
13344                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13345                    mStrictModeBuffer.trimToSize();
13346                }
13347                dbox.addText(dropboxTag, errorReport);
13348            }
13349        }.start();
13350    }
13351
13352    /**
13353     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13354     * @param app object of the crashing app, null for the system server
13355     * @param tag reported by the caller
13356     * @param system whether this wtf is coming from the system
13357     * @param crashInfo describing the context of the error
13358     * @return true if the process should exit immediately (WTF is fatal)
13359     */
13360    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13361            final ApplicationErrorReport.CrashInfo crashInfo) {
13362        final int callingUid = Binder.getCallingUid();
13363        final int callingPid = Binder.getCallingPid();
13364
13365        if (system) {
13366            // If this is coming from the system, we could very well have low-level
13367            // system locks held, so we want to do this all asynchronously.  And we
13368            // never want this to become fatal, so there is that too.
13369            mHandler.post(new Runnable() {
13370                @Override public void run() {
13371                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13372                }
13373            });
13374            return false;
13375        }
13376
13377        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13378                crashInfo);
13379
13380        if (r != null && r.pid != Process.myPid() &&
13381                Settings.Global.getInt(mContext.getContentResolver(),
13382                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13383            mAppErrors.crashApplication(r, crashInfo);
13384            return true;
13385        } else {
13386            return false;
13387        }
13388    }
13389
13390    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13391            final ApplicationErrorReport.CrashInfo crashInfo) {
13392        final ProcessRecord r = findAppProcess(app, "WTF");
13393        final String processName = app == null ? "system_server"
13394                : (r == null ? "unknown" : r.processName);
13395
13396        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13397                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13398
13399        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13400
13401        return r;
13402    }
13403
13404    /**
13405     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13406     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13407     */
13408    private ProcessRecord findAppProcess(IBinder app, String reason) {
13409        if (app == null) {
13410            return null;
13411        }
13412
13413        synchronized (this) {
13414            final int NP = mProcessNames.getMap().size();
13415            for (int ip=0; ip<NP; ip++) {
13416                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13417                final int NA = apps.size();
13418                for (int ia=0; ia<NA; ia++) {
13419                    ProcessRecord p = apps.valueAt(ia);
13420                    if (p.thread != null && p.thread.asBinder() == app) {
13421                        return p;
13422                    }
13423                }
13424            }
13425
13426            Slog.w(TAG, "Can't find mystery application for " + reason
13427                    + " from pid=" + Binder.getCallingPid()
13428                    + " uid=" + Binder.getCallingUid() + ": " + app);
13429            return null;
13430        }
13431    }
13432
13433    /**
13434     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13435     * to append various headers to the dropbox log text.
13436     */
13437    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13438            StringBuilder sb) {
13439        // Watchdog thread ends up invoking this function (with
13440        // a null ProcessRecord) to add the stack file to dropbox.
13441        // Do not acquire a lock on this (am) in such cases, as it
13442        // could cause a potential deadlock, if and when watchdog
13443        // is invoked due to unavailability of lock on am and it
13444        // would prevent watchdog from killing system_server.
13445        if (process == null) {
13446            sb.append("Process: ").append(processName).append("\n");
13447            return;
13448        }
13449        // Note: ProcessRecord 'process' is guarded by the service
13450        // instance.  (notably process.pkgList, which could otherwise change
13451        // concurrently during execution of this method)
13452        synchronized (this) {
13453            sb.append("Process: ").append(processName).append("\n");
13454            int flags = process.info.flags;
13455            IPackageManager pm = AppGlobals.getPackageManager();
13456            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13457            for (int ip=0; ip<process.pkgList.size(); ip++) {
13458                String pkg = process.pkgList.keyAt(ip);
13459                sb.append("Package: ").append(pkg);
13460                try {
13461                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13462                    if (pi != null) {
13463                        sb.append(" v").append(pi.versionCode);
13464                        if (pi.versionName != null) {
13465                            sb.append(" (").append(pi.versionName).append(")");
13466                        }
13467                    }
13468                } catch (RemoteException e) {
13469                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13470                }
13471                sb.append("\n");
13472            }
13473        }
13474    }
13475
13476    private static String processClass(ProcessRecord process) {
13477        if (process == null || process.pid == MY_PID) {
13478            return "system_server";
13479        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13480            return "system_app";
13481        } else {
13482            return "data_app";
13483        }
13484    }
13485
13486    private volatile long mWtfClusterStart;
13487    private volatile int mWtfClusterCount;
13488
13489    /**
13490     * Write a description of an error (crash, WTF, ANR) to the drop box.
13491     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13492     * @param process which caused the error, null means the system server
13493     * @param activity which triggered the error, null if unknown
13494     * @param parent activity related to the error, null if unknown
13495     * @param subject line related to the error, null if absent
13496     * @param report in long form describing the error, null if absent
13497     * @param logFile to include in the report, null if none
13498     * @param crashInfo giving an application stack trace, null if absent
13499     */
13500    public void addErrorToDropBox(String eventType,
13501            ProcessRecord process, String processName, ActivityRecord activity,
13502            ActivityRecord parent, String subject,
13503            final String report, final File logFile,
13504            final ApplicationErrorReport.CrashInfo crashInfo) {
13505        // NOTE -- this must never acquire the ActivityManagerService lock,
13506        // otherwise the watchdog may be prevented from resetting the system.
13507
13508        final String dropboxTag = processClass(process) + "_" + eventType;
13509        final DropBoxManager dbox = (DropBoxManager)
13510                mContext.getSystemService(Context.DROPBOX_SERVICE);
13511
13512        // Exit early if the dropbox isn't configured to accept this report type.
13513        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13514
13515        // Rate-limit how often we're willing to do the heavy lifting below to
13516        // collect and record logs; currently 5 logs per 10 second period.
13517        final long now = SystemClock.elapsedRealtime();
13518        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13519            mWtfClusterStart = now;
13520            mWtfClusterCount = 1;
13521        } else {
13522            if (mWtfClusterCount++ >= 5) return;
13523        }
13524
13525        final StringBuilder sb = new StringBuilder(1024);
13526        appendDropBoxProcessHeaders(process, processName, sb);
13527        if (process != null) {
13528            sb.append("Foreground: ")
13529                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13530                    .append("\n");
13531        }
13532        if (activity != null) {
13533            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13534        }
13535        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13536            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13537        }
13538        if (parent != null && parent != activity) {
13539            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13540        }
13541        if (subject != null) {
13542            sb.append("Subject: ").append(subject).append("\n");
13543        }
13544        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13545        if (Debug.isDebuggerConnected()) {
13546            sb.append("Debugger: Connected\n");
13547        }
13548        sb.append("\n");
13549
13550        // Do the rest in a worker thread to avoid blocking the caller on I/O
13551        // (After this point, we shouldn't access AMS internal data structures.)
13552        Thread worker = new Thread("Error dump: " + dropboxTag) {
13553            @Override
13554            public void run() {
13555                if (report != null) {
13556                    sb.append(report);
13557                }
13558                if (logFile != null) {
13559                    try {
13560                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13561                                    "\n\n[[TRUNCATED]]"));
13562                    } catch (IOException e) {
13563                        Slog.e(TAG, "Error reading " + logFile, e);
13564                    }
13565                }
13566                if (crashInfo != null && crashInfo.stackTrace != null) {
13567                    sb.append(crashInfo.stackTrace);
13568                }
13569
13570                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13571                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13572                if (lines > 0) {
13573                    sb.append("\n");
13574
13575                    // Merge several logcat streams, and take the last N lines
13576                    InputStreamReader input = null;
13577                    try {
13578                        java.lang.Process logcat = new ProcessBuilder(
13579                                "/system/bin/timeout", "-k", "15s", "10s",
13580                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13581                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13582                                        .redirectErrorStream(true).start();
13583
13584                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13585                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13586                        input = new InputStreamReader(logcat.getInputStream());
13587
13588                        int num;
13589                        char[] buf = new char[8192];
13590                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13591                    } catch (IOException e) {
13592                        Slog.e(TAG, "Error running logcat", e);
13593                    } finally {
13594                        if (input != null) try { input.close(); } catch (IOException e) {}
13595                    }
13596                }
13597
13598                dbox.addText(dropboxTag, sb.toString());
13599            }
13600        };
13601
13602        if (process == null) {
13603            // If process is null, we are being called from some internal code
13604            // and may be about to die -- run this synchronously.
13605            worker.run();
13606        } else {
13607            worker.start();
13608        }
13609    }
13610
13611    @Override
13612    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13613        enforceNotIsolatedCaller("getProcessesInErrorState");
13614        // assume our apps are happy - lazy create the list
13615        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13616
13617        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13618                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13619        int userId = UserHandle.getUserId(Binder.getCallingUid());
13620
13621        synchronized (this) {
13622
13623            // iterate across all processes
13624            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13625                ProcessRecord app = mLruProcesses.get(i);
13626                if (!allUsers && app.userId != userId) {
13627                    continue;
13628                }
13629                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13630                    // This one's in trouble, so we'll generate a report for it
13631                    // crashes are higher priority (in case there's a crash *and* an anr)
13632                    ActivityManager.ProcessErrorStateInfo report = null;
13633                    if (app.crashing) {
13634                        report = app.crashingReport;
13635                    } else if (app.notResponding) {
13636                        report = app.notRespondingReport;
13637                    }
13638
13639                    if (report != null) {
13640                        if (errList == null) {
13641                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13642                        }
13643                        errList.add(report);
13644                    } else {
13645                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13646                                " crashing = " + app.crashing +
13647                                " notResponding = " + app.notResponding);
13648                    }
13649                }
13650            }
13651        }
13652
13653        return errList;
13654    }
13655
13656    static int procStateToImportance(int procState, int memAdj,
13657            ActivityManager.RunningAppProcessInfo currApp) {
13658        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13659        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13660            currApp.lru = memAdj;
13661        } else {
13662            currApp.lru = 0;
13663        }
13664        return imp;
13665    }
13666
13667    private void fillInProcMemInfo(ProcessRecord app,
13668            ActivityManager.RunningAppProcessInfo outInfo) {
13669        outInfo.pid = app.pid;
13670        outInfo.uid = app.info.uid;
13671        if (mHeavyWeightProcess == app) {
13672            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13673        }
13674        if (app.persistent) {
13675            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13676        }
13677        if (app.activities.size() > 0) {
13678            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13679        }
13680        outInfo.lastTrimLevel = app.trimMemoryLevel;
13681        int adj = app.curAdj;
13682        int procState = app.curProcState;
13683        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13684        outInfo.importanceReasonCode = app.adjTypeCode;
13685        outInfo.processState = app.curProcState;
13686    }
13687
13688    @Override
13689    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13690        enforceNotIsolatedCaller("getRunningAppProcesses");
13691
13692        final int callingUid = Binder.getCallingUid();
13693
13694        // Lazy instantiation of list
13695        List<ActivityManager.RunningAppProcessInfo> runList = null;
13696        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13697                callingUid) == PackageManager.PERMISSION_GRANTED;
13698        final int userId = UserHandle.getUserId(callingUid);
13699        final boolean allUids = isGetTasksAllowed(
13700                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13701
13702        synchronized (this) {
13703            // Iterate across all processes
13704            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13705                ProcessRecord app = mLruProcesses.get(i);
13706                if ((!allUsers && app.userId != userId)
13707                        || (!allUids && app.uid != callingUid)) {
13708                    continue;
13709                }
13710                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13711                    // Generate process state info for running application
13712                    ActivityManager.RunningAppProcessInfo currApp =
13713                        new ActivityManager.RunningAppProcessInfo(app.processName,
13714                                app.pid, app.getPackageList());
13715                    fillInProcMemInfo(app, currApp);
13716                    if (app.adjSource instanceof ProcessRecord) {
13717                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13718                        currApp.importanceReasonImportance =
13719                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13720                                        app.adjSourceProcState);
13721                    } else if (app.adjSource instanceof ActivityRecord) {
13722                        ActivityRecord r = (ActivityRecord)app.adjSource;
13723                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13724                    }
13725                    if (app.adjTarget instanceof ComponentName) {
13726                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13727                    }
13728                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13729                    //        + " lru=" + currApp.lru);
13730                    if (runList == null) {
13731                        runList = new ArrayList<>();
13732                    }
13733                    runList.add(currApp);
13734                }
13735            }
13736        }
13737        return runList;
13738    }
13739
13740    @Override
13741    public List<ApplicationInfo> getRunningExternalApplications() {
13742        enforceNotIsolatedCaller("getRunningExternalApplications");
13743        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13744        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13745        if (runningApps != null && runningApps.size() > 0) {
13746            Set<String> extList = new HashSet<String>();
13747            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13748                if (app.pkgList != null) {
13749                    for (String pkg : app.pkgList) {
13750                        extList.add(pkg);
13751                    }
13752                }
13753            }
13754            IPackageManager pm = AppGlobals.getPackageManager();
13755            for (String pkg : extList) {
13756                try {
13757                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13758                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13759                        retList.add(info);
13760                    }
13761                } catch (RemoteException e) {
13762                }
13763            }
13764        }
13765        return retList;
13766    }
13767
13768    @Override
13769    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13770        enforceNotIsolatedCaller("getMyMemoryState");
13771        synchronized (this) {
13772            ProcessRecord proc;
13773            synchronized (mPidsSelfLocked) {
13774                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13775            }
13776            fillInProcMemInfo(proc, outInfo);
13777        }
13778    }
13779
13780    @Override
13781    public int getMemoryTrimLevel() {
13782        enforceNotIsolatedCaller("getMyMemoryState");
13783        synchronized (this) {
13784            return mLastMemoryLevel;
13785        }
13786    }
13787
13788    @Override
13789    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13790            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13791        (new ActivityManagerShellCommand(this, false)).exec(
13792                this, in, out, err, args, resultReceiver);
13793    }
13794
13795    @Override
13796    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13797        if (checkCallingPermission(android.Manifest.permission.DUMP)
13798                != PackageManager.PERMISSION_GRANTED) {
13799            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13800                    + Binder.getCallingPid()
13801                    + ", uid=" + Binder.getCallingUid()
13802                    + " without permission "
13803                    + android.Manifest.permission.DUMP);
13804            return;
13805        }
13806
13807        boolean dumpAll = false;
13808        boolean dumpClient = false;
13809        boolean dumpCheckin = false;
13810        boolean dumpCheckinFormat = false;
13811        String dumpPackage = null;
13812
13813        int opti = 0;
13814        while (opti < args.length) {
13815            String opt = args[opti];
13816            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13817                break;
13818            }
13819            opti++;
13820            if ("-a".equals(opt)) {
13821                dumpAll = true;
13822            } else if ("-c".equals(opt)) {
13823                dumpClient = true;
13824            } else if ("-p".equals(opt)) {
13825                if (opti < args.length) {
13826                    dumpPackage = args[opti];
13827                    opti++;
13828                } else {
13829                    pw.println("Error: -p option requires package argument");
13830                    return;
13831                }
13832                dumpClient = true;
13833            } else if ("--checkin".equals(opt)) {
13834                dumpCheckin = dumpCheckinFormat = true;
13835            } else if ("-C".equals(opt)) {
13836                dumpCheckinFormat = true;
13837            } else if ("-h".equals(opt)) {
13838                ActivityManagerShellCommand.dumpHelp(pw, true);
13839                return;
13840            } else {
13841                pw.println("Unknown argument: " + opt + "; use -h for help");
13842            }
13843        }
13844
13845        long origId = Binder.clearCallingIdentity();
13846        boolean more = false;
13847        // Is the caller requesting to dump a particular piece of data?
13848        if (opti < args.length) {
13849            String cmd = args[opti];
13850            opti++;
13851            if ("activities".equals(cmd) || "a".equals(cmd)) {
13852                synchronized (this) {
13853                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13854                }
13855            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13856                synchronized (this) {
13857                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13858                }
13859            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13860                String[] newArgs;
13861                String name;
13862                if (opti >= args.length) {
13863                    name = null;
13864                    newArgs = EMPTY_STRING_ARRAY;
13865                } else {
13866                    dumpPackage = args[opti];
13867                    opti++;
13868                    newArgs = new String[args.length - opti];
13869                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13870                            args.length - opti);
13871                }
13872                synchronized (this) {
13873                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13874                }
13875            } else if ("broadcast-stats".equals(cmd)) {
13876                String[] newArgs;
13877                String name;
13878                if (opti >= args.length) {
13879                    name = null;
13880                    newArgs = EMPTY_STRING_ARRAY;
13881                } else {
13882                    dumpPackage = args[opti];
13883                    opti++;
13884                    newArgs = new String[args.length - opti];
13885                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13886                            args.length - opti);
13887                }
13888                synchronized (this) {
13889                    if (dumpCheckinFormat) {
13890                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13891                                dumpPackage);
13892                    } else {
13893                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13894                    }
13895                }
13896            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13897                String[] newArgs;
13898                String name;
13899                if (opti >= args.length) {
13900                    name = null;
13901                    newArgs = EMPTY_STRING_ARRAY;
13902                } else {
13903                    dumpPackage = args[opti];
13904                    opti++;
13905                    newArgs = new String[args.length - opti];
13906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13907                            args.length - opti);
13908                }
13909                synchronized (this) {
13910                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13911                }
13912            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13913                String[] newArgs;
13914                String name;
13915                if (opti >= args.length) {
13916                    name = null;
13917                    newArgs = EMPTY_STRING_ARRAY;
13918                } else {
13919                    dumpPackage = args[opti];
13920                    opti++;
13921                    newArgs = new String[args.length - opti];
13922                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13923                            args.length - opti);
13924                }
13925                synchronized (this) {
13926                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13927                }
13928            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13929                synchronized (this) {
13930                    dumpOomLocked(fd, pw, args, opti, true);
13931                }
13932            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13933                synchronized (this) {
13934                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13935                }
13936            } else if ("provider".equals(cmd)) {
13937                String[] newArgs;
13938                String name;
13939                if (opti >= args.length) {
13940                    name = null;
13941                    newArgs = EMPTY_STRING_ARRAY;
13942                } else {
13943                    name = args[opti];
13944                    opti++;
13945                    newArgs = new String[args.length - opti];
13946                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13947                }
13948                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13949                    pw.println("No providers match: " + name);
13950                    pw.println("Use -h for help.");
13951                }
13952            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13953                synchronized (this) {
13954                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13955                }
13956            } else if ("service".equals(cmd)) {
13957                String[] newArgs;
13958                String name;
13959                if (opti >= args.length) {
13960                    name = null;
13961                    newArgs = EMPTY_STRING_ARRAY;
13962                } else {
13963                    name = args[opti];
13964                    opti++;
13965                    newArgs = new String[args.length - opti];
13966                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13967                            args.length - opti);
13968                }
13969                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13970                    pw.println("No services match: " + name);
13971                    pw.println("Use -h for help.");
13972                }
13973            } else if ("package".equals(cmd)) {
13974                String[] newArgs;
13975                if (opti >= args.length) {
13976                    pw.println("package: no package name specified");
13977                    pw.println("Use -h for help.");
13978                } else {
13979                    dumpPackage = args[opti];
13980                    opti++;
13981                    newArgs = new String[args.length - opti];
13982                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13983                            args.length - opti);
13984                    args = newArgs;
13985                    opti = 0;
13986                    more = true;
13987                }
13988            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13989                synchronized (this) {
13990                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13991                }
13992            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13993                if (dumpClient) {
13994                    ActiveServices.ServiceDumper dumper;
13995                    synchronized (this) {
13996                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13997                                dumpPackage);
13998                    }
13999                    dumper.dumpWithClient();
14000                } else {
14001                    synchronized (this) {
14002                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14003                                dumpPackage).dumpLocked();
14004                    }
14005                }
14006            } else if ("locks".equals(cmd)) {
14007                LockGuard.dump(fd, pw, args);
14008            } else {
14009                // Dumping a single activity?
14010                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14011                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14012                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14013                    if (res < 0) {
14014                        pw.println("Bad activity command, or no activities match: " + cmd);
14015                        pw.println("Use -h for help.");
14016                    }
14017                }
14018            }
14019            if (!more) {
14020                Binder.restoreCallingIdentity(origId);
14021                return;
14022            }
14023        }
14024
14025        // No piece of data specified, dump everything.
14026        if (dumpCheckinFormat) {
14027            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14028        } else if (dumpClient) {
14029            ActiveServices.ServiceDumper sdumper;
14030            synchronized (this) {
14031                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14032                pw.println();
14033                if (dumpAll) {
14034                    pw.println("-------------------------------------------------------------------------------");
14035                }
14036                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14037                pw.println();
14038                if (dumpAll) {
14039                    pw.println("-------------------------------------------------------------------------------");
14040                }
14041                if (dumpAll || dumpPackage != null) {
14042                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14043                    pw.println();
14044                    if (dumpAll) {
14045                        pw.println("-------------------------------------------------------------------------------");
14046                    }
14047                }
14048                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14049                pw.println();
14050                if (dumpAll) {
14051                    pw.println("-------------------------------------------------------------------------------");
14052                }
14053                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14054                pw.println();
14055                if (dumpAll) {
14056                    pw.println("-------------------------------------------------------------------------------");
14057                }
14058                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14059                        dumpPackage);
14060            }
14061            sdumper.dumpWithClient();
14062            pw.println();
14063            synchronized (this) {
14064                if (dumpAll) {
14065                    pw.println("-------------------------------------------------------------------------------");
14066                }
14067                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14068                pw.println();
14069                if (dumpAll) {
14070                    pw.println("-------------------------------------------------------------------------------");
14071                }
14072                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14073                if (mAssociations.size() > 0) {
14074                    pw.println();
14075                    if (dumpAll) {
14076                        pw.println("-------------------------------------------------------------------------------");
14077                    }
14078                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14079                }
14080                pw.println();
14081                if (dumpAll) {
14082                    pw.println("-------------------------------------------------------------------------------");
14083                }
14084                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14085            }
14086
14087        } else {
14088            synchronized (this) {
14089                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14090                pw.println();
14091                if (dumpAll) {
14092                    pw.println("-------------------------------------------------------------------------------");
14093                }
14094                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14095                pw.println();
14096                if (dumpAll) {
14097                    pw.println("-------------------------------------------------------------------------------");
14098                }
14099                if (dumpAll || dumpPackage != null) {
14100                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14101                    pw.println();
14102                    if (dumpAll) {
14103                        pw.println("-------------------------------------------------------------------------------");
14104                    }
14105                }
14106                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14107                pw.println();
14108                if (dumpAll) {
14109                    pw.println("-------------------------------------------------------------------------------");
14110                }
14111                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14112                pw.println();
14113                if (dumpAll) {
14114                    pw.println("-------------------------------------------------------------------------------");
14115                }
14116                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14117                        .dumpLocked();
14118                pw.println();
14119                if (dumpAll) {
14120                    pw.println("-------------------------------------------------------------------------------");
14121                }
14122                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14123                pw.println();
14124                if (dumpAll) {
14125                    pw.println("-------------------------------------------------------------------------------");
14126                }
14127                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14128                if (mAssociations.size() > 0) {
14129                    pw.println();
14130                    if (dumpAll) {
14131                        pw.println("-------------------------------------------------------------------------------");
14132                    }
14133                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14134                }
14135                pw.println();
14136                if (dumpAll) {
14137                    pw.println("-------------------------------------------------------------------------------");
14138                }
14139                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14140            }
14141        }
14142        Binder.restoreCallingIdentity(origId);
14143    }
14144
14145    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14146            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14147        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14148
14149        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14150                dumpPackage);
14151        boolean needSep = printedAnything;
14152
14153        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14154                dumpPackage, needSep, "  mFocusedActivity: ");
14155        if (printed) {
14156            printedAnything = true;
14157            needSep = false;
14158        }
14159
14160        if (dumpPackage == null) {
14161            if (needSep) {
14162                pw.println();
14163            }
14164            needSep = true;
14165            printedAnything = true;
14166            mStackSupervisor.dump(pw, "  ");
14167        }
14168
14169        if (!printedAnything) {
14170            pw.println("  (nothing)");
14171        }
14172    }
14173
14174    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14175            int opti, boolean dumpAll, String dumpPackage) {
14176        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14177
14178        boolean printedAnything = false;
14179
14180        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14181            boolean printedHeader = false;
14182
14183            final int N = mRecentTasks.size();
14184            for (int i=0; i<N; i++) {
14185                TaskRecord tr = mRecentTasks.get(i);
14186                if (dumpPackage != null) {
14187                    if (tr.realActivity == null ||
14188                            !dumpPackage.equals(tr.realActivity)) {
14189                        continue;
14190                    }
14191                }
14192                if (!printedHeader) {
14193                    pw.println("  Recent tasks:");
14194                    printedHeader = true;
14195                    printedAnything = true;
14196                }
14197                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14198                        pw.println(tr);
14199                if (dumpAll) {
14200                    mRecentTasks.get(i).dump(pw, "    ");
14201                }
14202            }
14203        }
14204
14205        if (!printedAnything) {
14206            pw.println("  (nothing)");
14207        }
14208    }
14209
14210    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14211            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14212        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14213
14214        int dumpUid = 0;
14215        if (dumpPackage != null) {
14216            IPackageManager pm = AppGlobals.getPackageManager();
14217            try {
14218                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14219            } catch (RemoteException e) {
14220            }
14221        }
14222
14223        boolean printedAnything = false;
14224
14225        final long now = SystemClock.uptimeMillis();
14226
14227        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14228            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14229                    = mAssociations.valueAt(i1);
14230            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14231                SparseArray<ArrayMap<String, Association>> sourceUids
14232                        = targetComponents.valueAt(i2);
14233                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14234                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14235                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14236                        Association ass = sourceProcesses.valueAt(i4);
14237                        if (dumpPackage != null) {
14238                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14239                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14240                                continue;
14241                            }
14242                        }
14243                        printedAnything = true;
14244                        pw.print("  ");
14245                        pw.print(ass.mTargetProcess);
14246                        pw.print("/");
14247                        UserHandle.formatUid(pw, ass.mTargetUid);
14248                        pw.print(" <- ");
14249                        pw.print(ass.mSourceProcess);
14250                        pw.print("/");
14251                        UserHandle.formatUid(pw, ass.mSourceUid);
14252                        pw.println();
14253                        pw.print("    via ");
14254                        pw.print(ass.mTargetComponent.flattenToShortString());
14255                        pw.println();
14256                        pw.print("    ");
14257                        long dur = ass.mTime;
14258                        if (ass.mNesting > 0) {
14259                            dur += now - ass.mStartTime;
14260                        }
14261                        TimeUtils.formatDuration(dur, pw);
14262                        pw.print(" (");
14263                        pw.print(ass.mCount);
14264                        pw.print(" times)");
14265                        pw.print("  ");
14266                        for (int i=0; i<ass.mStateTimes.length; i++) {
14267                            long amt = ass.mStateTimes[i];
14268                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14269                                amt += now - ass.mLastStateUptime;
14270                            }
14271                            if (amt != 0) {
14272                                pw.print(" ");
14273                                pw.print(ProcessList.makeProcStateString(
14274                                            i + ActivityManager.MIN_PROCESS_STATE));
14275                                pw.print("=");
14276                                TimeUtils.formatDuration(amt, pw);
14277                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14278                                    pw.print("*");
14279                                }
14280                            }
14281                        }
14282                        pw.println();
14283                        if (ass.mNesting > 0) {
14284                            pw.print("    Currently active: ");
14285                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14286                            pw.println();
14287                        }
14288                    }
14289                }
14290            }
14291
14292        }
14293
14294        if (!printedAnything) {
14295            pw.println("  (nothing)");
14296        }
14297    }
14298
14299    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14300            String header, boolean needSep) {
14301        boolean printed = false;
14302        int whichAppId = -1;
14303        if (dumpPackage != null) {
14304            try {
14305                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14306                        dumpPackage, 0);
14307                whichAppId = UserHandle.getAppId(info.uid);
14308            } catch (NameNotFoundException e) {
14309                e.printStackTrace();
14310            }
14311        }
14312        for (int i=0; i<uids.size(); i++) {
14313            UidRecord uidRec = uids.valueAt(i);
14314            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14315                continue;
14316            }
14317            if (!printed) {
14318                printed = true;
14319                if (needSep) {
14320                    pw.println();
14321                }
14322                pw.print("  ");
14323                pw.println(header);
14324                needSep = true;
14325            }
14326            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14327            pw.print(": "); pw.println(uidRec);
14328        }
14329        return printed;
14330    }
14331
14332    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14333            int opti, boolean dumpAll, String dumpPackage) {
14334        boolean needSep = false;
14335        boolean printedAnything = false;
14336        int numPers = 0;
14337
14338        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14339
14340        if (dumpAll) {
14341            final int NP = mProcessNames.getMap().size();
14342            for (int ip=0; ip<NP; ip++) {
14343                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14344                final int NA = procs.size();
14345                for (int ia=0; ia<NA; ia++) {
14346                    ProcessRecord r = procs.valueAt(ia);
14347                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14348                        continue;
14349                    }
14350                    if (!needSep) {
14351                        pw.println("  All known processes:");
14352                        needSep = true;
14353                        printedAnything = true;
14354                    }
14355                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14356                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14357                        pw.print(" "); pw.println(r);
14358                    r.dump(pw, "    ");
14359                    if (r.persistent) {
14360                        numPers++;
14361                    }
14362                }
14363            }
14364        }
14365
14366        if (mIsolatedProcesses.size() > 0) {
14367            boolean printed = false;
14368            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14369                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14370                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14371                    continue;
14372                }
14373                if (!printed) {
14374                    if (needSep) {
14375                        pw.println();
14376                    }
14377                    pw.println("  Isolated process list (sorted by uid):");
14378                    printedAnything = true;
14379                    printed = true;
14380                    needSep = true;
14381                }
14382                pw.println(String.format("%sIsolated #%2d: %s",
14383                        "    ", i, r.toString()));
14384            }
14385        }
14386
14387        if (mActiveUids.size() > 0) {
14388            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14389                printedAnything = needSep = true;
14390            }
14391        }
14392        if (mValidateUids.size() > 0) {
14393            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14394                printedAnything = needSep = true;
14395            }
14396        }
14397
14398        if (mLruProcesses.size() > 0) {
14399            if (needSep) {
14400                pw.println();
14401            }
14402            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14403                    pw.print(" total, non-act at ");
14404                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14405                    pw.print(", non-svc at ");
14406                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14407                    pw.println("):");
14408            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14409            needSep = true;
14410            printedAnything = true;
14411        }
14412
14413        if (dumpAll || dumpPackage != null) {
14414            synchronized (mPidsSelfLocked) {
14415                boolean printed = false;
14416                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14417                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14418                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14419                        continue;
14420                    }
14421                    if (!printed) {
14422                        if (needSep) pw.println();
14423                        needSep = true;
14424                        pw.println("  PID mappings:");
14425                        printed = true;
14426                        printedAnything = true;
14427                    }
14428                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14429                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14430                }
14431            }
14432        }
14433
14434        if (mForegroundProcesses.size() > 0) {
14435            synchronized (mPidsSelfLocked) {
14436                boolean printed = false;
14437                for (int i=0; i<mForegroundProcesses.size(); i++) {
14438                    ProcessRecord r = mPidsSelfLocked.get(
14439                            mForegroundProcesses.valueAt(i).pid);
14440                    if (dumpPackage != null && (r == null
14441                            || !r.pkgList.containsKey(dumpPackage))) {
14442                        continue;
14443                    }
14444                    if (!printed) {
14445                        if (needSep) pw.println();
14446                        needSep = true;
14447                        pw.println("  Foreground Processes:");
14448                        printed = true;
14449                        printedAnything = true;
14450                    }
14451                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14452                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14453                }
14454            }
14455        }
14456
14457        if (mPersistentStartingProcesses.size() > 0) {
14458            if (needSep) pw.println();
14459            needSep = true;
14460            printedAnything = true;
14461            pw.println("  Persisent processes that are starting:");
14462            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14463                    "Starting Norm", "Restarting PERS", dumpPackage);
14464        }
14465
14466        if (mRemovedProcesses.size() > 0) {
14467            if (needSep) pw.println();
14468            needSep = true;
14469            printedAnything = true;
14470            pw.println("  Processes that are being removed:");
14471            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14472                    "Removed Norm", "Removed PERS", dumpPackage);
14473        }
14474
14475        if (mProcessesOnHold.size() > 0) {
14476            if (needSep) pw.println();
14477            needSep = true;
14478            printedAnything = true;
14479            pw.println("  Processes that are on old until the system is ready:");
14480            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14481                    "OnHold Norm", "OnHold PERS", dumpPackage);
14482        }
14483
14484        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14485
14486        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14487        if (needSep) {
14488            printedAnything = true;
14489        }
14490
14491        if (dumpPackage == null) {
14492            pw.println();
14493            needSep = false;
14494            mUserController.dump(pw, dumpAll);
14495        }
14496        if (mHomeProcess != null && (dumpPackage == null
14497                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14498            if (needSep) {
14499                pw.println();
14500                needSep = false;
14501            }
14502            pw.println("  mHomeProcess: " + mHomeProcess);
14503        }
14504        if (mPreviousProcess != null && (dumpPackage == null
14505                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14506            if (needSep) {
14507                pw.println();
14508                needSep = false;
14509            }
14510            pw.println("  mPreviousProcess: " + mPreviousProcess);
14511        }
14512        if (dumpAll) {
14513            StringBuilder sb = new StringBuilder(128);
14514            sb.append("  mPreviousProcessVisibleTime: ");
14515            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14516            pw.println(sb);
14517        }
14518        if (mHeavyWeightProcess != null && (dumpPackage == null
14519                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14520            if (needSep) {
14521                pw.println();
14522                needSep = false;
14523            }
14524            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14525        }
14526        if (dumpPackage == null) {
14527            pw.println("  mConfiguration: " + mConfiguration);
14528        }
14529        if (dumpAll) {
14530            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14531            if (mCompatModePackages.getPackages().size() > 0) {
14532                boolean printed = false;
14533                for (Map.Entry<String, Integer> entry
14534                        : mCompatModePackages.getPackages().entrySet()) {
14535                    String pkg = entry.getKey();
14536                    int mode = entry.getValue();
14537                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14538                        continue;
14539                    }
14540                    if (!printed) {
14541                        pw.println("  mScreenCompatPackages:");
14542                        printed = true;
14543                    }
14544                    pw.print("    "); pw.print(pkg); pw.print(": ");
14545                            pw.print(mode); pw.println();
14546                }
14547            }
14548        }
14549        if (dumpPackage == null) {
14550            pw.println("  mWakefulness="
14551                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14552            pw.println("  mSleepTokens=" + mSleepTokens);
14553            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14554                    + lockScreenShownToString());
14555            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14556            if (mRunningVoice != null) {
14557                pw.println("  mRunningVoice=" + mRunningVoice);
14558                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14559            }
14560        }
14561        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14562                || mOrigWaitForDebugger) {
14563            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14564                    || dumpPackage.equals(mOrigDebugApp)) {
14565                if (needSep) {
14566                    pw.println();
14567                    needSep = false;
14568                }
14569                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14570                        + " mDebugTransient=" + mDebugTransient
14571                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14572            }
14573        }
14574        if (mCurAppTimeTracker != null) {
14575            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14576        }
14577        if (mMemWatchProcesses.getMap().size() > 0) {
14578            pw.println("  Mem watch processes:");
14579            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14580                    = mMemWatchProcesses.getMap();
14581            for (int i=0; i<procs.size(); i++) {
14582                final String proc = procs.keyAt(i);
14583                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14584                for (int j=0; j<uids.size(); j++) {
14585                    if (needSep) {
14586                        pw.println();
14587                        needSep = false;
14588                    }
14589                    StringBuilder sb = new StringBuilder();
14590                    sb.append("    ").append(proc).append('/');
14591                    UserHandle.formatUid(sb, uids.keyAt(j));
14592                    Pair<Long, String> val = uids.valueAt(j);
14593                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14594                    if (val.second != null) {
14595                        sb.append(", report to ").append(val.second);
14596                    }
14597                    pw.println(sb.toString());
14598                }
14599            }
14600            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14601            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14602            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14603                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14604        }
14605        if (mTrackAllocationApp != null) {
14606            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14607                if (needSep) {
14608                    pw.println();
14609                    needSep = false;
14610                }
14611                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14612            }
14613        }
14614        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14615                || mProfileFd != null) {
14616            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14617                if (needSep) {
14618                    pw.println();
14619                    needSep = false;
14620                }
14621                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14622                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14623                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14624                        + mAutoStopProfiler);
14625                pw.println("  mProfileType=" + mProfileType);
14626            }
14627        }
14628        if (mNativeDebuggingApp != null) {
14629            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14630                if (needSep) {
14631                    pw.println();
14632                    needSep = false;
14633                }
14634                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14635            }
14636        }
14637        if (dumpPackage == null) {
14638            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14639                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14640                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14641            }
14642            if (mController != null) {
14643                pw.println("  mController=" + mController
14644                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14645            }
14646            if (dumpAll) {
14647                pw.println("  Total persistent processes: " + numPers);
14648                pw.println("  mProcessesReady=" + mProcessesReady
14649                        + " mSystemReady=" + mSystemReady
14650                        + " mBooted=" + mBooted
14651                        + " mFactoryTest=" + mFactoryTest);
14652                pw.println("  mBooting=" + mBooting
14653                        + " mCallFinishBooting=" + mCallFinishBooting
14654                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14655                pw.print("  mLastPowerCheckRealtime=");
14656                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14657                        pw.println("");
14658                pw.print("  mLastPowerCheckUptime=");
14659                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14660                        pw.println("");
14661                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14662                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14663                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14664                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14665                        + " (" + mLruProcesses.size() + " total)"
14666                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14667                        + " mNumServiceProcs=" + mNumServiceProcs
14668                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14669                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14670                        + " mLastMemoryLevel=" + mLastMemoryLevel
14671                        + " mLastNumProcesses=" + mLastNumProcesses);
14672                long now = SystemClock.uptimeMillis();
14673                pw.print("  mLastIdleTime=");
14674                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14675                        pw.print(" mLowRamSinceLastIdle=");
14676                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14677                        pw.println();
14678            }
14679        }
14680
14681        if (!printedAnything) {
14682            pw.println("  (nothing)");
14683        }
14684    }
14685
14686    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14687            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14688        if (mProcessesToGc.size() > 0) {
14689            boolean printed = false;
14690            long now = SystemClock.uptimeMillis();
14691            for (int i=0; i<mProcessesToGc.size(); i++) {
14692                ProcessRecord proc = mProcessesToGc.get(i);
14693                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14694                    continue;
14695                }
14696                if (!printed) {
14697                    if (needSep) pw.println();
14698                    needSep = true;
14699                    pw.println("  Processes that are waiting to GC:");
14700                    printed = true;
14701                }
14702                pw.print("    Process "); pw.println(proc);
14703                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14704                        pw.print(", last gced=");
14705                        pw.print(now-proc.lastRequestedGc);
14706                        pw.print(" ms ago, last lowMem=");
14707                        pw.print(now-proc.lastLowMemory);
14708                        pw.println(" ms ago");
14709
14710            }
14711        }
14712        return needSep;
14713    }
14714
14715    void printOomLevel(PrintWriter pw, String name, int adj) {
14716        pw.print("    ");
14717        if (adj >= 0) {
14718            pw.print(' ');
14719            if (adj < 10) pw.print(' ');
14720        } else {
14721            if (adj > -10) pw.print(' ');
14722        }
14723        pw.print(adj);
14724        pw.print(": ");
14725        pw.print(name);
14726        pw.print(" (");
14727        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14728        pw.println(")");
14729    }
14730
14731    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14732            int opti, boolean dumpAll) {
14733        boolean needSep = false;
14734
14735        if (mLruProcesses.size() > 0) {
14736            if (needSep) pw.println();
14737            needSep = true;
14738            pw.println("  OOM levels:");
14739            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14740            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14741            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14742            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14743            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14744            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14745            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14746            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14747            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14748            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14749            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14750            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14751            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14752            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14753
14754            if (needSep) pw.println();
14755            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14756                    pw.print(" total, non-act at ");
14757                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14758                    pw.print(", non-svc at ");
14759                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14760                    pw.println("):");
14761            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14762            needSep = true;
14763        }
14764
14765        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14766
14767        pw.println();
14768        pw.println("  mHomeProcess: " + mHomeProcess);
14769        pw.println("  mPreviousProcess: " + mPreviousProcess);
14770        if (mHeavyWeightProcess != null) {
14771            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14772        }
14773
14774        return true;
14775    }
14776
14777    /**
14778     * There are three ways to call this:
14779     *  - no provider specified: dump all the providers
14780     *  - a flattened component name that matched an existing provider was specified as the
14781     *    first arg: dump that one provider
14782     *  - the first arg isn't the flattened component name of an existing provider:
14783     *    dump all providers whose component contains the first arg as a substring
14784     */
14785    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14786            int opti, boolean dumpAll) {
14787        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14788    }
14789
14790    static class ItemMatcher {
14791        ArrayList<ComponentName> components;
14792        ArrayList<String> strings;
14793        ArrayList<Integer> objects;
14794        boolean all;
14795
14796        ItemMatcher() {
14797            all = true;
14798        }
14799
14800        void build(String name) {
14801            ComponentName componentName = ComponentName.unflattenFromString(name);
14802            if (componentName != null) {
14803                if (components == null) {
14804                    components = new ArrayList<ComponentName>();
14805                }
14806                components.add(componentName);
14807                all = false;
14808            } else {
14809                int objectId = 0;
14810                // Not a '/' separated full component name; maybe an object ID?
14811                try {
14812                    objectId = Integer.parseInt(name, 16);
14813                    if (objects == null) {
14814                        objects = new ArrayList<Integer>();
14815                    }
14816                    objects.add(objectId);
14817                    all = false;
14818                } catch (RuntimeException e) {
14819                    // Not an integer; just do string match.
14820                    if (strings == null) {
14821                        strings = new ArrayList<String>();
14822                    }
14823                    strings.add(name);
14824                    all = false;
14825                }
14826            }
14827        }
14828
14829        int build(String[] args, int opti) {
14830            for (; opti<args.length; opti++) {
14831                String name = args[opti];
14832                if ("--".equals(name)) {
14833                    return opti+1;
14834                }
14835                build(name);
14836            }
14837            return opti;
14838        }
14839
14840        boolean match(Object object, ComponentName comp) {
14841            if (all) {
14842                return true;
14843            }
14844            if (components != null) {
14845                for (int i=0; i<components.size(); i++) {
14846                    if (components.get(i).equals(comp)) {
14847                        return true;
14848                    }
14849                }
14850            }
14851            if (objects != null) {
14852                for (int i=0; i<objects.size(); i++) {
14853                    if (System.identityHashCode(object) == objects.get(i)) {
14854                        return true;
14855                    }
14856                }
14857            }
14858            if (strings != null) {
14859                String flat = comp.flattenToString();
14860                for (int i=0; i<strings.size(); i++) {
14861                    if (flat.contains(strings.get(i))) {
14862                        return true;
14863                    }
14864                }
14865            }
14866            return false;
14867        }
14868    }
14869
14870    /**
14871     * There are three things that cmd can be:
14872     *  - a flattened component name that matches an existing activity
14873     *  - the cmd arg isn't the flattened component name of an existing activity:
14874     *    dump all activity whose component contains the cmd as a substring
14875     *  - A hex number of the ActivityRecord object instance.
14876     */
14877    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14878            int opti, boolean dumpAll) {
14879        ArrayList<ActivityRecord> activities;
14880
14881        synchronized (this) {
14882            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14883        }
14884
14885        if (activities.size() <= 0) {
14886            return false;
14887        }
14888
14889        String[] newArgs = new String[args.length - opti];
14890        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14891
14892        TaskRecord lastTask = null;
14893        boolean needSep = false;
14894        for (int i=activities.size()-1; i>=0; i--) {
14895            ActivityRecord r = activities.get(i);
14896            if (needSep) {
14897                pw.println();
14898            }
14899            needSep = true;
14900            synchronized (this) {
14901                if (lastTask != r.task) {
14902                    lastTask = r.task;
14903                    pw.print("TASK "); pw.print(lastTask.affinity);
14904                            pw.print(" id="); pw.println(lastTask.taskId);
14905                    if (dumpAll) {
14906                        lastTask.dump(pw, "  ");
14907                    }
14908                }
14909            }
14910            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14911        }
14912        return true;
14913    }
14914
14915    /**
14916     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14917     * there is a thread associated with the activity.
14918     */
14919    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14920            final ActivityRecord r, String[] args, boolean dumpAll) {
14921        String innerPrefix = prefix + "  ";
14922        synchronized (this) {
14923            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14924                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14925                    pw.print(" pid=");
14926                    if (r.app != null) pw.println(r.app.pid);
14927                    else pw.println("(not running)");
14928            if (dumpAll) {
14929                r.dump(pw, innerPrefix);
14930            }
14931        }
14932        if (r.app != null && r.app.thread != null) {
14933            // flush anything that is already in the PrintWriter since the thread is going
14934            // to write to the file descriptor directly
14935            pw.flush();
14936            try {
14937                TransferPipe tp = new TransferPipe();
14938                try {
14939                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14940                            r.appToken, innerPrefix, args);
14941                    tp.go(fd);
14942                } finally {
14943                    tp.kill();
14944                }
14945            } catch (IOException e) {
14946                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14947            } catch (RemoteException e) {
14948                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14949            }
14950        }
14951    }
14952
14953    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14954            int opti, boolean dumpAll, String dumpPackage) {
14955        boolean needSep = false;
14956        boolean onlyHistory = false;
14957        boolean printedAnything = false;
14958
14959        if ("history".equals(dumpPackage)) {
14960            if (opti < args.length && "-s".equals(args[opti])) {
14961                dumpAll = false;
14962            }
14963            onlyHistory = true;
14964            dumpPackage = null;
14965        }
14966
14967        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14968        if (!onlyHistory && dumpAll) {
14969            if (mRegisteredReceivers.size() > 0) {
14970                boolean printed = false;
14971                Iterator it = mRegisteredReceivers.values().iterator();
14972                while (it.hasNext()) {
14973                    ReceiverList r = (ReceiverList)it.next();
14974                    if (dumpPackage != null && (r.app == null ||
14975                            !dumpPackage.equals(r.app.info.packageName))) {
14976                        continue;
14977                    }
14978                    if (!printed) {
14979                        pw.println("  Registered Receivers:");
14980                        needSep = true;
14981                        printed = true;
14982                        printedAnything = true;
14983                    }
14984                    pw.print("  * "); pw.println(r);
14985                    r.dump(pw, "    ");
14986                }
14987            }
14988
14989            if (mReceiverResolver.dump(pw, needSep ?
14990                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14991                    "    ", dumpPackage, false, false)) {
14992                needSep = true;
14993                printedAnything = true;
14994            }
14995        }
14996
14997        for (BroadcastQueue q : mBroadcastQueues) {
14998            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14999            printedAnything |= needSep;
15000        }
15001
15002        needSep = true;
15003
15004        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15005            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15006                if (needSep) {
15007                    pw.println();
15008                }
15009                needSep = true;
15010                printedAnything = true;
15011                pw.print("  Sticky broadcasts for user ");
15012                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15013                StringBuilder sb = new StringBuilder(128);
15014                for (Map.Entry<String, ArrayList<Intent>> ent
15015                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15016                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15017                    if (dumpAll) {
15018                        pw.println(":");
15019                        ArrayList<Intent> intents = ent.getValue();
15020                        final int N = intents.size();
15021                        for (int i=0; i<N; i++) {
15022                            sb.setLength(0);
15023                            sb.append("    Intent: ");
15024                            intents.get(i).toShortString(sb, false, true, false, false);
15025                            pw.println(sb.toString());
15026                            Bundle bundle = intents.get(i).getExtras();
15027                            if (bundle != null) {
15028                                pw.print("      ");
15029                                pw.println(bundle.toString());
15030                            }
15031                        }
15032                    } else {
15033                        pw.println("");
15034                    }
15035                }
15036            }
15037        }
15038
15039        if (!onlyHistory && dumpAll) {
15040            pw.println();
15041            for (BroadcastQueue queue : mBroadcastQueues) {
15042                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15043                        + queue.mBroadcastsScheduled);
15044            }
15045            pw.println("  mHandler:");
15046            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15047            needSep = true;
15048            printedAnything = true;
15049        }
15050
15051        if (!printedAnything) {
15052            pw.println("  (nothing)");
15053        }
15054    }
15055
15056    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15057            int opti, boolean dumpAll, String dumpPackage) {
15058        if (mCurBroadcastStats == null) {
15059            return;
15060        }
15061
15062        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15063        final long now = SystemClock.elapsedRealtime();
15064        if (mLastBroadcastStats != null) {
15065            pw.print("  Last stats (from ");
15066            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15067            pw.print(" to ");
15068            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15069            pw.print(", ");
15070            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15071                    - mLastBroadcastStats.mStartUptime, pw);
15072            pw.println(" uptime):");
15073            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15074                pw.println("    (nothing)");
15075            }
15076            pw.println();
15077        }
15078        pw.print("  Current stats (from ");
15079        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15080        pw.print(" to now, ");
15081        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15082                - mCurBroadcastStats.mStartUptime, pw);
15083        pw.println(" uptime):");
15084        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15085            pw.println("    (nothing)");
15086        }
15087    }
15088
15089    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15090            int opti, boolean fullCheckin, String dumpPackage) {
15091        if (mCurBroadcastStats == null) {
15092            return;
15093        }
15094
15095        if (mLastBroadcastStats != null) {
15096            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15097            if (fullCheckin) {
15098                mLastBroadcastStats = null;
15099                return;
15100            }
15101        }
15102        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15103        if (fullCheckin) {
15104            mCurBroadcastStats = null;
15105        }
15106    }
15107
15108    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15109            int opti, boolean dumpAll, String dumpPackage) {
15110        boolean needSep;
15111        boolean printedAnything = false;
15112
15113        ItemMatcher matcher = new ItemMatcher();
15114        matcher.build(args, opti);
15115
15116        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15117
15118        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15119        printedAnything |= needSep;
15120
15121        if (mLaunchingProviders.size() > 0) {
15122            boolean printed = false;
15123            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15124                ContentProviderRecord r = mLaunchingProviders.get(i);
15125                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15126                    continue;
15127                }
15128                if (!printed) {
15129                    if (needSep) pw.println();
15130                    needSep = true;
15131                    pw.println("  Launching content providers:");
15132                    printed = true;
15133                    printedAnything = true;
15134                }
15135                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15136                        pw.println(r);
15137            }
15138        }
15139
15140        if (!printedAnything) {
15141            pw.println("  (nothing)");
15142        }
15143    }
15144
15145    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15146            int opti, boolean dumpAll, String dumpPackage) {
15147        boolean needSep = false;
15148        boolean printedAnything = false;
15149
15150        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15151
15152        if (mGrantedUriPermissions.size() > 0) {
15153            boolean printed = false;
15154            int dumpUid = -2;
15155            if (dumpPackage != null) {
15156                try {
15157                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15158                            MATCH_UNINSTALLED_PACKAGES, 0);
15159                } catch (NameNotFoundException e) {
15160                    dumpUid = -1;
15161                }
15162            }
15163            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15164                int uid = mGrantedUriPermissions.keyAt(i);
15165                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15166                    continue;
15167                }
15168                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15169                if (!printed) {
15170                    if (needSep) pw.println();
15171                    needSep = true;
15172                    pw.println("  Granted Uri Permissions:");
15173                    printed = true;
15174                    printedAnything = true;
15175                }
15176                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15177                for (UriPermission perm : perms.values()) {
15178                    pw.print("    "); pw.println(perm);
15179                    if (dumpAll) {
15180                        perm.dump(pw, "      ");
15181                    }
15182                }
15183            }
15184        }
15185
15186        if (!printedAnything) {
15187            pw.println("  (nothing)");
15188        }
15189    }
15190
15191    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15192            int opti, boolean dumpAll, String dumpPackage) {
15193        boolean printed = false;
15194
15195        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15196
15197        if (mIntentSenderRecords.size() > 0) {
15198            Iterator<WeakReference<PendingIntentRecord>> it
15199                    = mIntentSenderRecords.values().iterator();
15200            while (it.hasNext()) {
15201                WeakReference<PendingIntentRecord> ref = it.next();
15202                PendingIntentRecord rec = ref != null ? ref.get(): null;
15203                if (dumpPackage != null && (rec == null
15204                        || !dumpPackage.equals(rec.key.packageName))) {
15205                    continue;
15206                }
15207                printed = true;
15208                if (rec != null) {
15209                    pw.print("  * "); pw.println(rec);
15210                    if (dumpAll) {
15211                        rec.dump(pw, "    ");
15212                    }
15213                } else {
15214                    pw.print("  * "); pw.println(ref);
15215                }
15216            }
15217        }
15218
15219        if (!printed) {
15220            pw.println("  (nothing)");
15221        }
15222    }
15223
15224    private static final int dumpProcessList(PrintWriter pw,
15225            ActivityManagerService service, List list,
15226            String prefix, String normalLabel, String persistentLabel,
15227            String dumpPackage) {
15228        int numPers = 0;
15229        final int N = list.size()-1;
15230        for (int i=N; i>=0; i--) {
15231            ProcessRecord r = (ProcessRecord)list.get(i);
15232            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15233                continue;
15234            }
15235            pw.println(String.format("%s%s #%2d: %s",
15236                    prefix, (r.persistent ? persistentLabel : normalLabel),
15237                    i, r.toString()));
15238            if (r.persistent) {
15239                numPers++;
15240            }
15241        }
15242        return numPers;
15243    }
15244
15245    private static final boolean dumpProcessOomList(PrintWriter pw,
15246            ActivityManagerService service, List<ProcessRecord> origList,
15247            String prefix, String normalLabel, String persistentLabel,
15248            boolean inclDetails, String dumpPackage) {
15249
15250        ArrayList<Pair<ProcessRecord, Integer>> list
15251                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15252        for (int i=0; i<origList.size(); i++) {
15253            ProcessRecord r = origList.get(i);
15254            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15255                continue;
15256            }
15257            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15258        }
15259
15260        if (list.size() <= 0) {
15261            return false;
15262        }
15263
15264        Comparator<Pair<ProcessRecord, Integer>> comparator
15265                = new Comparator<Pair<ProcessRecord, Integer>>() {
15266            @Override
15267            public int compare(Pair<ProcessRecord, Integer> object1,
15268                    Pair<ProcessRecord, Integer> object2) {
15269                if (object1.first.setAdj != object2.first.setAdj) {
15270                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15271                }
15272                if (object1.first.setProcState != object2.first.setProcState) {
15273                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15274                }
15275                if (object1.second.intValue() != object2.second.intValue()) {
15276                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15277                }
15278                return 0;
15279            }
15280        };
15281
15282        Collections.sort(list, comparator);
15283
15284        final long curRealtime = SystemClock.elapsedRealtime();
15285        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15286        final long curUptime = SystemClock.uptimeMillis();
15287        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15288
15289        for (int i=list.size()-1; i>=0; i--) {
15290            ProcessRecord r = list.get(i).first;
15291            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15292            char schedGroup;
15293            switch (r.setSchedGroup) {
15294                case ProcessList.SCHED_GROUP_BACKGROUND:
15295                    schedGroup = 'B';
15296                    break;
15297                case ProcessList.SCHED_GROUP_DEFAULT:
15298                    schedGroup = 'F';
15299                    break;
15300                case ProcessList.SCHED_GROUP_TOP_APP:
15301                    schedGroup = 'T';
15302                    break;
15303                default:
15304                    schedGroup = '?';
15305                    break;
15306            }
15307            char foreground;
15308            if (r.foregroundActivities) {
15309                foreground = 'A';
15310            } else if (r.foregroundServices) {
15311                foreground = 'S';
15312            } else {
15313                foreground = ' ';
15314            }
15315            String procState = ProcessList.makeProcStateString(r.curProcState);
15316            pw.print(prefix);
15317            pw.print(r.persistent ? persistentLabel : normalLabel);
15318            pw.print(" #");
15319            int num = (origList.size()-1)-list.get(i).second;
15320            if (num < 10) pw.print(' ');
15321            pw.print(num);
15322            pw.print(": ");
15323            pw.print(oomAdj);
15324            pw.print(' ');
15325            pw.print(schedGroup);
15326            pw.print('/');
15327            pw.print(foreground);
15328            pw.print('/');
15329            pw.print(procState);
15330            pw.print(" trm:");
15331            if (r.trimMemoryLevel < 10) pw.print(' ');
15332            pw.print(r.trimMemoryLevel);
15333            pw.print(' ');
15334            pw.print(r.toShortString());
15335            pw.print(" (");
15336            pw.print(r.adjType);
15337            pw.println(')');
15338            if (r.adjSource != null || r.adjTarget != null) {
15339                pw.print(prefix);
15340                pw.print("    ");
15341                if (r.adjTarget instanceof ComponentName) {
15342                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15343                } else if (r.adjTarget != null) {
15344                    pw.print(r.adjTarget.toString());
15345                } else {
15346                    pw.print("{null}");
15347                }
15348                pw.print("<=");
15349                if (r.adjSource instanceof ProcessRecord) {
15350                    pw.print("Proc{");
15351                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15352                    pw.println("}");
15353                } else if (r.adjSource != null) {
15354                    pw.println(r.adjSource.toString());
15355                } else {
15356                    pw.println("{null}");
15357                }
15358            }
15359            if (inclDetails) {
15360                pw.print(prefix);
15361                pw.print("    ");
15362                pw.print("oom: max="); pw.print(r.maxAdj);
15363                pw.print(" curRaw="); pw.print(r.curRawAdj);
15364                pw.print(" setRaw="); pw.print(r.setRawAdj);
15365                pw.print(" cur="); pw.print(r.curAdj);
15366                pw.print(" set="); pw.println(r.setAdj);
15367                pw.print(prefix);
15368                pw.print("    ");
15369                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15370                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15371                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15372                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15373                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15374                pw.println();
15375                pw.print(prefix);
15376                pw.print("    ");
15377                pw.print("cached="); pw.print(r.cached);
15378                pw.print(" empty="); pw.print(r.empty);
15379                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15380
15381                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15382                    if (r.lastWakeTime != 0) {
15383                        long wtime;
15384                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15385                        synchronized (stats) {
15386                            wtime = stats.getProcessWakeTime(r.info.uid,
15387                                    r.pid, curRealtime);
15388                        }
15389                        long timeUsed = wtime - r.lastWakeTime;
15390                        pw.print(prefix);
15391                        pw.print("    ");
15392                        pw.print("keep awake over ");
15393                        TimeUtils.formatDuration(realtimeSince, pw);
15394                        pw.print(" used ");
15395                        TimeUtils.formatDuration(timeUsed, pw);
15396                        pw.print(" (");
15397                        pw.print((timeUsed*100)/realtimeSince);
15398                        pw.println("%)");
15399                    }
15400                    if (r.lastCpuTime != 0) {
15401                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15402                        pw.print(prefix);
15403                        pw.print("    ");
15404                        pw.print("run cpu over ");
15405                        TimeUtils.formatDuration(uptimeSince, pw);
15406                        pw.print(" used ");
15407                        TimeUtils.formatDuration(timeUsed, pw);
15408                        pw.print(" (");
15409                        pw.print((timeUsed*100)/uptimeSince);
15410                        pw.println("%)");
15411                    }
15412                }
15413            }
15414        }
15415        return true;
15416    }
15417
15418    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15419            String[] args) {
15420        ArrayList<ProcessRecord> procs;
15421        synchronized (this) {
15422            if (args != null && args.length > start
15423                    && args[start].charAt(0) != '-') {
15424                procs = new ArrayList<ProcessRecord>();
15425                int pid = -1;
15426                try {
15427                    pid = Integer.parseInt(args[start]);
15428                } catch (NumberFormatException e) {
15429                }
15430                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15431                    ProcessRecord proc = mLruProcesses.get(i);
15432                    if (proc.pid == pid) {
15433                        procs.add(proc);
15434                    } else if (allPkgs && proc.pkgList != null
15435                            && proc.pkgList.containsKey(args[start])) {
15436                        procs.add(proc);
15437                    } else if (proc.processName.equals(args[start])) {
15438                        procs.add(proc);
15439                    }
15440                }
15441                if (procs.size() <= 0) {
15442                    return null;
15443                }
15444            } else {
15445                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15446            }
15447        }
15448        return procs;
15449    }
15450
15451    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15452            PrintWriter pw, String[] args) {
15453        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15454        if (procs == null) {
15455            pw.println("No process found for: " + args[0]);
15456            return;
15457        }
15458
15459        long uptime = SystemClock.uptimeMillis();
15460        long realtime = SystemClock.elapsedRealtime();
15461        pw.println("Applications Graphics Acceleration Info:");
15462        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15463
15464        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15465            ProcessRecord r = procs.get(i);
15466            if (r.thread != null) {
15467                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15468                pw.flush();
15469                try {
15470                    TransferPipe tp = new TransferPipe();
15471                    try {
15472                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15473                        tp.go(fd);
15474                    } finally {
15475                        tp.kill();
15476                    }
15477                } catch (IOException e) {
15478                    pw.println("Failure while dumping the app: " + r);
15479                    pw.flush();
15480                } catch (RemoteException e) {
15481                    pw.println("Got a RemoteException while dumping the app " + r);
15482                    pw.flush();
15483                }
15484            }
15485        }
15486    }
15487
15488    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15489        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15490        if (procs == null) {
15491            pw.println("No process found for: " + args[0]);
15492            return;
15493        }
15494
15495        pw.println("Applications Database Info:");
15496
15497        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15498            ProcessRecord r = procs.get(i);
15499            if (r.thread != null) {
15500                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15501                pw.flush();
15502                try {
15503                    TransferPipe tp = new TransferPipe();
15504                    try {
15505                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15506                        tp.go(fd);
15507                    } finally {
15508                        tp.kill();
15509                    }
15510                } catch (IOException e) {
15511                    pw.println("Failure while dumping the app: " + r);
15512                    pw.flush();
15513                } catch (RemoteException e) {
15514                    pw.println("Got a RemoteException while dumping the app " + r);
15515                    pw.flush();
15516                }
15517            }
15518        }
15519    }
15520
15521    final static class MemItem {
15522        final boolean isProc;
15523        final String label;
15524        final String shortLabel;
15525        final long pss;
15526        final long swapPss;
15527        final int id;
15528        final boolean hasActivities;
15529        ArrayList<MemItem> subitems;
15530
15531        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15532                boolean _hasActivities) {
15533            isProc = true;
15534            label = _label;
15535            shortLabel = _shortLabel;
15536            pss = _pss;
15537            swapPss = _swapPss;
15538            id = _id;
15539            hasActivities = _hasActivities;
15540        }
15541
15542        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15543            isProc = false;
15544            label = _label;
15545            shortLabel = _shortLabel;
15546            pss = _pss;
15547            swapPss = _swapPss;
15548            id = _id;
15549            hasActivities = false;
15550        }
15551    }
15552
15553    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15554            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15555        if (sort && !isCompact) {
15556            Collections.sort(items, new Comparator<MemItem>() {
15557                @Override
15558                public int compare(MemItem lhs, MemItem rhs) {
15559                    if (lhs.pss < rhs.pss) {
15560                        return 1;
15561                    } else if (lhs.pss > rhs.pss) {
15562                        return -1;
15563                    }
15564                    return 0;
15565                }
15566            });
15567        }
15568
15569        for (int i=0; i<items.size(); i++) {
15570            MemItem mi = items.get(i);
15571            if (!isCompact) {
15572                if (dumpSwapPss) {
15573                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15574                            mi.label, stringifyKBSize(mi.swapPss));
15575                } else {
15576                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15577                }
15578            } else if (mi.isProc) {
15579                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15580                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15581                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15582                pw.println(mi.hasActivities ? ",a" : ",e");
15583            } else {
15584                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15585                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15586            }
15587            if (mi.subitems != null) {
15588                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15589                        true, isCompact, dumpSwapPss);
15590            }
15591        }
15592    }
15593
15594    // These are in KB.
15595    static final long[] DUMP_MEM_BUCKETS = new long[] {
15596        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15597        120*1024, 160*1024, 200*1024,
15598        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15599        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15600    };
15601
15602    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15603            boolean stackLike) {
15604        int start = label.lastIndexOf('.');
15605        if (start >= 0) start++;
15606        else start = 0;
15607        int end = label.length();
15608        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15609            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15610                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15611                out.append(bucket);
15612                out.append(stackLike ? "MB." : "MB ");
15613                out.append(label, start, end);
15614                return;
15615            }
15616        }
15617        out.append(memKB/1024);
15618        out.append(stackLike ? "MB." : "MB ");
15619        out.append(label, start, end);
15620    }
15621
15622    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15623            ProcessList.NATIVE_ADJ,
15624            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15625            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15626            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15627            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15628            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15629            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15630    };
15631    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15632            "Native",
15633            "System", "Persistent", "Persistent Service", "Foreground",
15634            "Visible", "Perceptible",
15635            "Heavy Weight", "Backup",
15636            "A Services", "Home",
15637            "Previous", "B Services", "Cached"
15638    };
15639    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15640            "native",
15641            "sys", "pers", "persvc", "fore",
15642            "vis", "percept",
15643            "heavy", "backup",
15644            "servicea", "home",
15645            "prev", "serviceb", "cached"
15646    };
15647
15648    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15649            long realtime, boolean isCheckinRequest, boolean isCompact) {
15650        if (isCompact) {
15651            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15652        }
15653        if (isCheckinRequest || isCompact) {
15654            // short checkin version
15655            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15656        } else {
15657            pw.println("Applications Memory Usage (in Kilobytes):");
15658            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15659        }
15660    }
15661
15662    private static final int KSM_SHARED = 0;
15663    private static final int KSM_SHARING = 1;
15664    private static final int KSM_UNSHARED = 2;
15665    private static final int KSM_VOLATILE = 3;
15666
15667    private final long[] getKsmInfo() {
15668        long[] longOut = new long[4];
15669        final int[] SINGLE_LONG_FORMAT = new int[] {
15670            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15671        };
15672        long[] longTmp = new long[1];
15673        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15674                SINGLE_LONG_FORMAT, null, longTmp, null);
15675        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15676        longTmp[0] = 0;
15677        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15678                SINGLE_LONG_FORMAT, null, longTmp, null);
15679        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15680        longTmp[0] = 0;
15681        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15682                SINGLE_LONG_FORMAT, null, longTmp, null);
15683        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15684        longTmp[0] = 0;
15685        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15686                SINGLE_LONG_FORMAT, null, longTmp, null);
15687        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15688        return longOut;
15689    }
15690
15691    private static String stringifySize(long size, int order) {
15692        Locale locale = Locale.US;
15693        switch (order) {
15694            case 1:
15695                return String.format(locale, "%,13d", size);
15696            case 1024:
15697                return String.format(locale, "%,9dK", size / 1024);
15698            case 1024 * 1024:
15699                return String.format(locale, "%,5dM", size / 1024 / 1024);
15700            case 1024 * 1024 * 1024:
15701                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15702            default:
15703                throw new IllegalArgumentException("Invalid size order");
15704        }
15705    }
15706
15707    private static String stringifyKBSize(long size) {
15708        return stringifySize(size * 1024, 1024);
15709    }
15710
15711    // Update this version number in case you change the 'compact' format
15712    private static final int MEMINFO_COMPACT_VERSION = 1;
15713
15714    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15715            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15716        boolean dumpDetails = false;
15717        boolean dumpFullDetails = false;
15718        boolean dumpDalvik = false;
15719        boolean dumpSummaryOnly = false;
15720        boolean dumpUnreachable = false;
15721        boolean oomOnly = false;
15722        boolean isCompact = false;
15723        boolean localOnly = false;
15724        boolean packages = false;
15725        boolean isCheckinRequest = false;
15726        boolean dumpSwapPss = false;
15727
15728        int opti = 0;
15729        while (opti < args.length) {
15730            String opt = args[opti];
15731            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15732                break;
15733            }
15734            opti++;
15735            if ("-a".equals(opt)) {
15736                dumpDetails = true;
15737                dumpFullDetails = true;
15738                dumpDalvik = true;
15739                dumpSwapPss = true;
15740            } else if ("-d".equals(opt)) {
15741                dumpDalvik = true;
15742            } else if ("-c".equals(opt)) {
15743                isCompact = true;
15744            } else if ("-s".equals(opt)) {
15745                dumpDetails = true;
15746                dumpSummaryOnly = true;
15747            } else if ("-S".equals(opt)) {
15748                dumpSwapPss = true;
15749            } else if ("--unreachable".equals(opt)) {
15750                dumpUnreachable = true;
15751            } else if ("--oom".equals(opt)) {
15752                oomOnly = true;
15753            } else if ("--local".equals(opt)) {
15754                localOnly = true;
15755            } else if ("--package".equals(opt)) {
15756                packages = true;
15757            } else if ("--checkin".equals(opt)) {
15758                isCheckinRequest = true;
15759
15760            } else if ("-h".equals(opt)) {
15761                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15762                pw.println("  -a: include all available information for each process.");
15763                pw.println("  -d: include dalvik details.");
15764                pw.println("  -c: dump in a compact machine-parseable representation.");
15765                pw.println("  -s: dump only summary of application memory usage.");
15766                pw.println("  -S: dump also SwapPss.");
15767                pw.println("  --oom: only show processes organized by oom adj.");
15768                pw.println("  --local: only collect details locally, don't call process.");
15769                pw.println("  --package: interpret process arg as package, dumping all");
15770                pw.println("             processes that have loaded that package.");
15771                pw.println("  --checkin: dump data for a checkin");
15772                pw.println("If [process] is specified it can be the name or ");
15773                pw.println("pid of a specific process to dump.");
15774                return;
15775            } else {
15776                pw.println("Unknown argument: " + opt + "; use -h for help");
15777            }
15778        }
15779
15780        long uptime = SystemClock.uptimeMillis();
15781        long realtime = SystemClock.elapsedRealtime();
15782        final long[] tmpLong = new long[1];
15783
15784        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15785        if (procs == null) {
15786            // No Java processes.  Maybe they want to print a native process.
15787            if (args != null && args.length > opti
15788                    && args[opti].charAt(0) != '-') {
15789                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15790                        = new ArrayList<ProcessCpuTracker.Stats>();
15791                updateCpuStatsNow();
15792                int findPid = -1;
15793                try {
15794                    findPid = Integer.parseInt(args[opti]);
15795                } catch (NumberFormatException e) {
15796                }
15797                synchronized (mProcessCpuTracker) {
15798                    final int N = mProcessCpuTracker.countStats();
15799                    for (int i=0; i<N; i++) {
15800                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15801                        if (st.pid == findPid || (st.baseName != null
15802                                && st.baseName.equals(args[opti]))) {
15803                            nativeProcs.add(st);
15804                        }
15805                    }
15806                }
15807                if (nativeProcs.size() > 0) {
15808                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15809                            isCompact);
15810                    Debug.MemoryInfo mi = null;
15811                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15812                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15813                        final int pid = r.pid;
15814                        if (!isCheckinRequest && dumpDetails) {
15815                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15816                        }
15817                        if (mi == null) {
15818                            mi = new Debug.MemoryInfo();
15819                        }
15820                        if (dumpDetails || (!brief && !oomOnly)) {
15821                            Debug.getMemoryInfo(pid, mi);
15822                        } else {
15823                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15824                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15825                        }
15826                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15827                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15828                        if (isCheckinRequest) {
15829                            pw.println();
15830                        }
15831                    }
15832                    return;
15833                }
15834            }
15835            pw.println("No process found for: " + args[opti]);
15836            return;
15837        }
15838
15839        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15840            dumpDetails = true;
15841        }
15842
15843        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15844
15845        String[] innerArgs = new String[args.length-opti];
15846        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15847
15848        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15849        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15850        long nativePss = 0;
15851        long nativeSwapPss = 0;
15852        long dalvikPss = 0;
15853        long dalvikSwapPss = 0;
15854        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15855                EmptyArray.LONG;
15856        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15857                EmptyArray.LONG;
15858        long otherPss = 0;
15859        long otherSwapPss = 0;
15860        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15861        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15862
15863        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15864        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15865        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15866                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15867
15868        long totalPss = 0;
15869        long totalSwapPss = 0;
15870        long cachedPss = 0;
15871        long cachedSwapPss = 0;
15872        boolean hasSwapPss = false;
15873
15874        Debug.MemoryInfo mi = null;
15875        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15876            final ProcessRecord r = procs.get(i);
15877            final IApplicationThread thread;
15878            final int pid;
15879            final int oomAdj;
15880            final boolean hasActivities;
15881            synchronized (this) {
15882                thread = r.thread;
15883                pid = r.pid;
15884                oomAdj = r.getSetAdjWithServices();
15885                hasActivities = r.activities.size() > 0;
15886            }
15887            if (thread != null) {
15888                if (!isCheckinRequest && dumpDetails) {
15889                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15890                }
15891                if (mi == null) {
15892                    mi = new Debug.MemoryInfo();
15893                }
15894                if (dumpDetails || (!brief && !oomOnly)) {
15895                    Debug.getMemoryInfo(pid, mi);
15896                    hasSwapPss = mi.hasSwappedOutPss;
15897                } else {
15898                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15899                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15900                }
15901                if (dumpDetails) {
15902                    if (localOnly) {
15903                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15904                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15905                        if (isCheckinRequest) {
15906                            pw.println();
15907                        }
15908                    } else {
15909                        try {
15910                            pw.flush();
15911                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15912                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15913                        } catch (RemoteException e) {
15914                            if (!isCheckinRequest) {
15915                                pw.println("Got RemoteException!");
15916                                pw.flush();
15917                            }
15918                        }
15919                    }
15920                }
15921
15922                final long myTotalPss = mi.getTotalPss();
15923                final long myTotalUss = mi.getTotalUss();
15924                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15925
15926                synchronized (this) {
15927                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15928                        // Record this for posterity if the process has been stable.
15929                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15930                    }
15931                }
15932
15933                if (!isCheckinRequest && mi != null) {
15934                    totalPss += myTotalPss;
15935                    totalSwapPss += myTotalSwapPss;
15936                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15937                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15938                            myTotalSwapPss, pid, hasActivities);
15939                    procMems.add(pssItem);
15940                    procMemsMap.put(pid, pssItem);
15941
15942                    nativePss += mi.nativePss;
15943                    nativeSwapPss += mi.nativeSwappedOutPss;
15944                    dalvikPss += mi.dalvikPss;
15945                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15946                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15947                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15948                        dalvikSubitemSwapPss[j] +=
15949                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15950                    }
15951                    otherPss += mi.otherPss;
15952                    otherSwapPss += mi.otherSwappedOutPss;
15953                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15954                        long mem = mi.getOtherPss(j);
15955                        miscPss[j] += mem;
15956                        otherPss -= mem;
15957                        mem = mi.getOtherSwappedOutPss(j);
15958                        miscSwapPss[j] += mem;
15959                        otherSwapPss -= mem;
15960                    }
15961
15962                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15963                        cachedPss += myTotalPss;
15964                        cachedSwapPss += myTotalSwapPss;
15965                    }
15966
15967                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15968                        if (oomIndex == (oomPss.length - 1)
15969                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15970                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15971                            oomPss[oomIndex] += myTotalPss;
15972                            oomSwapPss[oomIndex] += myTotalSwapPss;
15973                            if (oomProcs[oomIndex] == null) {
15974                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15975                            }
15976                            oomProcs[oomIndex].add(pssItem);
15977                            break;
15978                        }
15979                    }
15980                }
15981            }
15982        }
15983
15984        long nativeProcTotalPss = 0;
15985
15986        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15987            // If we are showing aggregations, also look for native processes to
15988            // include so that our aggregations are more accurate.
15989            updateCpuStatsNow();
15990            mi = null;
15991            synchronized (mProcessCpuTracker) {
15992                final int N = mProcessCpuTracker.countStats();
15993                for (int i=0; i<N; i++) {
15994                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15995                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15996                        if (mi == null) {
15997                            mi = new Debug.MemoryInfo();
15998                        }
15999                        if (!brief && !oomOnly) {
16000                            Debug.getMemoryInfo(st.pid, mi);
16001                        } else {
16002                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16003                            mi.nativePrivateDirty = (int)tmpLong[0];
16004                        }
16005
16006                        final long myTotalPss = mi.getTotalPss();
16007                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16008                        totalPss += myTotalPss;
16009                        nativeProcTotalPss += myTotalPss;
16010
16011                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16012                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16013                        procMems.add(pssItem);
16014
16015                        nativePss += mi.nativePss;
16016                        nativeSwapPss += mi.nativeSwappedOutPss;
16017                        dalvikPss += mi.dalvikPss;
16018                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16019                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16020                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16021                            dalvikSubitemSwapPss[j] +=
16022                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16023                        }
16024                        otherPss += mi.otherPss;
16025                        otherSwapPss += mi.otherSwappedOutPss;
16026                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16027                            long mem = mi.getOtherPss(j);
16028                            miscPss[j] += mem;
16029                            otherPss -= mem;
16030                            mem = mi.getOtherSwappedOutPss(j);
16031                            miscSwapPss[j] += mem;
16032                            otherSwapPss -= mem;
16033                        }
16034                        oomPss[0] += myTotalPss;
16035                        oomSwapPss[0] += myTotalSwapPss;
16036                        if (oomProcs[0] == null) {
16037                            oomProcs[0] = new ArrayList<MemItem>();
16038                        }
16039                        oomProcs[0].add(pssItem);
16040                    }
16041                }
16042            }
16043
16044            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16045
16046            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16047            final MemItem dalvikItem =
16048                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16049            if (dalvikSubitemPss.length > 0) {
16050                dalvikItem.subitems = new ArrayList<MemItem>();
16051                for (int j=0; j<dalvikSubitemPss.length; j++) {
16052                    final String name = Debug.MemoryInfo.getOtherLabel(
16053                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16054                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16055                                    dalvikSubitemSwapPss[j], j));
16056                }
16057            }
16058            catMems.add(dalvikItem);
16059            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16060            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16061                String label = Debug.MemoryInfo.getOtherLabel(j);
16062                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16063            }
16064
16065            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16066            for (int j=0; j<oomPss.length; j++) {
16067                if (oomPss[j] != 0) {
16068                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16069                            : DUMP_MEM_OOM_LABEL[j];
16070                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16071                            DUMP_MEM_OOM_ADJ[j]);
16072                    item.subitems = oomProcs[j];
16073                    oomMems.add(item);
16074                }
16075            }
16076
16077            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16078            if (!brief && !oomOnly && !isCompact) {
16079                pw.println();
16080                pw.println("Total PSS by process:");
16081                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16082                pw.println();
16083            }
16084            if (!isCompact) {
16085                pw.println("Total PSS by OOM adjustment:");
16086            }
16087            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16088            if (!brief && !oomOnly) {
16089                PrintWriter out = categoryPw != null ? categoryPw : pw;
16090                if (!isCompact) {
16091                    out.println();
16092                    out.println("Total PSS by category:");
16093                }
16094                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16095            }
16096            if (!isCompact) {
16097                pw.println();
16098            }
16099            MemInfoReader memInfo = new MemInfoReader();
16100            memInfo.readMemInfo();
16101            if (nativeProcTotalPss > 0) {
16102                synchronized (this) {
16103                    final long cachedKb = memInfo.getCachedSizeKb();
16104                    final long freeKb = memInfo.getFreeSizeKb();
16105                    final long zramKb = memInfo.getZramTotalSizeKb();
16106                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16107                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16108                            kernelKb*1024, nativeProcTotalPss*1024);
16109                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16110                            nativeProcTotalPss);
16111                }
16112            }
16113            if (!brief) {
16114                if (!isCompact) {
16115                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16116                    pw.print(" (status ");
16117                    switch (mLastMemoryLevel) {
16118                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16119                            pw.println("normal)");
16120                            break;
16121                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16122                            pw.println("moderate)");
16123                            break;
16124                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16125                            pw.println("low)");
16126                            break;
16127                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16128                            pw.println("critical)");
16129                            break;
16130                        default:
16131                            pw.print(mLastMemoryLevel);
16132                            pw.println(")");
16133                            break;
16134                    }
16135                    pw.print(" Free RAM: ");
16136                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16137                            + memInfo.getFreeSizeKb()));
16138                    pw.print(" (");
16139                    pw.print(stringifyKBSize(cachedPss));
16140                    pw.print(" cached pss + ");
16141                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16142                    pw.print(" cached kernel + ");
16143                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16144                    pw.println(" free)");
16145                } else {
16146                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16147                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16148                            + memInfo.getFreeSizeKb()); pw.print(",");
16149                    pw.println(totalPss - cachedPss);
16150                }
16151            }
16152            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16153                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16154                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16155            if (!isCompact) {
16156                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16157                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16158                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16159                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16160                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16161            } else {
16162                pw.print("lostram,"); pw.println(lostRAM);
16163            }
16164            if (!brief) {
16165                if (memInfo.getZramTotalSizeKb() != 0) {
16166                    if (!isCompact) {
16167                        pw.print("     ZRAM: ");
16168                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16169                                pw.print(" physical used for ");
16170                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16171                                        - memInfo.getSwapFreeSizeKb()));
16172                                pw.print(" in swap (");
16173                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16174                                pw.println(" total swap)");
16175                    } else {
16176                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16177                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16178                                pw.println(memInfo.getSwapFreeSizeKb());
16179                    }
16180                }
16181                final long[] ksm = getKsmInfo();
16182                if (!isCompact) {
16183                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16184                            || ksm[KSM_VOLATILE] != 0) {
16185                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16186                                pw.print(" saved from shared ");
16187                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16188                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16189                                pw.print(" unshared; ");
16190                                pw.print(stringifyKBSize(
16191                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16192                    }
16193                    pw.print("   Tuning: ");
16194                    pw.print(ActivityManager.staticGetMemoryClass());
16195                    pw.print(" (large ");
16196                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16197                    pw.print("), oom ");
16198                    pw.print(stringifySize(
16199                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16200                    pw.print(", restore limit ");
16201                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16202                    if (ActivityManager.isLowRamDeviceStatic()) {
16203                        pw.print(" (low-ram)");
16204                    }
16205                    if (ActivityManager.isHighEndGfx()) {
16206                        pw.print(" (high-end-gfx)");
16207                    }
16208                    pw.println();
16209                } else {
16210                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16211                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16212                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16213                    pw.print("tuning,");
16214                    pw.print(ActivityManager.staticGetMemoryClass());
16215                    pw.print(',');
16216                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16217                    pw.print(',');
16218                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16219                    if (ActivityManager.isLowRamDeviceStatic()) {
16220                        pw.print(",low-ram");
16221                    }
16222                    if (ActivityManager.isHighEndGfx()) {
16223                        pw.print(",high-end-gfx");
16224                    }
16225                    pw.println();
16226                }
16227            }
16228        }
16229    }
16230
16231    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16232            long memtrack, String name) {
16233        sb.append("  ");
16234        sb.append(ProcessList.makeOomAdjString(oomAdj));
16235        sb.append(' ');
16236        sb.append(ProcessList.makeProcStateString(procState));
16237        sb.append(' ');
16238        ProcessList.appendRamKb(sb, pss);
16239        sb.append(": ");
16240        sb.append(name);
16241        if (memtrack > 0) {
16242            sb.append(" (");
16243            sb.append(stringifyKBSize(memtrack));
16244            sb.append(" memtrack)");
16245        }
16246    }
16247
16248    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16249        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16250        sb.append(" (pid ");
16251        sb.append(mi.pid);
16252        sb.append(") ");
16253        sb.append(mi.adjType);
16254        sb.append('\n');
16255        if (mi.adjReason != null) {
16256            sb.append("                      ");
16257            sb.append(mi.adjReason);
16258            sb.append('\n');
16259        }
16260    }
16261
16262    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16263        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16264        for (int i=0, N=memInfos.size(); i<N; i++) {
16265            ProcessMemInfo mi = memInfos.get(i);
16266            infoMap.put(mi.pid, mi);
16267        }
16268        updateCpuStatsNow();
16269        long[] memtrackTmp = new long[1];
16270        synchronized (mProcessCpuTracker) {
16271            final int N = mProcessCpuTracker.countStats();
16272            for (int i=0; i<N; i++) {
16273                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16274                if (st.vsize > 0) {
16275                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16276                    if (pss > 0) {
16277                        if (infoMap.indexOfKey(st.pid) < 0) {
16278                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16279                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16280                            mi.pss = pss;
16281                            mi.memtrack = memtrackTmp[0];
16282                            memInfos.add(mi);
16283                        }
16284                    }
16285                }
16286            }
16287        }
16288
16289        long totalPss = 0;
16290        long totalMemtrack = 0;
16291        for (int i=0, N=memInfos.size(); i<N; i++) {
16292            ProcessMemInfo mi = memInfos.get(i);
16293            if (mi.pss == 0) {
16294                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16295                mi.memtrack = memtrackTmp[0];
16296            }
16297            totalPss += mi.pss;
16298            totalMemtrack += mi.memtrack;
16299        }
16300        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16301            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16302                if (lhs.oomAdj != rhs.oomAdj) {
16303                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16304                }
16305                if (lhs.pss != rhs.pss) {
16306                    return lhs.pss < rhs.pss ? 1 : -1;
16307                }
16308                return 0;
16309            }
16310        });
16311
16312        StringBuilder tag = new StringBuilder(128);
16313        StringBuilder stack = new StringBuilder(128);
16314        tag.append("Low on memory -- ");
16315        appendMemBucket(tag, totalPss, "total", false);
16316        appendMemBucket(stack, totalPss, "total", true);
16317
16318        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16319        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16320        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16321
16322        boolean firstLine = true;
16323        int lastOomAdj = Integer.MIN_VALUE;
16324        long extraNativeRam = 0;
16325        long extraNativeMemtrack = 0;
16326        long cachedPss = 0;
16327        for (int i=0, N=memInfos.size(); i<N; i++) {
16328            ProcessMemInfo mi = memInfos.get(i);
16329
16330            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16331                cachedPss += mi.pss;
16332            }
16333
16334            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16335                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16336                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16337                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16338                if (lastOomAdj != mi.oomAdj) {
16339                    lastOomAdj = mi.oomAdj;
16340                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16341                        tag.append(" / ");
16342                    }
16343                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16344                        if (firstLine) {
16345                            stack.append(":");
16346                            firstLine = false;
16347                        }
16348                        stack.append("\n\t at ");
16349                    } else {
16350                        stack.append("$");
16351                    }
16352                } else {
16353                    tag.append(" ");
16354                    stack.append("$");
16355                }
16356                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16357                    appendMemBucket(tag, mi.pss, mi.name, false);
16358                }
16359                appendMemBucket(stack, mi.pss, mi.name, true);
16360                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16361                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16362                    stack.append("(");
16363                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16364                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16365                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16366                            stack.append(":");
16367                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16368                        }
16369                    }
16370                    stack.append(")");
16371                }
16372            }
16373
16374            appendMemInfo(fullNativeBuilder, mi);
16375            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16376                // The short form only has native processes that are >= 512K.
16377                if (mi.pss >= 512) {
16378                    appendMemInfo(shortNativeBuilder, mi);
16379                } else {
16380                    extraNativeRam += mi.pss;
16381                    extraNativeMemtrack += mi.memtrack;
16382                }
16383            } else {
16384                // Short form has all other details, but if we have collected RAM
16385                // from smaller native processes let's dump a summary of that.
16386                if (extraNativeRam > 0) {
16387                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16388                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16389                    shortNativeBuilder.append('\n');
16390                    extraNativeRam = 0;
16391                }
16392                appendMemInfo(fullJavaBuilder, mi);
16393            }
16394        }
16395
16396        fullJavaBuilder.append("           ");
16397        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16398        fullJavaBuilder.append(": TOTAL");
16399        if (totalMemtrack > 0) {
16400            fullJavaBuilder.append(" (");
16401            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16402            fullJavaBuilder.append(" memtrack)");
16403        } else {
16404        }
16405        fullJavaBuilder.append("\n");
16406
16407        MemInfoReader memInfo = new MemInfoReader();
16408        memInfo.readMemInfo();
16409        final long[] infos = memInfo.getRawInfo();
16410
16411        StringBuilder memInfoBuilder = new StringBuilder(1024);
16412        Debug.getMemInfo(infos);
16413        memInfoBuilder.append("  MemInfo: ");
16414        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16415        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16416        memInfoBuilder.append(stringifyKBSize(
16417                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16418        memInfoBuilder.append(stringifyKBSize(
16419                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16420        memInfoBuilder.append(stringifyKBSize(
16421                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16422        memInfoBuilder.append("           ");
16423        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16424        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16425        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16426        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16427        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16428            memInfoBuilder.append("  ZRAM: ");
16429            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16430            memInfoBuilder.append(" RAM, ");
16431            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16432            memInfoBuilder.append(" swap total, ");
16433            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16434            memInfoBuilder.append(" swap free\n");
16435        }
16436        final long[] ksm = getKsmInfo();
16437        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16438                || ksm[KSM_VOLATILE] != 0) {
16439            memInfoBuilder.append("  KSM: ");
16440            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16441            memInfoBuilder.append(" saved from shared ");
16442            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16443            memInfoBuilder.append("\n       ");
16444            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16445            memInfoBuilder.append(" unshared; ");
16446            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16447            memInfoBuilder.append(" volatile\n");
16448        }
16449        memInfoBuilder.append("  Free RAM: ");
16450        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16451                + memInfo.getFreeSizeKb()));
16452        memInfoBuilder.append("\n");
16453        memInfoBuilder.append("  Used RAM: ");
16454        memInfoBuilder.append(stringifyKBSize(
16455                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16456        memInfoBuilder.append("\n");
16457        memInfoBuilder.append("  Lost RAM: ");
16458        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16459                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16460                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16461        memInfoBuilder.append("\n");
16462        Slog.i(TAG, "Low on memory:");
16463        Slog.i(TAG, shortNativeBuilder.toString());
16464        Slog.i(TAG, fullJavaBuilder.toString());
16465        Slog.i(TAG, memInfoBuilder.toString());
16466
16467        StringBuilder dropBuilder = new StringBuilder(1024);
16468        /*
16469        StringWriter oomSw = new StringWriter();
16470        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16471        StringWriter catSw = new StringWriter();
16472        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16473        String[] emptyArgs = new String[] { };
16474        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16475        oomPw.flush();
16476        String oomString = oomSw.toString();
16477        */
16478        dropBuilder.append("Low on memory:");
16479        dropBuilder.append(stack);
16480        dropBuilder.append('\n');
16481        dropBuilder.append(fullNativeBuilder);
16482        dropBuilder.append(fullJavaBuilder);
16483        dropBuilder.append('\n');
16484        dropBuilder.append(memInfoBuilder);
16485        dropBuilder.append('\n');
16486        /*
16487        dropBuilder.append(oomString);
16488        dropBuilder.append('\n');
16489        */
16490        StringWriter catSw = new StringWriter();
16491        synchronized (ActivityManagerService.this) {
16492            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16493            String[] emptyArgs = new String[] { };
16494            catPw.println();
16495            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16496            catPw.println();
16497            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16498                    false, null).dumpLocked();
16499            catPw.println();
16500            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16501            catPw.flush();
16502        }
16503        dropBuilder.append(catSw.toString());
16504        addErrorToDropBox("lowmem", null, "system_server", null,
16505                null, tag.toString(), dropBuilder.toString(), null, null);
16506        //Slog.i(TAG, "Sent to dropbox:");
16507        //Slog.i(TAG, dropBuilder.toString());
16508        synchronized (ActivityManagerService.this) {
16509            long now = SystemClock.uptimeMillis();
16510            if (mLastMemUsageReportTime < now) {
16511                mLastMemUsageReportTime = now;
16512            }
16513        }
16514    }
16515
16516    /**
16517     * Searches array of arguments for the specified string
16518     * @param args array of argument strings
16519     * @param value value to search for
16520     * @return true if the value is contained in the array
16521     */
16522    private static boolean scanArgs(String[] args, String value) {
16523        if (args != null) {
16524            for (String arg : args) {
16525                if (value.equals(arg)) {
16526                    return true;
16527                }
16528            }
16529        }
16530        return false;
16531    }
16532
16533    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16534            ContentProviderRecord cpr, boolean always) {
16535        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16536
16537        if (!inLaunching || always) {
16538            synchronized (cpr) {
16539                cpr.launchingApp = null;
16540                cpr.notifyAll();
16541            }
16542            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16543            String names[] = cpr.info.authority.split(";");
16544            for (int j = 0; j < names.length; j++) {
16545                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16546            }
16547        }
16548
16549        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16550            ContentProviderConnection conn = cpr.connections.get(i);
16551            if (conn.waiting) {
16552                // If this connection is waiting for the provider, then we don't
16553                // need to mess with its process unless we are always removing
16554                // or for some reason the provider is not currently launching.
16555                if (inLaunching && !always) {
16556                    continue;
16557                }
16558            }
16559            ProcessRecord capp = conn.client;
16560            conn.dead = true;
16561            if (conn.stableCount > 0) {
16562                if (!capp.persistent && capp.thread != null
16563                        && capp.pid != 0
16564                        && capp.pid != MY_PID) {
16565                    capp.kill("depends on provider "
16566                            + cpr.name.flattenToShortString()
16567                            + " in dying proc " + (proc != null ? proc.processName : "??")
16568                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16569                }
16570            } else if (capp.thread != null && conn.provider.provider != null) {
16571                try {
16572                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16573                } catch (RemoteException e) {
16574                }
16575                // In the protocol here, we don't expect the client to correctly
16576                // clean up this connection, we'll just remove it.
16577                cpr.connections.remove(i);
16578                if (conn.client.conProviders.remove(conn)) {
16579                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16580                }
16581            }
16582        }
16583
16584        if (inLaunching && always) {
16585            mLaunchingProviders.remove(cpr);
16586        }
16587        return inLaunching;
16588    }
16589
16590    /**
16591     * Main code for cleaning up a process when it has gone away.  This is
16592     * called both as a result of the process dying, or directly when stopping
16593     * a process when running in single process mode.
16594     *
16595     * @return Returns true if the given process has been restarted, so the
16596     * app that was passed in must remain on the process lists.
16597     */
16598    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16599            boolean restarting, boolean allowRestart, int index) {
16600        if (index >= 0) {
16601            removeLruProcessLocked(app);
16602            ProcessList.remove(app.pid);
16603        }
16604
16605        mProcessesToGc.remove(app);
16606        mPendingPssProcesses.remove(app);
16607
16608        // Dismiss any open dialogs.
16609        if (app.crashDialog != null && !app.forceCrashReport) {
16610            app.crashDialog.dismiss();
16611            app.crashDialog = null;
16612        }
16613        if (app.anrDialog != null) {
16614            app.anrDialog.dismiss();
16615            app.anrDialog = null;
16616        }
16617        if (app.waitDialog != null) {
16618            app.waitDialog.dismiss();
16619            app.waitDialog = null;
16620        }
16621
16622        app.crashing = false;
16623        app.notResponding = false;
16624
16625        app.resetPackageList(mProcessStats);
16626        app.unlinkDeathRecipient();
16627        app.makeInactive(mProcessStats);
16628        app.waitingToKill = null;
16629        app.forcingToForeground = null;
16630        updateProcessForegroundLocked(app, false, false);
16631        app.foregroundActivities = false;
16632        app.hasShownUi = false;
16633        app.treatLikeActivity = false;
16634        app.hasAboveClient = false;
16635        app.hasClientActivities = false;
16636
16637        mServices.killServicesLocked(app, allowRestart);
16638
16639        boolean restart = false;
16640
16641        // Remove published content providers.
16642        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16643            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16644            final boolean always = app.bad || !allowRestart;
16645            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16646            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16647                // We left the provider in the launching list, need to
16648                // restart it.
16649                restart = true;
16650            }
16651
16652            cpr.provider = null;
16653            cpr.proc = null;
16654        }
16655        app.pubProviders.clear();
16656
16657        // Take care of any launching providers waiting for this process.
16658        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16659            restart = true;
16660        }
16661
16662        // Unregister from connected content providers.
16663        if (!app.conProviders.isEmpty()) {
16664            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16665                ContentProviderConnection conn = app.conProviders.get(i);
16666                conn.provider.connections.remove(conn);
16667                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16668                        conn.provider.name);
16669            }
16670            app.conProviders.clear();
16671        }
16672
16673        // At this point there may be remaining entries in mLaunchingProviders
16674        // where we were the only one waiting, so they are no longer of use.
16675        // Look for these and clean up if found.
16676        // XXX Commented out for now.  Trying to figure out a way to reproduce
16677        // the actual situation to identify what is actually going on.
16678        if (false) {
16679            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16680                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16681                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16682                    synchronized (cpr) {
16683                        cpr.launchingApp = null;
16684                        cpr.notifyAll();
16685                    }
16686                }
16687            }
16688        }
16689
16690        skipCurrentReceiverLocked(app);
16691
16692        // Unregister any receivers.
16693        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16694            removeReceiverLocked(app.receivers.valueAt(i));
16695        }
16696        app.receivers.clear();
16697
16698        // If the app is undergoing backup, tell the backup manager about it
16699        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16700            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16701                    + mBackupTarget.appInfo + " died during backup");
16702            try {
16703                IBackupManager bm = IBackupManager.Stub.asInterface(
16704                        ServiceManager.getService(Context.BACKUP_SERVICE));
16705                bm.agentDisconnected(app.info.packageName);
16706            } catch (RemoteException e) {
16707                // can't happen; backup manager is local
16708            }
16709        }
16710
16711        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16712            ProcessChangeItem item = mPendingProcessChanges.get(i);
16713            if (item.pid == app.pid) {
16714                mPendingProcessChanges.remove(i);
16715                mAvailProcessChanges.add(item);
16716            }
16717        }
16718        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16719                null).sendToTarget();
16720
16721        // If the caller is restarting this app, then leave it in its
16722        // current lists and let the caller take care of it.
16723        if (restarting) {
16724            return false;
16725        }
16726
16727        if (!app.persistent || app.isolated) {
16728            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16729                    "Removing non-persistent process during cleanup: " + app);
16730            removeProcessNameLocked(app.processName, app.uid);
16731            if (mHeavyWeightProcess == app) {
16732                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16733                        mHeavyWeightProcess.userId, 0));
16734                mHeavyWeightProcess = null;
16735            }
16736        } else if (!app.removed) {
16737            // This app is persistent, so we need to keep its record around.
16738            // If it is not already on the pending app list, add it there
16739            // and start a new process for it.
16740            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16741                mPersistentStartingProcesses.add(app);
16742                restart = true;
16743            }
16744        }
16745        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16746                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16747        mProcessesOnHold.remove(app);
16748
16749        if (app == mHomeProcess) {
16750            mHomeProcess = null;
16751        }
16752        if (app == mPreviousProcess) {
16753            mPreviousProcess = null;
16754        }
16755
16756        if (restart && !app.isolated) {
16757            // We have components that still need to be running in the
16758            // process, so re-launch it.
16759            if (index < 0) {
16760                ProcessList.remove(app.pid);
16761            }
16762            addProcessNameLocked(app);
16763            startProcessLocked(app, "restart", app.processName);
16764            return true;
16765        } else if (app.pid > 0 && app.pid != MY_PID) {
16766            // Goodbye!
16767            boolean removed;
16768            synchronized (mPidsSelfLocked) {
16769                mPidsSelfLocked.remove(app.pid);
16770                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16771            }
16772            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16773            if (app.isolated) {
16774                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16775            }
16776            app.setPid(0);
16777        }
16778        return false;
16779    }
16780
16781    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16782        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16783            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16784            if (cpr.launchingApp == app) {
16785                return true;
16786            }
16787        }
16788        return false;
16789    }
16790
16791    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16792        // Look through the content providers we are waiting to have launched,
16793        // and if any run in this process then either schedule a restart of
16794        // the process or kill the client waiting for it if this process has
16795        // gone bad.
16796        boolean restart = false;
16797        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16798            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16799            if (cpr.launchingApp == app) {
16800                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16801                    restart = true;
16802                } else {
16803                    removeDyingProviderLocked(app, cpr, true);
16804                }
16805            }
16806        }
16807        return restart;
16808    }
16809
16810    // =========================================================
16811    // SERVICES
16812    // =========================================================
16813
16814    @Override
16815    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16816            int flags) {
16817        enforceNotIsolatedCaller("getServices");
16818        synchronized (this) {
16819            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16820        }
16821    }
16822
16823    @Override
16824    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16825        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16826        synchronized (this) {
16827            return mServices.getRunningServiceControlPanelLocked(name);
16828        }
16829    }
16830
16831    @Override
16832    public ComponentName startService(IApplicationThread caller, Intent service,
16833            String resolvedType, String callingPackage, int userId)
16834            throws TransactionTooLargeException {
16835        enforceNotIsolatedCaller("startService");
16836        // Refuse possible leaked file descriptors
16837        if (service != null && service.hasFileDescriptors() == true) {
16838            throw new IllegalArgumentException("File descriptors passed in Intent");
16839        }
16840
16841        if (callingPackage == null) {
16842            throw new IllegalArgumentException("callingPackage cannot be null");
16843        }
16844
16845        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16846                "startService: " + service + " type=" + resolvedType);
16847        synchronized(this) {
16848            final int callingPid = Binder.getCallingPid();
16849            final int callingUid = Binder.getCallingUid();
16850            final long origId = Binder.clearCallingIdentity();
16851            ComponentName res = mServices.startServiceLocked(caller, service,
16852                    resolvedType, callingPid, callingUid, callingPackage, userId);
16853            Binder.restoreCallingIdentity(origId);
16854            return res;
16855        }
16856    }
16857
16858    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16859            String callingPackage, int userId)
16860            throws TransactionTooLargeException {
16861        synchronized(this) {
16862            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16863                    "startServiceInPackage: " + service + " type=" + resolvedType);
16864            final long origId = Binder.clearCallingIdentity();
16865            ComponentName res = mServices.startServiceLocked(null, service,
16866                    resolvedType, -1, uid, callingPackage, userId);
16867            Binder.restoreCallingIdentity(origId);
16868            return res;
16869        }
16870    }
16871
16872    @Override
16873    public int stopService(IApplicationThread caller, Intent service,
16874            String resolvedType, int userId) {
16875        enforceNotIsolatedCaller("stopService");
16876        // Refuse possible leaked file descriptors
16877        if (service != null && service.hasFileDescriptors() == true) {
16878            throw new IllegalArgumentException("File descriptors passed in Intent");
16879        }
16880
16881        synchronized(this) {
16882            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16883        }
16884    }
16885
16886    @Override
16887    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16888        enforceNotIsolatedCaller("peekService");
16889        // Refuse possible leaked file descriptors
16890        if (service != null && service.hasFileDescriptors() == true) {
16891            throw new IllegalArgumentException("File descriptors passed in Intent");
16892        }
16893
16894        if (callingPackage == null) {
16895            throw new IllegalArgumentException("callingPackage cannot be null");
16896        }
16897
16898        synchronized(this) {
16899            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16900        }
16901    }
16902
16903    @Override
16904    public boolean stopServiceToken(ComponentName className, IBinder token,
16905            int startId) {
16906        synchronized(this) {
16907            return mServices.stopServiceTokenLocked(className, token, startId);
16908        }
16909    }
16910
16911    @Override
16912    public void setServiceForeground(ComponentName className, IBinder token,
16913            int id, Notification notification, int flags) {
16914        synchronized(this) {
16915            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16916        }
16917    }
16918
16919    @Override
16920    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16921            boolean requireFull, String name, String callerPackage) {
16922        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16923                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16924    }
16925
16926    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16927            String className, int flags) {
16928        boolean result = false;
16929        // For apps that don't have pre-defined UIDs, check for permission
16930        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16931            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16932                if (ActivityManager.checkUidPermission(
16933                        INTERACT_ACROSS_USERS,
16934                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16935                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16936                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16937                            + " requests FLAG_SINGLE_USER, but app does not hold "
16938                            + INTERACT_ACROSS_USERS;
16939                    Slog.w(TAG, msg);
16940                    throw new SecurityException(msg);
16941                }
16942                // Permission passed
16943                result = true;
16944            }
16945        } else if ("system".equals(componentProcessName)) {
16946            result = true;
16947        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16948            // Phone app and persistent apps are allowed to export singleuser providers.
16949            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16950                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16951        }
16952        if (DEBUG_MU) Slog.v(TAG_MU,
16953                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16954                + Integer.toHexString(flags) + ") = " + result);
16955        return result;
16956    }
16957
16958    /**
16959     * Checks to see if the caller is in the same app as the singleton
16960     * component, or the component is in a special app. It allows special apps
16961     * to export singleton components but prevents exporting singleton
16962     * components for regular apps.
16963     */
16964    boolean isValidSingletonCall(int callingUid, int componentUid) {
16965        int componentAppId = UserHandle.getAppId(componentUid);
16966        return UserHandle.isSameApp(callingUid, componentUid)
16967                || componentAppId == Process.SYSTEM_UID
16968                || componentAppId == Process.PHONE_UID
16969                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16970                        == PackageManager.PERMISSION_GRANTED;
16971    }
16972
16973    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16974            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16975            int userId) throws TransactionTooLargeException {
16976        enforceNotIsolatedCaller("bindService");
16977
16978        // Refuse possible leaked file descriptors
16979        if (service != null && service.hasFileDescriptors() == true) {
16980            throw new IllegalArgumentException("File descriptors passed in Intent");
16981        }
16982
16983        if (callingPackage == null) {
16984            throw new IllegalArgumentException("callingPackage cannot be null");
16985        }
16986
16987        synchronized(this) {
16988            return mServices.bindServiceLocked(caller, token, service,
16989                    resolvedType, connection, flags, callingPackage, userId);
16990        }
16991    }
16992
16993    public boolean unbindService(IServiceConnection connection) {
16994        synchronized (this) {
16995            return mServices.unbindServiceLocked(connection);
16996        }
16997    }
16998
16999    public void publishService(IBinder token, Intent intent, IBinder service) {
17000        // Refuse possible leaked file descriptors
17001        if (intent != null && intent.hasFileDescriptors() == true) {
17002            throw new IllegalArgumentException("File descriptors passed in Intent");
17003        }
17004
17005        synchronized(this) {
17006            if (!(token instanceof ServiceRecord)) {
17007                throw new IllegalArgumentException("Invalid service token");
17008            }
17009            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17010        }
17011    }
17012
17013    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17014        // Refuse possible leaked file descriptors
17015        if (intent != null && intent.hasFileDescriptors() == true) {
17016            throw new IllegalArgumentException("File descriptors passed in Intent");
17017        }
17018
17019        synchronized(this) {
17020            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17021        }
17022    }
17023
17024    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17025        synchronized(this) {
17026            if (!(token instanceof ServiceRecord)) {
17027                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17028                throw new IllegalArgumentException("Invalid service token");
17029            }
17030            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17031        }
17032    }
17033
17034    // =========================================================
17035    // BACKUP AND RESTORE
17036    // =========================================================
17037
17038    // Cause the target app to be launched if necessary and its backup agent
17039    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17040    // activity manager to announce its creation.
17041    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17042        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17043                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17044        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17045
17046        synchronized(this) {
17047            // !!! TODO: currently no check here that we're already bound
17048            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17049            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17050            synchronized (stats) {
17051                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17052            }
17053
17054            // Backup agent is now in use, its package can't be stopped.
17055            try {
17056                AppGlobals.getPackageManager().setPackageStoppedState(
17057                        app.packageName, false, UserHandle.getUserId(app.uid));
17058            } catch (RemoteException e) {
17059            } catch (IllegalArgumentException e) {
17060                Slog.w(TAG, "Failed trying to unstop package "
17061                        + app.packageName + ": " + e);
17062            }
17063
17064            BackupRecord r = new BackupRecord(ss, app, backupMode);
17065            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17066                    ? new ComponentName(app.packageName, app.backupAgentName)
17067                    : new ComponentName("android", "FullBackupAgent");
17068            // startProcessLocked() returns existing proc's record if it's already running
17069            ProcessRecord proc = startProcessLocked(app.processName, app,
17070                    false, 0, "backup", hostingName, false, false, false);
17071            if (proc == null) {
17072                Slog.e(TAG, "Unable to start backup agent process " + r);
17073                return false;
17074            }
17075
17076            // If the app is a regular app (uid >= 10000) and not the system server or phone
17077            // process, etc, then mark it as being in full backup so that certain calls to the
17078            // process can be blocked. This is not reset to false anywhere because we kill the
17079            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17080            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17081                proc.inFullBackup = true;
17082            }
17083            r.app = proc;
17084            mBackupTarget = r;
17085            mBackupAppName = app.packageName;
17086
17087            // Try not to kill the process during backup
17088            updateOomAdjLocked(proc);
17089
17090            // If the process is already attached, schedule the creation of the backup agent now.
17091            // If it is not yet live, this will be done when it attaches to the framework.
17092            if (proc.thread != null) {
17093                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17094                try {
17095                    proc.thread.scheduleCreateBackupAgent(app,
17096                            compatibilityInfoForPackageLocked(app), backupMode);
17097                } catch (RemoteException e) {
17098                    // Will time out on the backup manager side
17099                }
17100            } else {
17101                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17102            }
17103            // Invariants: at this point, the target app process exists and the application
17104            // is either already running or in the process of coming up.  mBackupTarget and
17105            // mBackupAppName describe the app, so that when it binds back to the AM we
17106            // know that it's scheduled for a backup-agent operation.
17107        }
17108
17109        return true;
17110    }
17111
17112    @Override
17113    public void clearPendingBackup() {
17114        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17115        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17116
17117        synchronized (this) {
17118            mBackupTarget = null;
17119            mBackupAppName = null;
17120        }
17121    }
17122
17123    // A backup agent has just come up
17124    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17125        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17126                + " = " + agent);
17127
17128        synchronized(this) {
17129            if (!agentPackageName.equals(mBackupAppName)) {
17130                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17131                return;
17132            }
17133        }
17134
17135        long oldIdent = Binder.clearCallingIdentity();
17136        try {
17137            IBackupManager bm = IBackupManager.Stub.asInterface(
17138                    ServiceManager.getService(Context.BACKUP_SERVICE));
17139            bm.agentConnected(agentPackageName, agent);
17140        } catch (RemoteException e) {
17141            // can't happen; the backup manager service is local
17142        } catch (Exception e) {
17143            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17144            e.printStackTrace();
17145        } finally {
17146            Binder.restoreCallingIdentity(oldIdent);
17147        }
17148    }
17149
17150    // done with this agent
17151    public void unbindBackupAgent(ApplicationInfo appInfo) {
17152        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17153        if (appInfo == null) {
17154            Slog.w(TAG, "unbind backup agent for null app");
17155            return;
17156        }
17157
17158        synchronized(this) {
17159            try {
17160                if (mBackupAppName == null) {
17161                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17162                    return;
17163                }
17164
17165                if (!mBackupAppName.equals(appInfo.packageName)) {
17166                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17167                    return;
17168                }
17169
17170                // Not backing this app up any more; reset its OOM adjustment
17171                final ProcessRecord proc = mBackupTarget.app;
17172                updateOomAdjLocked(proc);
17173
17174                // If the app crashed during backup, 'thread' will be null here
17175                if (proc.thread != null) {
17176                    try {
17177                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17178                                compatibilityInfoForPackageLocked(appInfo));
17179                    } catch (Exception e) {
17180                        Slog.e(TAG, "Exception when unbinding backup agent:");
17181                        e.printStackTrace();
17182                    }
17183                }
17184            } finally {
17185                mBackupTarget = null;
17186                mBackupAppName = null;
17187            }
17188        }
17189    }
17190    // =========================================================
17191    // BROADCASTS
17192    // =========================================================
17193
17194    boolean isPendingBroadcastProcessLocked(int pid) {
17195        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17196                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17197    }
17198
17199    void skipPendingBroadcastLocked(int pid) {
17200            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17201            for (BroadcastQueue queue : mBroadcastQueues) {
17202                queue.skipPendingBroadcastLocked(pid);
17203            }
17204    }
17205
17206    // The app just attached; send any pending broadcasts that it should receive
17207    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17208        boolean didSomething = false;
17209        for (BroadcastQueue queue : mBroadcastQueues) {
17210            didSomething |= queue.sendPendingBroadcastsLocked(app);
17211        }
17212        return didSomething;
17213    }
17214
17215    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17216            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17217        enforceNotIsolatedCaller("registerReceiver");
17218        ArrayList<Intent> stickyIntents = null;
17219        ProcessRecord callerApp = null;
17220        int callingUid;
17221        int callingPid;
17222        synchronized(this) {
17223            if (caller != null) {
17224                callerApp = getRecordForAppLocked(caller);
17225                if (callerApp == null) {
17226                    throw new SecurityException(
17227                            "Unable to find app for caller " + caller
17228                            + " (pid=" + Binder.getCallingPid()
17229                            + ") when registering receiver " + receiver);
17230                }
17231                if (callerApp.info.uid != Process.SYSTEM_UID &&
17232                        !callerApp.pkgList.containsKey(callerPackage) &&
17233                        !"android".equals(callerPackage)) {
17234                    throw new SecurityException("Given caller package " + callerPackage
17235                            + " is not running in process " + callerApp);
17236                }
17237                callingUid = callerApp.info.uid;
17238                callingPid = callerApp.pid;
17239            } else {
17240                callerPackage = null;
17241                callingUid = Binder.getCallingUid();
17242                callingPid = Binder.getCallingPid();
17243            }
17244
17245            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17246                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17247
17248            Iterator<String> actions = filter.actionsIterator();
17249            if (actions == null) {
17250                ArrayList<String> noAction = new ArrayList<String>(1);
17251                noAction.add(null);
17252                actions = noAction.iterator();
17253            }
17254
17255            // Collect stickies of users
17256            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17257            while (actions.hasNext()) {
17258                String action = actions.next();
17259                for (int id : userIds) {
17260                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17261                    if (stickies != null) {
17262                        ArrayList<Intent> intents = stickies.get(action);
17263                        if (intents != null) {
17264                            if (stickyIntents == null) {
17265                                stickyIntents = new ArrayList<Intent>();
17266                            }
17267                            stickyIntents.addAll(intents);
17268                        }
17269                    }
17270                }
17271            }
17272        }
17273
17274        ArrayList<Intent> allSticky = null;
17275        if (stickyIntents != null) {
17276            final ContentResolver resolver = mContext.getContentResolver();
17277            // Look for any matching sticky broadcasts...
17278            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17279                Intent intent = stickyIntents.get(i);
17280                // If intent has scheme "content", it will need to acccess
17281                // provider that needs to lock mProviderMap in ActivityThread
17282                // and also it may need to wait application response, so we
17283                // cannot lock ActivityManagerService here.
17284                if (filter.match(resolver, intent, true, TAG) >= 0) {
17285                    if (allSticky == null) {
17286                        allSticky = new ArrayList<Intent>();
17287                    }
17288                    allSticky.add(intent);
17289                }
17290            }
17291        }
17292
17293        // The first sticky in the list is returned directly back to the client.
17294        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17295        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17296        if (receiver == null) {
17297            return sticky;
17298        }
17299
17300        synchronized (this) {
17301            if (callerApp != null && (callerApp.thread == null
17302                    || callerApp.thread.asBinder() != caller.asBinder())) {
17303                // Original caller already died
17304                return null;
17305            }
17306            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17307            if (rl == null) {
17308                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17309                        userId, receiver);
17310                if (rl.app != null) {
17311                    rl.app.receivers.add(rl);
17312                } else {
17313                    try {
17314                        receiver.asBinder().linkToDeath(rl, 0);
17315                    } catch (RemoteException e) {
17316                        return sticky;
17317                    }
17318                    rl.linkedToDeath = true;
17319                }
17320                mRegisteredReceivers.put(receiver.asBinder(), rl);
17321            } else if (rl.uid != callingUid) {
17322                throw new IllegalArgumentException(
17323                        "Receiver requested to register for uid " + callingUid
17324                        + " was previously registered for uid " + rl.uid);
17325            } else if (rl.pid != callingPid) {
17326                throw new IllegalArgumentException(
17327                        "Receiver requested to register for pid " + callingPid
17328                        + " was previously registered for pid " + rl.pid);
17329            } else if (rl.userId != userId) {
17330                throw new IllegalArgumentException(
17331                        "Receiver requested to register for user " + userId
17332                        + " was previously registered for user " + rl.userId);
17333            }
17334            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17335                    permission, callingUid, userId);
17336            rl.add(bf);
17337            if (!bf.debugCheck()) {
17338                Slog.w(TAG, "==> For Dynamic broadcast");
17339            }
17340            mReceiverResolver.addFilter(bf);
17341
17342            // Enqueue broadcasts for all existing stickies that match
17343            // this filter.
17344            if (allSticky != null) {
17345                ArrayList receivers = new ArrayList();
17346                receivers.add(bf);
17347
17348                final int stickyCount = allSticky.size();
17349                for (int i = 0; i < stickyCount; i++) {
17350                    Intent intent = allSticky.get(i);
17351                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17352                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17353                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17354                            null, 0, null, null, false, true, true, -1);
17355                    queue.enqueueParallelBroadcastLocked(r);
17356                    queue.scheduleBroadcastsLocked();
17357                }
17358            }
17359
17360            return sticky;
17361        }
17362    }
17363
17364    public void unregisterReceiver(IIntentReceiver receiver) {
17365        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17366
17367        final long origId = Binder.clearCallingIdentity();
17368        try {
17369            boolean doTrim = false;
17370
17371            synchronized(this) {
17372                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17373                if (rl != null) {
17374                    final BroadcastRecord r = rl.curBroadcast;
17375                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17376                        final boolean doNext = r.queue.finishReceiverLocked(
17377                                r, r.resultCode, r.resultData, r.resultExtras,
17378                                r.resultAbort, false);
17379                        if (doNext) {
17380                            doTrim = true;
17381                            r.queue.processNextBroadcast(false);
17382                        }
17383                    }
17384
17385                    if (rl.app != null) {
17386                        rl.app.receivers.remove(rl);
17387                    }
17388                    removeReceiverLocked(rl);
17389                    if (rl.linkedToDeath) {
17390                        rl.linkedToDeath = false;
17391                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17392                    }
17393                }
17394            }
17395
17396            // If we actually concluded any broadcasts, we might now be able
17397            // to trim the recipients' apps from our working set
17398            if (doTrim) {
17399                trimApplications();
17400                return;
17401            }
17402
17403        } finally {
17404            Binder.restoreCallingIdentity(origId);
17405        }
17406    }
17407
17408    void removeReceiverLocked(ReceiverList rl) {
17409        mRegisteredReceivers.remove(rl.receiver.asBinder());
17410        for (int i = rl.size() - 1; i >= 0; i--) {
17411            mReceiverResolver.removeFilter(rl.get(i));
17412        }
17413    }
17414
17415    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17416        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17417            ProcessRecord r = mLruProcesses.get(i);
17418            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17419                try {
17420                    r.thread.dispatchPackageBroadcast(cmd, packages);
17421                } catch (RemoteException ex) {
17422                }
17423            }
17424        }
17425    }
17426
17427    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17428            int callingUid, int[] users) {
17429        // TODO: come back and remove this assumption to triage all broadcasts
17430        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17431
17432        List<ResolveInfo> receivers = null;
17433        try {
17434            HashSet<ComponentName> singleUserReceivers = null;
17435            boolean scannedFirstReceivers = false;
17436            for (int user : users) {
17437                // Skip users that have Shell restrictions, with exception of always permitted
17438                // Shell broadcasts
17439                if (callingUid == Process.SHELL_UID
17440                        && mUserController.hasUserRestriction(
17441                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17442                        && !isPermittedShellBroadcast(intent)) {
17443                    continue;
17444                }
17445                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17446                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17447                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17448                    // If this is not the system user, we need to check for
17449                    // any receivers that should be filtered out.
17450                    for (int i=0; i<newReceivers.size(); i++) {
17451                        ResolveInfo ri = newReceivers.get(i);
17452                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17453                            newReceivers.remove(i);
17454                            i--;
17455                        }
17456                    }
17457                }
17458                if (newReceivers != null && newReceivers.size() == 0) {
17459                    newReceivers = null;
17460                }
17461                if (receivers == null) {
17462                    receivers = newReceivers;
17463                } else if (newReceivers != null) {
17464                    // We need to concatenate the additional receivers
17465                    // found with what we have do far.  This would be easy,
17466                    // but we also need to de-dup any receivers that are
17467                    // singleUser.
17468                    if (!scannedFirstReceivers) {
17469                        // Collect any single user receivers we had already retrieved.
17470                        scannedFirstReceivers = true;
17471                        for (int i=0; i<receivers.size(); i++) {
17472                            ResolveInfo ri = receivers.get(i);
17473                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17474                                ComponentName cn = new ComponentName(
17475                                        ri.activityInfo.packageName, ri.activityInfo.name);
17476                                if (singleUserReceivers == null) {
17477                                    singleUserReceivers = new HashSet<ComponentName>();
17478                                }
17479                                singleUserReceivers.add(cn);
17480                            }
17481                        }
17482                    }
17483                    // Add the new results to the existing results, tracking
17484                    // and de-dupping single user receivers.
17485                    for (int i=0; i<newReceivers.size(); i++) {
17486                        ResolveInfo ri = newReceivers.get(i);
17487                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17488                            ComponentName cn = new ComponentName(
17489                                    ri.activityInfo.packageName, ri.activityInfo.name);
17490                            if (singleUserReceivers == null) {
17491                                singleUserReceivers = new HashSet<ComponentName>();
17492                            }
17493                            if (!singleUserReceivers.contains(cn)) {
17494                                singleUserReceivers.add(cn);
17495                                receivers.add(ri);
17496                            }
17497                        } else {
17498                            receivers.add(ri);
17499                        }
17500                    }
17501                }
17502            }
17503        } catch (RemoteException ex) {
17504            // pm is in same process, this will never happen.
17505        }
17506        return receivers;
17507    }
17508
17509    private boolean isPermittedShellBroadcast(Intent intent) {
17510        // remote bugreport should always be allowed to be taken
17511        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17512    }
17513
17514    final int broadcastIntentLocked(ProcessRecord callerApp,
17515            String callerPackage, Intent intent, String resolvedType,
17516            IIntentReceiver resultTo, int resultCode, String resultData,
17517            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17518            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17519        intent = new Intent(intent);
17520
17521        // By default broadcasts do not go to stopped apps.
17522        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17523
17524        // If we have not finished booting, don't allow this to launch new processes.
17525        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17526            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17527        }
17528
17529        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17530                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17531                + " ordered=" + ordered + " userid=" + userId);
17532        if ((resultTo != null) && !ordered) {
17533            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17534        }
17535
17536        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17537                ALLOW_NON_FULL, "broadcast", callerPackage);
17538
17539        // Make sure that the user who is receiving this broadcast is running.
17540        // If not, we will just skip it. Make an exception for shutdown broadcasts
17541        // and upgrade steps.
17542
17543        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17544            if ((callingUid != Process.SYSTEM_UID
17545                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17546                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17547                Slog.w(TAG, "Skipping broadcast of " + intent
17548                        + ": user " + userId + " is stopped");
17549                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17550            }
17551        }
17552
17553        BroadcastOptions brOptions = null;
17554        if (bOptions != null) {
17555            brOptions = new BroadcastOptions(bOptions);
17556            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17557                // See if the caller is allowed to do this.  Note we are checking against
17558                // the actual real caller (not whoever provided the operation as say a
17559                // PendingIntent), because that who is actually supplied the arguments.
17560                if (checkComponentPermission(
17561                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17562                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17563                        != PackageManager.PERMISSION_GRANTED) {
17564                    String msg = "Permission Denial: " + intent.getAction()
17565                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17566                            + ", uid=" + callingUid + ")"
17567                            + " requires "
17568                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17569                    Slog.w(TAG, msg);
17570                    throw new SecurityException(msg);
17571                }
17572            }
17573        }
17574
17575        // Verify that protected broadcasts are only being sent by system code,
17576        // and that system code is only sending protected broadcasts.
17577        final String action = intent.getAction();
17578        final boolean isProtectedBroadcast;
17579        try {
17580            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17581        } catch (RemoteException e) {
17582            Slog.w(TAG, "Remote exception", e);
17583            return ActivityManager.BROADCAST_SUCCESS;
17584        }
17585
17586        final boolean isCallerSystem;
17587        switch (UserHandle.getAppId(callingUid)) {
17588            case Process.ROOT_UID:
17589            case Process.SYSTEM_UID:
17590            case Process.PHONE_UID:
17591            case Process.BLUETOOTH_UID:
17592            case Process.NFC_UID:
17593                isCallerSystem = true;
17594                break;
17595            default:
17596                isCallerSystem = (callerApp != null) && callerApp.persistent;
17597                break;
17598        }
17599
17600        if (isCallerSystem) {
17601            if (isProtectedBroadcast
17602                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17603                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17604                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17605                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17606                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17607                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17608                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17609                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17610                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17611                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17612                // Broadcast is either protected, or it's a public action that
17613                // we've relaxed, so it's fine for system internals to send.
17614            } else {
17615                // The vast majority of broadcasts sent from system internals
17616                // should be protected to avoid security holes, so yell loudly
17617                // to ensure we examine these cases.
17618                if (callerApp != null) {
17619                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17620                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17621                            new Throwable());
17622                } else {
17623                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17624                            + " from system uid " + UserHandle.formatUid(callingUid)
17625                            + " pkg " + callerPackage,
17626                            new Throwable());
17627                }
17628            }
17629
17630        } else {
17631            if (isProtectedBroadcast) {
17632                String msg = "Permission Denial: not allowed to send broadcast "
17633                        + action + " from pid="
17634                        + callingPid + ", uid=" + callingUid;
17635                Slog.w(TAG, msg);
17636                throw new SecurityException(msg);
17637
17638            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17639                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17640                // Special case for compatibility: we don't want apps to send this,
17641                // but historically it has not been protected and apps may be using it
17642                // to poke their own app widget.  So, instead of making it protected,
17643                // just limit it to the caller.
17644                if (callerPackage == null) {
17645                    String msg = "Permission Denial: not allowed to send broadcast "
17646                            + action + " from unknown caller.";
17647                    Slog.w(TAG, msg);
17648                    throw new SecurityException(msg);
17649                } else if (intent.getComponent() != null) {
17650                    // They are good enough to send to an explicit component...  verify
17651                    // it is being sent to the calling app.
17652                    if (!intent.getComponent().getPackageName().equals(
17653                            callerPackage)) {
17654                        String msg = "Permission Denial: not allowed to send broadcast "
17655                                + action + " to "
17656                                + intent.getComponent().getPackageName() + " from "
17657                                + callerPackage;
17658                        Slog.w(TAG, msg);
17659                        throw new SecurityException(msg);
17660                    }
17661                } else {
17662                    // Limit broadcast to their own package.
17663                    intent.setPackage(callerPackage);
17664                }
17665            }
17666        }
17667
17668        if (action != null) {
17669            switch (action) {
17670                case Intent.ACTION_UID_REMOVED:
17671                case Intent.ACTION_PACKAGE_REMOVED:
17672                case Intent.ACTION_PACKAGE_CHANGED:
17673                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17674                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17675                case Intent.ACTION_PACKAGES_SUSPENDED:
17676                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17677                    // Handle special intents: if this broadcast is from the package
17678                    // manager about a package being removed, we need to remove all of
17679                    // its activities from the history stack.
17680                    if (checkComponentPermission(
17681                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17682                            callingPid, callingUid, -1, true)
17683                            != PackageManager.PERMISSION_GRANTED) {
17684                        String msg = "Permission Denial: " + intent.getAction()
17685                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17686                                + ", uid=" + callingUid + ")"
17687                                + " requires "
17688                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17689                        Slog.w(TAG, msg);
17690                        throw new SecurityException(msg);
17691                    }
17692                    switch (action) {
17693                        case Intent.ACTION_UID_REMOVED:
17694                            final Bundle intentExtras = intent.getExtras();
17695                            final int uid = intentExtras != null
17696                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17697                            if (uid >= 0) {
17698                                mBatteryStatsService.removeUid(uid);
17699                                mAppOpsService.uidRemoved(uid);
17700                            }
17701                            break;
17702                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17703                            // If resources are unavailable just force stop all those packages
17704                            // and flush the attribute cache as well.
17705                            String list[] =
17706                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17707                            if (list != null && list.length > 0) {
17708                                for (int i = 0; i < list.length; i++) {
17709                                    forceStopPackageLocked(list[i], -1, false, true, true,
17710                                            false, false, userId, "storage unmount");
17711                                }
17712                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17713                                sendPackageBroadcastLocked(
17714                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17715                                        userId);
17716                            }
17717                            break;
17718                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17719                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17720                            break;
17721                        case Intent.ACTION_PACKAGE_REMOVED:
17722                        case Intent.ACTION_PACKAGE_CHANGED:
17723                            Uri data = intent.getData();
17724                            String ssp;
17725                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17726                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17727                                final boolean replacing =
17728                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17729                                final boolean killProcess =
17730                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17731                                final boolean fullUninstall = removed && !replacing;
17732                                if (removed) {
17733                                    if (killProcess) {
17734                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17735                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17736                                                false, true, true, false, fullUninstall, userId,
17737                                                removed ? "pkg removed" : "pkg changed");
17738                                    }
17739                                    final int cmd = killProcess
17740                                            ? IApplicationThread.PACKAGE_REMOVED
17741                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17742                                    sendPackageBroadcastLocked(cmd,
17743                                            new String[] {ssp}, userId);
17744                                    if (fullUninstall) {
17745                                        mAppOpsService.packageRemoved(
17746                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17747
17748                                        // Remove all permissions granted from/to this package
17749                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17750
17751                                        removeTasksByPackageNameLocked(ssp, userId);
17752                                        mBatteryStatsService.notePackageUninstalled(ssp);
17753                                    }
17754                                } else {
17755                                    if (killProcess) {
17756                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17757                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17758                                                userId, ProcessList.INVALID_ADJ,
17759                                                false, true, true, false, "change " + ssp);
17760                                    }
17761                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17762                                            intent.getStringArrayExtra(
17763                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17764                                }
17765                            }
17766                            break;
17767                        case Intent.ACTION_PACKAGES_SUSPENDED:
17768                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17769                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17770                                    intent.getAction());
17771                            final String[] packageNames = intent.getStringArrayExtra(
17772                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17773                            final int userHandle = intent.getIntExtra(
17774                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17775
17776                            synchronized(ActivityManagerService.this) {
17777                                mRecentTasks.onPackagesSuspendedChanged(
17778                                        packageNames, suspended, userHandle);
17779                            }
17780                            break;
17781                    }
17782                    break;
17783                case Intent.ACTION_PACKAGE_REPLACED:
17784                {
17785                    final Uri data = intent.getData();
17786                    final String ssp;
17787                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17788                        final ApplicationInfo aInfo =
17789                                getPackageManagerInternalLocked().getApplicationInfo(
17790                                        ssp,
17791                                        userId);
17792                        if (aInfo == null) {
17793                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17794                                    + " ssp=" + ssp + " data=" + data);
17795                            return ActivityManager.BROADCAST_SUCCESS;
17796                        }
17797                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17798                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17799                                new String[] {ssp}, userId);
17800                    }
17801                    break;
17802                }
17803                case Intent.ACTION_PACKAGE_ADDED:
17804                {
17805                    // Special case for adding a package: by default turn on compatibility mode.
17806                    Uri data = intent.getData();
17807                    String ssp;
17808                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17809                        final boolean replacing =
17810                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17811                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17812
17813                        try {
17814                            ApplicationInfo ai = AppGlobals.getPackageManager().
17815                                    getApplicationInfo(ssp, 0, 0);
17816                            mBatteryStatsService.notePackageInstalled(ssp,
17817                                    ai != null ? ai.versionCode : 0);
17818                        } catch (RemoteException e) {
17819                        }
17820                    }
17821                    break;
17822                }
17823                case Intent.ACTION_TIMEZONE_CHANGED:
17824                    // If this is the time zone changed action, queue up a message that will reset
17825                    // the timezone of all currently running processes. This message will get
17826                    // queued up before the broadcast happens.
17827                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17828                    break;
17829                case Intent.ACTION_TIME_CHANGED:
17830                    // If the user set the time, let all running processes know.
17831                    final int is24Hour =
17832                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17833                                    : 0;
17834                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17835                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17836                    synchronized (stats) {
17837                        stats.noteCurrentTimeChangedLocked();
17838                    }
17839                    break;
17840                case Intent.ACTION_CLEAR_DNS_CACHE:
17841                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17842                    break;
17843                case Proxy.PROXY_CHANGE_ACTION:
17844                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17845                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17846                    break;
17847                case android.hardware.Camera.ACTION_NEW_PICTURE:
17848                case android.hardware.Camera.ACTION_NEW_VIDEO:
17849                    // These broadcasts are no longer allowed by the system, since they can
17850                    // cause significant thrashing at a crictical point (using the camera).
17851                    // Apps should use JobScehduler to monitor for media provider changes.
17852                    Slog.w(TAG, action + " no longer allowed; dropping from "
17853                            + UserHandle.formatUid(callingUid));
17854                    // Lie; we don't want to crash the app.
17855                    return ActivityManager.BROADCAST_SUCCESS;
17856            }
17857        }
17858
17859        // Add to the sticky list if requested.
17860        if (sticky) {
17861            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17862                    callingPid, callingUid)
17863                    != PackageManager.PERMISSION_GRANTED) {
17864                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17865                        + callingPid + ", uid=" + callingUid
17866                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17867                Slog.w(TAG, msg);
17868                throw new SecurityException(msg);
17869            }
17870            if (requiredPermissions != null && requiredPermissions.length > 0) {
17871                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17872                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17873                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17874            }
17875            if (intent.getComponent() != null) {
17876                throw new SecurityException(
17877                        "Sticky broadcasts can't target a specific component");
17878            }
17879            // We use userId directly here, since the "all" target is maintained
17880            // as a separate set of sticky broadcasts.
17881            if (userId != UserHandle.USER_ALL) {
17882                // But first, if this is not a broadcast to all users, then
17883                // make sure it doesn't conflict with an existing broadcast to
17884                // all users.
17885                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17886                        UserHandle.USER_ALL);
17887                if (stickies != null) {
17888                    ArrayList<Intent> list = stickies.get(intent.getAction());
17889                    if (list != null) {
17890                        int N = list.size();
17891                        int i;
17892                        for (i=0; i<N; i++) {
17893                            if (intent.filterEquals(list.get(i))) {
17894                                throw new IllegalArgumentException(
17895                                        "Sticky broadcast " + intent + " for user "
17896                                        + userId + " conflicts with existing global broadcast");
17897                            }
17898                        }
17899                    }
17900                }
17901            }
17902            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17903            if (stickies == null) {
17904                stickies = new ArrayMap<>();
17905                mStickyBroadcasts.put(userId, stickies);
17906            }
17907            ArrayList<Intent> list = stickies.get(intent.getAction());
17908            if (list == null) {
17909                list = new ArrayList<>();
17910                stickies.put(intent.getAction(), list);
17911            }
17912            final int stickiesCount = list.size();
17913            int i;
17914            for (i = 0; i < stickiesCount; i++) {
17915                if (intent.filterEquals(list.get(i))) {
17916                    // This sticky already exists, replace it.
17917                    list.set(i, new Intent(intent));
17918                    break;
17919                }
17920            }
17921            if (i >= stickiesCount) {
17922                list.add(new Intent(intent));
17923            }
17924        }
17925
17926        int[] users;
17927        if (userId == UserHandle.USER_ALL) {
17928            // Caller wants broadcast to go to all started users.
17929            users = mUserController.getStartedUserArrayLocked();
17930        } else {
17931            // Caller wants broadcast to go to one specific user.
17932            users = new int[] {userId};
17933        }
17934
17935        // Figure out who all will receive this broadcast.
17936        List receivers = null;
17937        List<BroadcastFilter> registeredReceivers = null;
17938        // Need to resolve the intent to interested receivers...
17939        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17940                 == 0) {
17941            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17942        }
17943        if (intent.getComponent() == null) {
17944            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17945                // Query one target user at a time, excluding shell-restricted users
17946                for (int i = 0; i < users.length; i++) {
17947                    if (mUserController.hasUserRestriction(
17948                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17949                        continue;
17950                    }
17951                    List<BroadcastFilter> registeredReceiversForUser =
17952                            mReceiverResolver.queryIntent(intent,
17953                                    resolvedType, false, users[i]);
17954                    if (registeredReceivers == null) {
17955                        registeredReceivers = registeredReceiversForUser;
17956                    } else if (registeredReceiversForUser != null) {
17957                        registeredReceivers.addAll(registeredReceiversForUser);
17958                    }
17959                }
17960            } else {
17961                registeredReceivers = mReceiverResolver.queryIntent(intent,
17962                        resolvedType, false, userId);
17963            }
17964        }
17965
17966        final boolean replacePending =
17967                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17968
17969        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17970                + " replacePending=" + replacePending);
17971
17972        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17973        if (!ordered && NR > 0) {
17974            // If we are not serializing this broadcast, then send the
17975            // registered receivers separately so they don't wait for the
17976            // components to be launched.
17977            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17978            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17979                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17980                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17981                    resultExtras, ordered, sticky, false, userId);
17982            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17983            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17984            if (!replaced) {
17985                queue.enqueueParallelBroadcastLocked(r);
17986                queue.scheduleBroadcastsLocked();
17987            }
17988            registeredReceivers = null;
17989            NR = 0;
17990        }
17991
17992        // Merge into one list.
17993        int ir = 0;
17994        if (receivers != null) {
17995            // A special case for PACKAGE_ADDED: do not allow the package
17996            // being added to see this broadcast.  This prevents them from
17997            // using this as a back door to get run as soon as they are
17998            // installed.  Maybe in the future we want to have a special install
17999            // broadcast or such for apps, but we'd like to deliberately make
18000            // this decision.
18001            String skipPackages[] = null;
18002            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18003                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18004                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18005                Uri data = intent.getData();
18006                if (data != null) {
18007                    String pkgName = data.getSchemeSpecificPart();
18008                    if (pkgName != null) {
18009                        skipPackages = new String[] { pkgName };
18010                    }
18011                }
18012            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18013                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18014            }
18015            if (skipPackages != null && (skipPackages.length > 0)) {
18016                for (String skipPackage : skipPackages) {
18017                    if (skipPackage != null) {
18018                        int NT = receivers.size();
18019                        for (int it=0; it<NT; it++) {
18020                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18021                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18022                                receivers.remove(it);
18023                                it--;
18024                                NT--;
18025                            }
18026                        }
18027                    }
18028                }
18029            }
18030
18031            int NT = receivers != null ? receivers.size() : 0;
18032            int it = 0;
18033            ResolveInfo curt = null;
18034            BroadcastFilter curr = null;
18035            while (it < NT && ir < NR) {
18036                if (curt == null) {
18037                    curt = (ResolveInfo)receivers.get(it);
18038                }
18039                if (curr == null) {
18040                    curr = registeredReceivers.get(ir);
18041                }
18042                if (curr.getPriority() >= curt.priority) {
18043                    // Insert this broadcast record into the final list.
18044                    receivers.add(it, curr);
18045                    ir++;
18046                    curr = null;
18047                    it++;
18048                    NT++;
18049                } else {
18050                    // Skip to the next ResolveInfo in the final list.
18051                    it++;
18052                    curt = null;
18053                }
18054            }
18055        }
18056        while (ir < NR) {
18057            if (receivers == null) {
18058                receivers = new ArrayList();
18059            }
18060            receivers.add(registeredReceivers.get(ir));
18061            ir++;
18062        }
18063
18064        if ((receivers != null && receivers.size() > 0)
18065                || resultTo != null) {
18066            BroadcastQueue queue = broadcastQueueForIntent(intent);
18067            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18068                    callerPackage, callingPid, callingUid, resolvedType,
18069                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18070                    resultData, resultExtras, ordered, sticky, false, userId);
18071
18072            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18073                    + ": prev had " + queue.mOrderedBroadcasts.size());
18074            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18075                    "Enqueueing broadcast " + r.intent.getAction());
18076
18077            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18078            if (!replaced) {
18079                queue.enqueueOrderedBroadcastLocked(r);
18080                queue.scheduleBroadcastsLocked();
18081            }
18082        } else {
18083            // There was nobody interested in the broadcast, but we still want to record
18084            // that it happened.
18085            if (intent.getComponent() == null && intent.getPackage() == null
18086                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18087                // This was an implicit broadcast... let's record it for posterity.
18088                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18089            }
18090        }
18091
18092        return ActivityManager.BROADCAST_SUCCESS;
18093    }
18094
18095    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18096            int skipCount, long dispatchTime) {
18097        final long now = SystemClock.elapsedRealtime();
18098        if (mCurBroadcastStats == null ||
18099                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18100            mLastBroadcastStats = mCurBroadcastStats;
18101            if (mLastBroadcastStats != null) {
18102                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18103                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18104            }
18105            mCurBroadcastStats = new BroadcastStats();
18106        }
18107        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18108    }
18109
18110    final Intent verifyBroadcastLocked(Intent intent) {
18111        // Refuse possible leaked file descriptors
18112        if (intent != null && intent.hasFileDescriptors() == true) {
18113            throw new IllegalArgumentException("File descriptors passed in Intent");
18114        }
18115
18116        int flags = intent.getFlags();
18117
18118        if (!mProcessesReady) {
18119            // if the caller really truly claims to know what they're doing, go
18120            // ahead and allow the broadcast without launching any receivers
18121            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18122                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18123            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18124                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18125                        + " before boot completion");
18126                throw new IllegalStateException("Cannot broadcast before boot completed");
18127            }
18128        }
18129
18130        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18131            throw new IllegalArgumentException(
18132                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18133        }
18134
18135        return intent;
18136    }
18137
18138    public final int broadcastIntent(IApplicationThread caller,
18139            Intent intent, String resolvedType, IIntentReceiver resultTo,
18140            int resultCode, String resultData, Bundle resultExtras,
18141            String[] requiredPermissions, int appOp, Bundle bOptions,
18142            boolean serialized, boolean sticky, int userId) {
18143        enforceNotIsolatedCaller("broadcastIntent");
18144        synchronized(this) {
18145            intent = verifyBroadcastLocked(intent);
18146
18147            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18148            final int callingPid = Binder.getCallingPid();
18149            final int callingUid = Binder.getCallingUid();
18150            final long origId = Binder.clearCallingIdentity();
18151            int res = broadcastIntentLocked(callerApp,
18152                    callerApp != null ? callerApp.info.packageName : null,
18153                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18154                    requiredPermissions, appOp, bOptions, serialized, sticky,
18155                    callingPid, callingUid, userId);
18156            Binder.restoreCallingIdentity(origId);
18157            return res;
18158        }
18159    }
18160
18161
18162    int broadcastIntentInPackage(String packageName, int uid,
18163            Intent intent, String resolvedType, IIntentReceiver resultTo,
18164            int resultCode, String resultData, Bundle resultExtras,
18165            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18166            int userId) {
18167        synchronized(this) {
18168            intent = verifyBroadcastLocked(intent);
18169
18170            final long origId = Binder.clearCallingIdentity();
18171            String[] requiredPermissions = requiredPermission == null ? null
18172                    : new String[] {requiredPermission};
18173            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18174                    resultTo, resultCode, resultData, resultExtras,
18175                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18176                    sticky, -1, uid, userId);
18177            Binder.restoreCallingIdentity(origId);
18178            return res;
18179        }
18180    }
18181
18182    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18183        // Refuse possible leaked file descriptors
18184        if (intent != null && intent.hasFileDescriptors() == true) {
18185            throw new IllegalArgumentException("File descriptors passed in Intent");
18186        }
18187
18188        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18189                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18190
18191        synchronized(this) {
18192            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18193                    != PackageManager.PERMISSION_GRANTED) {
18194                String msg = "Permission Denial: unbroadcastIntent() from pid="
18195                        + Binder.getCallingPid()
18196                        + ", uid=" + Binder.getCallingUid()
18197                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18198                Slog.w(TAG, msg);
18199                throw new SecurityException(msg);
18200            }
18201            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18202            if (stickies != null) {
18203                ArrayList<Intent> list = stickies.get(intent.getAction());
18204                if (list != null) {
18205                    int N = list.size();
18206                    int i;
18207                    for (i=0; i<N; i++) {
18208                        if (intent.filterEquals(list.get(i))) {
18209                            list.remove(i);
18210                            break;
18211                        }
18212                    }
18213                    if (list.size() <= 0) {
18214                        stickies.remove(intent.getAction());
18215                    }
18216                }
18217                if (stickies.size() <= 0) {
18218                    mStickyBroadcasts.remove(userId);
18219                }
18220            }
18221        }
18222    }
18223
18224    void backgroundServicesFinishedLocked(int userId) {
18225        for (BroadcastQueue queue : mBroadcastQueues) {
18226            queue.backgroundServicesFinishedLocked(userId);
18227        }
18228    }
18229
18230    public void finishReceiver(IBinder who, int resultCode, String resultData,
18231            Bundle resultExtras, boolean resultAbort, int flags) {
18232        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18233
18234        // Refuse possible leaked file descriptors
18235        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18236            throw new IllegalArgumentException("File descriptors passed in Bundle");
18237        }
18238
18239        final long origId = Binder.clearCallingIdentity();
18240        try {
18241            boolean doNext = false;
18242            BroadcastRecord r;
18243
18244            synchronized(this) {
18245                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18246                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18247                r = queue.getMatchingOrderedReceiver(who);
18248                if (r != null) {
18249                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18250                        resultData, resultExtras, resultAbort, true);
18251                }
18252            }
18253
18254            if (doNext) {
18255                r.queue.processNextBroadcast(false);
18256            }
18257            trimApplications();
18258        } finally {
18259            Binder.restoreCallingIdentity(origId);
18260        }
18261    }
18262
18263    // =========================================================
18264    // INSTRUMENTATION
18265    // =========================================================
18266
18267    public boolean startInstrumentation(ComponentName className,
18268            String profileFile, int flags, Bundle arguments,
18269            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18270            int userId, String abiOverride) {
18271        enforceNotIsolatedCaller("startInstrumentation");
18272        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18273                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18274        // Refuse possible leaked file descriptors
18275        if (arguments != null && arguments.hasFileDescriptors()) {
18276            throw new IllegalArgumentException("File descriptors passed in Bundle");
18277        }
18278
18279        synchronized(this) {
18280            InstrumentationInfo ii = null;
18281            ApplicationInfo ai = null;
18282            try {
18283                ii = mContext.getPackageManager().getInstrumentationInfo(
18284                    className, STOCK_PM_FLAGS);
18285                ai = AppGlobals.getPackageManager().getApplicationInfo(
18286                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18287            } catch (PackageManager.NameNotFoundException e) {
18288            } catch (RemoteException e) {
18289            }
18290            if (ii == null) {
18291                reportStartInstrumentationFailureLocked(watcher, className,
18292                        "Unable to find instrumentation info for: " + className);
18293                return false;
18294            }
18295            if (ai == null) {
18296                reportStartInstrumentationFailureLocked(watcher, className,
18297                        "Unable to find instrumentation target package: " + ii.targetPackage);
18298                return false;
18299            }
18300            if (!ai.hasCode()) {
18301                reportStartInstrumentationFailureLocked(watcher, className,
18302                        "Instrumentation target has no code: " + ii.targetPackage);
18303                return false;
18304            }
18305
18306            int match = mContext.getPackageManager().checkSignatures(
18307                    ii.targetPackage, ii.packageName);
18308            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18309                String msg = "Permission Denial: starting instrumentation "
18310                        + className + " from pid="
18311                        + Binder.getCallingPid()
18312                        + ", uid=" + Binder.getCallingPid()
18313                        + " not allowed because package " + ii.packageName
18314                        + " does not have a signature matching the target "
18315                        + ii.targetPackage;
18316                reportStartInstrumentationFailureLocked(watcher, className, msg);
18317                throw new SecurityException(msg);
18318            }
18319
18320            final long origId = Binder.clearCallingIdentity();
18321            // Instrumentation can kill and relaunch even persistent processes
18322            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18323                    "start instr");
18324            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18325            app.instrumentationClass = className;
18326            app.instrumentationInfo = ai;
18327            app.instrumentationProfileFile = profileFile;
18328            app.instrumentationArguments = arguments;
18329            app.instrumentationWatcher = watcher;
18330            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18331            app.instrumentationResultClass = className;
18332            Binder.restoreCallingIdentity(origId);
18333        }
18334
18335        return true;
18336    }
18337
18338    /**
18339     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18340     * error to the logs, but if somebody is watching, send the report there too.  This enables
18341     * the "am" command to report errors with more information.
18342     *
18343     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18344     * @param cn The component name of the instrumentation.
18345     * @param report The error report.
18346     */
18347    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18348            ComponentName cn, String report) {
18349        Slog.w(TAG, report);
18350        if (watcher != null) {
18351            Bundle results = new Bundle();
18352            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18353            results.putString("Error", report);
18354            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18355        }
18356    }
18357
18358    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18359        if (app.instrumentationWatcher != null) {
18360            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18361                    app.instrumentationClass, resultCode, results);
18362        }
18363
18364        // Can't call out of the system process with a lock held, so post a message.
18365        if (app.instrumentationUiAutomationConnection != null) {
18366            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18367                    app.instrumentationUiAutomationConnection).sendToTarget();
18368        }
18369
18370        app.instrumentationWatcher = null;
18371        app.instrumentationUiAutomationConnection = null;
18372        app.instrumentationClass = null;
18373        app.instrumentationInfo = null;
18374        app.instrumentationProfileFile = null;
18375        app.instrumentationArguments = null;
18376
18377        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18378                "finished inst");
18379    }
18380
18381    public void finishInstrumentation(IApplicationThread target,
18382            int resultCode, Bundle results) {
18383        int userId = UserHandle.getCallingUserId();
18384        // Refuse possible leaked file descriptors
18385        if (results != null && results.hasFileDescriptors()) {
18386            throw new IllegalArgumentException("File descriptors passed in Intent");
18387        }
18388
18389        synchronized(this) {
18390            ProcessRecord app = getRecordForAppLocked(target);
18391            if (app == null) {
18392                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18393                return;
18394            }
18395            final long origId = Binder.clearCallingIdentity();
18396            finishInstrumentationLocked(app, resultCode, results);
18397            Binder.restoreCallingIdentity(origId);
18398        }
18399    }
18400
18401    // =========================================================
18402    // CONFIGURATION
18403    // =========================================================
18404
18405    public ConfigurationInfo getDeviceConfigurationInfo() {
18406        ConfigurationInfo config = new ConfigurationInfo();
18407        synchronized (this) {
18408            config.reqTouchScreen = mConfiguration.touchscreen;
18409            config.reqKeyboardType = mConfiguration.keyboard;
18410            config.reqNavigation = mConfiguration.navigation;
18411            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18412                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18413                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18414            }
18415            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18416                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18417                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18418            }
18419            config.reqGlEsVersion = GL_ES_VERSION;
18420        }
18421        return config;
18422    }
18423
18424    ActivityStack getFocusedStack() {
18425        return mStackSupervisor.getFocusedStack();
18426    }
18427
18428    @Override
18429    public int getFocusedStackId() throws RemoteException {
18430        ActivityStack focusedStack = getFocusedStack();
18431        if (focusedStack != null) {
18432            return focusedStack.getStackId();
18433        }
18434        return -1;
18435    }
18436
18437    public Configuration getConfiguration() {
18438        Configuration ci;
18439        synchronized(this) {
18440            ci = new Configuration(mConfiguration);
18441            ci.userSetLocale = false;
18442        }
18443        return ci;
18444    }
18445
18446    @Override
18447    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18448        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18449        synchronized (this) {
18450            mSuppressResizeConfigChanges = suppress;
18451        }
18452    }
18453
18454    @Override
18455    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18456        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18457        if (fromStackId == HOME_STACK_ID) {
18458            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18459        }
18460        synchronized (this) {
18461            final long origId = Binder.clearCallingIdentity();
18462            try {
18463                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18464            } finally {
18465                Binder.restoreCallingIdentity(origId);
18466            }
18467        }
18468    }
18469
18470    @Override
18471    public void updatePersistentConfiguration(Configuration values) {
18472        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18473                "updateConfiguration()");
18474        enforceWriteSettingsPermission("updateConfiguration()");
18475        if (values == null) {
18476            throw new NullPointerException("Configuration must not be null");
18477        }
18478
18479        int userId = UserHandle.getCallingUserId();
18480
18481        synchronized(this) {
18482            final long origId = Binder.clearCallingIdentity();
18483            updateConfigurationLocked(values, null, false, true, userId);
18484            Binder.restoreCallingIdentity(origId);
18485        }
18486    }
18487
18488    private void updateFontScaleIfNeeded() {
18489        final int currentUserId;
18490        synchronized(this) {
18491            currentUserId = mUserController.getCurrentUserIdLocked();
18492        }
18493        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18494                FONT_SCALE, 1.0f, currentUserId);
18495        if (mConfiguration.fontScale != scaleFactor) {
18496            final Configuration configuration = mWindowManager.computeNewConfiguration();
18497            configuration.fontScale = scaleFactor;
18498            updatePersistentConfiguration(configuration);
18499        }
18500    }
18501
18502    private void enforceWriteSettingsPermission(String func) {
18503        int uid = Binder.getCallingUid();
18504        if (uid == Process.ROOT_UID) {
18505            return;
18506        }
18507
18508        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18509                Settings.getPackageNameForUid(mContext, uid), false)) {
18510            return;
18511        }
18512
18513        String msg = "Permission Denial: " + func + " from pid="
18514                + Binder.getCallingPid()
18515                + ", uid=" + uid
18516                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18517        Slog.w(TAG, msg);
18518        throw new SecurityException(msg);
18519    }
18520
18521    public void updateConfiguration(Configuration values) {
18522        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18523                "updateConfiguration()");
18524
18525        synchronized(this) {
18526            if (values == null && mWindowManager != null) {
18527                // sentinel: fetch the current configuration from the window manager
18528                values = mWindowManager.computeNewConfiguration();
18529            }
18530
18531            if (mWindowManager != null) {
18532                mProcessList.applyDisplaySize(mWindowManager);
18533            }
18534
18535            final long origId = Binder.clearCallingIdentity();
18536            if (values != null) {
18537                Settings.System.clearConfiguration(values);
18538            }
18539            updateConfigurationLocked(values, null, false);
18540            Binder.restoreCallingIdentity(origId);
18541        }
18542    }
18543
18544    void updateUserConfigurationLocked() {
18545        Configuration configuration = new Configuration(mConfiguration);
18546        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18547                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18548        updateConfigurationLocked(configuration, null, false);
18549    }
18550
18551    boolean updateConfigurationLocked(Configuration values,
18552            ActivityRecord starting, boolean initLocale) {
18553        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18554        return updateConfigurationLocked(values, starting, initLocale, false,
18555                UserHandle.USER_NULL);
18556    }
18557
18558    // To cache the list of supported system locales
18559    private String[] mSupportedSystemLocales = null;
18560
18561    /**
18562     * Do either or both things: (1) change the current configuration, and (2)
18563     * make sure the given activity is running with the (now) current
18564     * configuration.  Returns true if the activity has been left running, or
18565     * false if <var>starting</var> is being destroyed to match the new
18566     * configuration.
18567     *
18568     * @param userId is only used when persistent parameter is set to true to persist configuration
18569     *               for that particular user
18570     */
18571    private boolean updateConfigurationLocked(Configuration values,
18572            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18573        int changes = 0;
18574
18575        if (mWindowManager != null) {
18576            mWindowManager.deferSurfaceLayout();
18577        }
18578        if (values != null) {
18579            Configuration newConfig = new Configuration(mConfiguration);
18580            changes = newConfig.updateFrom(values);
18581            if (changes != 0) {
18582                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18583                        "Updating configuration to: " + values);
18584
18585                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18586
18587                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18588                    final LocaleList locales = values.getLocales();
18589                    int bestLocaleIndex = 0;
18590                    if (locales.size() > 1) {
18591                        if (mSupportedSystemLocales == null) {
18592                            mSupportedSystemLocales =
18593                                    Resources.getSystem().getAssets().getLocales();
18594                        }
18595                        bestLocaleIndex = Math.max(0,
18596                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18597                    }
18598                    SystemProperties.set("persist.sys.locale",
18599                            locales.get(bestLocaleIndex).toLanguageTag());
18600                    LocaleList.setDefault(locales, bestLocaleIndex);
18601                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18602                            locales.get(bestLocaleIndex)));
18603                }
18604
18605                mConfigurationSeq++;
18606                if (mConfigurationSeq <= 0) {
18607                    mConfigurationSeq = 1;
18608                }
18609                newConfig.seq = mConfigurationSeq;
18610                mConfiguration = newConfig;
18611                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18612                mUsageStatsService.reportConfigurationChange(newConfig,
18613                        mUserController.getCurrentUserIdLocked());
18614                //mUsageStatsService.noteStartConfig(newConfig);
18615
18616                final Configuration configCopy = new Configuration(mConfiguration);
18617
18618                // TODO: If our config changes, should we auto dismiss any currently
18619                // showing dialogs?
18620                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18621
18622                AttributeCache ac = AttributeCache.instance();
18623                if (ac != null) {
18624                    ac.updateConfiguration(configCopy);
18625                }
18626
18627                // Make sure all resources in our process are updated
18628                // right now, so that anyone who is going to retrieve
18629                // resource values after we return will be sure to get
18630                // the new ones.  This is especially important during
18631                // boot, where the first config change needs to guarantee
18632                // all resources have that config before following boot
18633                // code is executed.
18634                mSystemThread.applyConfigurationToResources(configCopy);
18635
18636                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18637                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18638                    msg.obj = new Configuration(configCopy);
18639                    msg.arg1 = userId;
18640                    mHandler.sendMessage(msg);
18641                }
18642
18643                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18644                if (isDensityChange) {
18645                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18646                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18647                }
18648
18649                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18650                    ProcessRecord app = mLruProcesses.get(i);
18651                    try {
18652                        if (app.thread != null) {
18653                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18654                                    + app.processName + " new config " + mConfiguration);
18655                            app.thread.scheduleConfigurationChanged(configCopy);
18656                        }
18657                    } catch (Exception e) {
18658                    }
18659                }
18660                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18661                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18662                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18663                        | Intent.FLAG_RECEIVER_FOREGROUND);
18664                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18665                        null, AppOpsManager.OP_NONE, null, false, false,
18666                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18667                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18668                    // Tell the shortcut manager that the system locale changed.  It needs to know
18669                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18670                    // we "push" from here, rather than having the service listen to the broadcast.
18671                    final ShortcutServiceInternal shortcutService =
18672                            LocalServices.getService(ShortcutServiceInternal.class);
18673                    if (shortcutService != null) {
18674                        shortcutService.onSystemLocaleChangedNoLock();
18675                    }
18676
18677                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18678                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18679                    if (!mProcessesReady) {
18680                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18681                    }
18682                    broadcastIntentLocked(null, null, intent,
18683                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18684                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18685                }
18686            }
18687            // Update the configuration with WM first and check if any of the stacks need to be
18688            // resized due to the configuration change. If so, resize the stacks now and do any
18689            // relaunches if necessary. This way we don't need to relaunch again below in
18690            // ensureActivityConfigurationLocked().
18691            if (mWindowManager != null) {
18692                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18693                if (resizedStacks != null) {
18694                    for (int stackId : resizedStacks) {
18695                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18696                        mStackSupervisor.resizeStackLocked(
18697                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18698                    }
18699                }
18700            }
18701        }
18702
18703        boolean kept = true;
18704        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18705        // mainStack is null during startup.
18706        if (mainStack != null) {
18707            if (changes != 0 && starting == null) {
18708                // If the configuration changed, and the caller is not already
18709                // in the process of starting an activity, then find the top
18710                // activity to check if its configuration needs to change.
18711                starting = mainStack.topRunningActivityLocked();
18712            }
18713
18714            if (starting != null) {
18715                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18716                // And we need to make sure at this point that all other activities
18717                // are made visible with the correct configuration.
18718                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18719                        !PRESERVE_WINDOWS);
18720            }
18721        }
18722        if (mWindowManager != null) {
18723            mWindowManager.continueSurfaceLayout();
18724        }
18725        return kept;
18726    }
18727
18728    /**
18729     * Decide based on the configuration whether we should shouw the ANR,
18730     * crash, etc dialogs.  The idea is that if there is no affordnace to
18731     * press the on-screen buttons, we shouldn't show the dialog.
18732     *
18733     * A thought: SystemUI might also want to get told about this, the Power
18734     * dialog / global actions also might want different behaviors.
18735     */
18736    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18737        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18738                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18739                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18740        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18741                                    == Configuration.UI_MODE_TYPE_CAR);
18742        return inputMethodExists && uiIsNotCarType && !inVrMode;
18743    }
18744
18745    @Override
18746    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18747        synchronized (this) {
18748            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18749            if (srec != null) {
18750                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18751            }
18752        }
18753        return false;
18754    }
18755
18756    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18757            Intent resultData) {
18758
18759        synchronized (this) {
18760            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18761            if (r != null) {
18762                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18763            }
18764            return false;
18765        }
18766    }
18767
18768    public int getLaunchedFromUid(IBinder activityToken) {
18769        ActivityRecord srec;
18770        synchronized (this) {
18771            srec = ActivityRecord.forTokenLocked(activityToken);
18772        }
18773        if (srec == null) {
18774            return -1;
18775        }
18776        return srec.launchedFromUid;
18777    }
18778
18779    public String getLaunchedFromPackage(IBinder activityToken) {
18780        ActivityRecord srec;
18781        synchronized (this) {
18782            srec = ActivityRecord.forTokenLocked(activityToken);
18783        }
18784        if (srec == null) {
18785            return null;
18786        }
18787        return srec.launchedFromPackage;
18788    }
18789
18790    // =========================================================
18791    // LIFETIME MANAGEMENT
18792    // =========================================================
18793
18794    // Returns which broadcast queue the app is the current [or imminent] receiver
18795    // on, or 'null' if the app is not an active broadcast recipient.
18796    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18797        BroadcastRecord r = app.curReceiver;
18798        if (r != null) {
18799            return r.queue;
18800        }
18801
18802        // It's not the current receiver, but it might be starting up to become one
18803        synchronized (this) {
18804            for (BroadcastQueue queue : mBroadcastQueues) {
18805                r = queue.mPendingBroadcast;
18806                if (r != null && r.curApp == app) {
18807                    // found it; report which queue it's in
18808                    return queue;
18809                }
18810            }
18811        }
18812
18813        return null;
18814    }
18815
18816    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18817            int targetUid, ComponentName targetComponent, String targetProcess) {
18818        if (!mTrackingAssociations) {
18819            return null;
18820        }
18821        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18822                = mAssociations.get(targetUid);
18823        if (components == null) {
18824            components = new ArrayMap<>();
18825            mAssociations.put(targetUid, components);
18826        }
18827        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18828        if (sourceUids == null) {
18829            sourceUids = new SparseArray<>();
18830            components.put(targetComponent, sourceUids);
18831        }
18832        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18833        if (sourceProcesses == null) {
18834            sourceProcesses = new ArrayMap<>();
18835            sourceUids.put(sourceUid, sourceProcesses);
18836        }
18837        Association ass = sourceProcesses.get(sourceProcess);
18838        if (ass == null) {
18839            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18840                    targetProcess);
18841            sourceProcesses.put(sourceProcess, ass);
18842        }
18843        ass.mCount++;
18844        ass.mNesting++;
18845        if (ass.mNesting == 1) {
18846            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18847            ass.mLastState = sourceState;
18848        }
18849        return ass;
18850    }
18851
18852    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18853            ComponentName targetComponent) {
18854        if (!mTrackingAssociations) {
18855            return;
18856        }
18857        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18858                = mAssociations.get(targetUid);
18859        if (components == null) {
18860            return;
18861        }
18862        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18863        if (sourceUids == null) {
18864            return;
18865        }
18866        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18867        if (sourceProcesses == null) {
18868            return;
18869        }
18870        Association ass = sourceProcesses.get(sourceProcess);
18871        if (ass == null || ass.mNesting <= 0) {
18872            return;
18873        }
18874        ass.mNesting--;
18875        if (ass.mNesting == 0) {
18876            long uptime = SystemClock.uptimeMillis();
18877            ass.mTime += uptime - ass.mStartTime;
18878            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18879                    += uptime - ass.mLastStateUptime;
18880            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18881        }
18882    }
18883
18884    private void noteUidProcessState(final int uid, final int state) {
18885        mBatteryStatsService.noteUidProcessState(uid, state);
18886        if (mTrackingAssociations) {
18887            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18888                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18889                        = mAssociations.valueAt(i1);
18890                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18891                    SparseArray<ArrayMap<String, Association>> sourceUids
18892                            = targetComponents.valueAt(i2);
18893                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18894                    if (sourceProcesses != null) {
18895                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18896                            Association ass = sourceProcesses.valueAt(i4);
18897                            if (ass.mNesting >= 1) {
18898                                // currently associated
18899                                long uptime = SystemClock.uptimeMillis();
18900                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18901                                        += uptime - ass.mLastStateUptime;
18902                                ass.mLastState = state;
18903                                ass.mLastStateUptime = uptime;
18904                            }
18905                        }
18906                    }
18907                }
18908            }
18909        }
18910    }
18911
18912    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18913            boolean doingAll, long now) {
18914        if (mAdjSeq == app.adjSeq) {
18915            // This adjustment has already been computed.
18916            return app.curRawAdj;
18917        }
18918
18919        if (app.thread == null) {
18920            app.adjSeq = mAdjSeq;
18921            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18922            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18923            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18924        }
18925
18926        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18927        app.adjSource = null;
18928        app.adjTarget = null;
18929        app.empty = false;
18930        app.cached = false;
18931
18932        final int activitiesSize = app.activities.size();
18933
18934        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18935            // The max adjustment doesn't allow this app to be anything
18936            // below foreground, so it is not worth doing work for it.
18937            app.adjType = "fixed";
18938            app.adjSeq = mAdjSeq;
18939            app.curRawAdj = app.maxAdj;
18940            app.foregroundActivities = false;
18941            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18942            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18943            // System processes can do UI, and when they do we want to have
18944            // them trim their memory after the user leaves the UI.  To
18945            // facilitate this, here we need to determine whether or not it
18946            // is currently showing UI.
18947            app.systemNoUi = true;
18948            if (app == TOP_APP) {
18949                app.systemNoUi = false;
18950                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18951                app.adjType = "pers-top-activity";
18952            } else if (activitiesSize > 0) {
18953                for (int j = 0; j < activitiesSize; j++) {
18954                    final ActivityRecord r = app.activities.get(j);
18955                    if (r.visible) {
18956                        app.systemNoUi = false;
18957                    }
18958                }
18959            }
18960            if (!app.systemNoUi) {
18961                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18962            }
18963            return (app.curAdj=app.maxAdj);
18964        }
18965
18966        app.systemNoUi = false;
18967
18968        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18969
18970        // Determine the importance of the process, starting with most
18971        // important to least, and assign an appropriate OOM adjustment.
18972        int adj;
18973        int schedGroup;
18974        int procState;
18975        boolean foregroundActivities = false;
18976        BroadcastQueue queue;
18977        if (app == TOP_APP) {
18978            // The last app on the list is the foreground app.
18979            adj = ProcessList.FOREGROUND_APP_ADJ;
18980            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18981            app.adjType = "top-activity";
18982            foregroundActivities = true;
18983            procState = PROCESS_STATE_CUR_TOP;
18984        } else if (app.instrumentationClass != null) {
18985            // Don't want to kill running instrumentation.
18986            adj = ProcessList.FOREGROUND_APP_ADJ;
18987            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18988            app.adjType = "instrumentation";
18989            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18990        } else if ((queue = isReceivingBroadcast(app)) != null) {
18991            // An app that is currently receiving a broadcast also
18992            // counts as being in the foreground for OOM killer purposes.
18993            // It's placed in a sched group based on the nature of the
18994            // broadcast as reflected by which queue it's active in.
18995            adj = ProcessList.FOREGROUND_APP_ADJ;
18996            schedGroup = (queue == mFgBroadcastQueue)
18997                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18998            app.adjType = "broadcast";
18999            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19000        } else if (app.executingServices.size() > 0) {
19001            // An app that is currently executing a service callback also
19002            // counts as being in the foreground.
19003            adj = ProcessList.FOREGROUND_APP_ADJ;
19004            schedGroup = app.execServicesFg ?
19005                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19006            app.adjType = "exec-service";
19007            procState = ActivityManager.PROCESS_STATE_SERVICE;
19008            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19009        } else {
19010            // As far as we know the process is empty.  We may change our mind later.
19011            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19012            // At this point we don't actually know the adjustment.  Use the cached adj
19013            // value that the caller wants us to.
19014            adj = cachedAdj;
19015            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19016            app.cached = true;
19017            app.empty = true;
19018            app.adjType = "cch-empty";
19019        }
19020
19021        // Examine all activities if not already foreground.
19022        if (!foregroundActivities && activitiesSize > 0) {
19023            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19024            for (int j = 0; j < activitiesSize; j++) {
19025                final ActivityRecord r = app.activities.get(j);
19026                if (r.app != app) {
19027                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19028                            + " instead of expected " + app);
19029                    if (r.app == null || (r.app.uid == app.uid)) {
19030                        // Only fix things up when they look sane
19031                        r.app = app;
19032                    } else {
19033                        continue;
19034                    }
19035                }
19036                if (r.visible) {
19037                    // App has a visible activity; only upgrade adjustment.
19038                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19039                        adj = ProcessList.VISIBLE_APP_ADJ;
19040                        app.adjType = "visible";
19041                    }
19042                    if (procState > PROCESS_STATE_CUR_TOP) {
19043                        procState = PROCESS_STATE_CUR_TOP;
19044                    }
19045                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19046                    app.cached = false;
19047                    app.empty = false;
19048                    foregroundActivities = true;
19049                    if (r.task != null && minLayer > 0) {
19050                        final int layer = r.task.mLayerRank;
19051                        if (layer >= 0 && minLayer > layer) {
19052                            minLayer = layer;
19053                        }
19054                    }
19055                    break;
19056                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19057                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19058                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19059                        app.adjType = "pausing";
19060                    }
19061                    if (procState > PROCESS_STATE_CUR_TOP) {
19062                        procState = PROCESS_STATE_CUR_TOP;
19063                    }
19064                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19065                    app.cached = false;
19066                    app.empty = false;
19067                    foregroundActivities = true;
19068                } else if (r.state == ActivityState.STOPPING) {
19069                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19070                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19071                        app.adjType = "stopping";
19072                    }
19073                    // For the process state, we will at this point consider the
19074                    // process to be cached.  It will be cached either as an activity
19075                    // or empty depending on whether the activity is finishing.  We do
19076                    // this so that we can treat the process as cached for purposes of
19077                    // memory trimming (determing current memory level, trim command to
19078                    // send to process) since there can be an arbitrary number of stopping
19079                    // processes and they should soon all go into the cached state.
19080                    if (!r.finishing) {
19081                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19082                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19083                        }
19084                    }
19085                    app.cached = false;
19086                    app.empty = false;
19087                    foregroundActivities = true;
19088                } else {
19089                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19090                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19091                        app.adjType = "cch-act";
19092                    }
19093                }
19094            }
19095            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19096                adj += minLayer;
19097            }
19098        }
19099
19100        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19101                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19102            if (app.foregroundServices) {
19103                // The user is aware of this app, so make it visible.
19104                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19105                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19106                app.cached = false;
19107                app.adjType = "fg-service";
19108                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19109            } else if (app.forcingToForeground != null) {
19110                // The user is aware of this app, so make it visible.
19111                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19112                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19113                app.cached = false;
19114                app.adjType = "force-fg";
19115                app.adjSource = app.forcingToForeground;
19116                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19117            }
19118        }
19119
19120        if (app == mHeavyWeightProcess) {
19121            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19122                // We don't want to kill the current heavy-weight process.
19123                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19124                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19125                app.cached = false;
19126                app.adjType = "heavy";
19127            }
19128            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19129                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19130            }
19131        }
19132
19133        if (app == mHomeProcess) {
19134            if (adj > ProcessList.HOME_APP_ADJ) {
19135                // This process is hosting what we currently consider to be the
19136                // home app, so we don't want to let it go into the background.
19137                adj = ProcessList.HOME_APP_ADJ;
19138                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19139                app.cached = false;
19140                app.adjType = "home";
19141            }
19142            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19143                procState = ActivityManager.PROCESS_STATE_HOME;
19144            }
19145        }
19146
19147        if (app == mPreviousProcess && app.activities.size() > 0) {
19148            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19149                // This was the previous process that showed UI to the user.
19150                // We want to try to keep it around more aggressively, to give
19151                // a good experience around switching between two apps.
19152                adj = ProcessList.PREVIOUS_APP_ADJ;
19153                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19154                app.cached = false;
19155                app.adjType = "previous";
19156            }
19157            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19158                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19159            }
19160        }
19161
19162        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19163                + " reason=" + app.adjType);
19164
19165        // By default, we use the computed adjustment.  It may be changed if
19166        // there are applications dependent on our services or providers, but
19167        // this gives us a baseline and makes sure we don't get into an
19168        // infinite recursion.
19169        app.adjSeq = mAdjSeq;
19170        app.curRawAdj = adj;
19171        app.hasStartedServices = false;
19172
19173        if (mBackupTarget != null && app == mBackupTarget.app) {
19174            // If possible we want to avoid killing apps while they're being backed up
19175            if (adj > ProcessList.BACKUP_APP_ADJ) {
19176                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19177                adj = ProcessList.BACKUP_APP_ADJ;
19178                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19179                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19180                }
19181                app.adjType = "backup";
19182                app.cached = false;
19183            }
19184            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19185                procState = ActivityManager.PROCESS_STATE_BACKUP;
19186            }
19187        }
19188
19189        boolean mayBeTop = false;
19190
19191        for (int is = app.services.size()-1;
19192                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19193                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19194                        || procState > ActivityManager.PROCESS_STATE_TOP);
19195                is--) {
19196            ServiceRecord s = app.services.valueAt(is);
19197            if (s.startRequested) {
19198                app.hasStartedServices = true;
19199                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19200                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19201                }
19202                if (app.hasShownUi && app != mHomeProcess) {
19203                    // If this process has shown some UI, let it immediately
19204                    // go to the LRU list because it may be pretty heavy with
19205                    // UI stuff.  We'll tag it with a label just to help
19206                    // debug and understand what is going on.
19207                    if (adj > ProcessList.SERVICE_ADJ) {
19208                        app.adjType = "cch-started-ui-services";
19209                    }
19210                } else {
19211                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19212                        // This service has seen some activity within
19213                        // recent memory, so we will keep its process ahead
19214                        // of the background processes.
19215                        if (adj > ProcessList.SERVICE_ADJ) {
19216                            adj = ProcessList.SERVICE_ADJ;
19217                            app.adjType = "started-services";
19218                            app.cached = false;
19219                        }
19220                    }
19221                    // If we have let the service slide into the background
19222                    // state, still have some text describing what it is doing
19223                    // even though the service no longer has an impact.
19224                    if (adj > ProcessList.SERVICE_ADJ) {
19225                        app.adjType = "cch-started-services";
19226                    }
19227                }
19228            }
19229
19230            app.whitelistManager = false;
19231
19232            for (int conni = s.connections.size()-1;
19233                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19234                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19235                            || procState > ActivityManager.PROCESS_STATE_TOP);
19236                    conni--) {
19237                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19238                for (int i = 0;
19239                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19240                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19241                                || procState > ActivityManager.PROCESS_STATE_TOP);
19242                        i++) {
19243                    // XXX should compute this based on the max of
19244                    // all connected clients.
19245                    ConnectionRecord cr = clist.get(i);
19246                    if (cr.binding.client == app) {
19247                        // Binding to ourself is not interesting.
19248                        continue;
19249                    }
19250                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19251                        app.whitelistManager = true;
19252                    }
19253
19254                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19255                        ProcessRecord client = cr.binding.client;
19256                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19257                                TOP_APP, doingAll, now);
19258                        int clientProcState = client.curProcState;
19259                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19260                            // If the other app is cached for any reason, for purposes here
19261                            // we are going to consider it empty.  The specific cached state
19262                            // doesn't propagate except under certain conditions.
19263                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19264                        }
19265                        String adjType = null;
19266                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19267                            // Not doing bind OOM management, so treat
19268                            // this guy more like a started service.
19269                            if (app.hasShownUi && app != mHomeProcess) {
19270                                // If this process has shown some UI, let it immediately
19271                                // go to the LRU list because it may be pretty heavy with
19272                                // UI stuff.  We'll tag it with a label just to help
19273                                // debug and understand what is going on.
19274                                if (adj > clientAdj) {
19275                                    adjType = "cch-bound-ui-services";
19276                                }
19277                                app.cached = false;
19278                                clientAdj = adj;
19279                                clientProcState = procState;
19280                            } else {
19281                                if (now >= (s.lastActivity
19282                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19283                                    // This service has not seen activity within
19284                                    // recent memory, so allow it to drop to the
19285                                    // LRU list if there is no other reason to keep
19286                                    // it around.  We'll also tag it with a label just
19287                                    // to help debug and undertand what is going on.
19288                                    if (adj > clientAdj) {
19289                                        adjType = "cch-bound-services";
19290                                    }
19291                                    clientAdj = adj;
19292                                }
19293                            }
19294                        }
19295                        if (adj > clientAdj) {
19296                            // If this process has recently shown UI, and
19297                            // the process that is binding to it is less
19298                            // important than being visible, then we don't
19299                            // care about the binding as much as we care
19300                            // about letting this process get into the LRU
19301                            // list to be killed and restarted if needed for
19302                            // memory.
19303                            if (app.hasShownUi && app != mHomeProcess
19304                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19305                                adjType = "cch-bound-ui-services";
19306                            } else {
19307                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19308                                        |Context.BIND_IMPORTANT)) != 0) {
19309                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19310                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19311                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19312                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19313                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19314                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19315                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19316                                    adj = clientAdj;
19317                                } else {
19318                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19319                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19320                                    }
19321                                }
19322                                if (!client.cached) {
19323                                    app.cached = false;
19324                                }
19325                                adjType = "service";
19326                            }
19327                        }
19328                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19329                            // This will treat important bound services identically to
19330                            // the top app, which may behave differently than generic
19331                            // foreground work.
19332                            if (client.curSchedGroup > schedGroup) {
19333                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19334                                    schedGroup = client.curSchedGroup;
19335                                } else {
19336                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19337                                }
19338                            }
19339                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19340                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19341                                    // Special handling of clients who are in the top state.
19342                                    // We *may* want to consider this process to be in the
19343                                    // top state as well, but only if there is not another
19344                                    // reason for it to be running.  Being on the top is a
19345                                    // special state, meaning you are specifically running
19346                                    // for the current top app.  If the process is already
19347                                    // running in the background for some other reason, it
19348                                    // is more important to continue considering it to be
19349                                    // in the background state.
19350                                    mayBeTop = true;
19351                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19352                                } else {
19353                                    // Special handling for above-top states (persistent
19354                                    // processes).  These should not bring the current process
19355                                    // into the top state, since they are not on top.  Instead
19356                                    // give them the best state after that.
19357                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19358                                        clientProcState =
19359                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19360                                    } else if (mWakefulness
19361                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19362                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19363                                                    != 0) {
19364                                        clientProcState =
19365                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19366                                    } else {
19367                                        clientProcState =
19368                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19369                                    }
19370                                }
19371                            }
19372                        } else {
19373                            if (clientProcState <
19374                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19375                                clientProcState =
19376                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19377                            }
19378                        }
19379                        if (procState > clientProcState) {
19380                            procState = clientProcState;
19381                        }
19382                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19383                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19384                            app.pendingUiClean = true;
19385                        }
19386                        if (adjType != null) {
19387                            app.adjType = adjType;
19388                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19389                                    .REASON_SERVICE_IN_USE;
19390                            app.adjSource = cr.binding.client;
19391                            app.adjSourceProcState = clientProcState;
19392                            app.adjTarget = s.name;
19393                        }
19394                    }
19395                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19396                        app.treatLikeActivity = true;
19397                    }
19398                    final ActivityRecord a = cr.activity;
19399                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19400                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19401                            (a.visible || a.state == ActivityState.RESUMED ||
19402                             a.state == ActivityState.PAUSING)) {
19403                            adj = ProcessList.FOREGROUND_APP_ADJ;
19404                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19405                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19406                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19407                                } else {
19408                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19409                                }
19410                            }
19411                            app.cached = false;
19412                            app.adjType = "service";
19413                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19414                                    .REASON_SERVICE_IN_USE;
19415                            app.adjSource = a;
19416                            app.adjSourceProcState = procState;
19417                            app.adjTarget = s.name;
19418                        }
19419                    }
19420                }
19421            }
19422        }
19423
19424        for (int provi = app.pubProviders.size()-1;
19425                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19426                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19427                        || procState > ActivityManager.PROCESS_STATE_TOP);
19428                provi--) {
19429            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19430            for (int i = cpr.connections.size()-1;
19431                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19432                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19433                            || procState > ActivityManager.PROCESS_STATE_TOP);
19434                    i--) {
19435                ContentProviderConnection conn = cpr.connections.get(i);
19436                ProcessRecord client = conn.client;
19437                if (client == app) {
19438                    // Being our own client is not interesting.
19439                    continue;
19440                }
19441                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19442                int clientProcState = client.curProcState;
19443                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19444                    // If the other app is cached for any reason, for purposes here
19445                    // we are going to consider it empty.
19446                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19447                }
19448                if (adj > clientAdj) {
19449                    if (app.hasShownUi && app != mHomeProcess
19450                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19451                        app.adjType = "cch-ui-provider";
19452                    } else {
19453                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19454                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19455                        app.adjType = "provider";
19456                    }
19457                    app.cached &= client.cached;
19458                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19459                            .REASON_PROVIDER_IN_USE;
19460                    app.adjSource = client;
19461                    app.adjSourceProcState = clientProcState;
19462                    app.adjTarget = cpr.name;
19463                }
19464                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19465                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19466                        // Special handling of clients who are in the top state.
19467                        // We *may* want to consider this process to be in the
19468                        // top state as well, but only if there is not another
19469                        // reason for it to be running.  Being on the top is a
19470                        // special state, meaning you are specifically running
19471                        // for the current top app.  If the process is already
19472                        // running in the background for some other reason, it
19473                        // is more important to continue considering it to be
19474                        // in the background state.
19475                        mayBeTop = true;
19476                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19477                    } else {
19478                        // Special handling for above-top states (persistent
19479                        // processes).  These should not bring the current process
19480                        // into the top state, since they are not on top.  Instead
19481                        // give them the best state after that.
19482                        clientProcState =
19483                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19484                    }
19485                }
19486                if (procState > clientProcState) {
19487                    procState = clientProcState;
19488                }
19489                if (client.curSchedGroup > schedGroup) {
19490                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19491                }
19492            }
19493            // If the provider has external (non-framework) process
19494            // dependencies, ensure that its adjustment is at least
19495            // FOREGROUND_APP_ADJ.
19496            if (cpr.hasExternalProcessHandles()) {
19497                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19498                    adj = ProcessList.FOREGROUND_APP_ADJ;
19499                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19500                    app.cached = false;
19501                    app.adjType = "provider";
19502                    app.adjTarget = cpr.name;
19503                }
19504                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19505                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19506                }
19507            }
19508        }
19509
19510        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19511            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19512                adj = ProcessList.PREVIOUS_APP_ADJ;
19513                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19514                app.cached = false;
19515                app.adjType = "provider";
19516            }
19517            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19518                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19519            }
19520        }
19521
19522        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19523            // A client of one of our services or providers is in the top state.  We
19524            // *may* want to be in the top state, but not if we are already running in
19525            // the background for some other reason.  For the decision here, we are going
19526            // to pick out a few specific states that we want to remain in when a client
19527            // is top (states that tend to be longer-term) and otherwise allow it to go
19528            // to the top state.
19529            switch (procState) {
19530                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19531                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19532                case ActivityManager.PROCESS_STATE_SERVICE:
19533                    // These all are longer-term states, so pull them up to the top
19534                    // of the background states, but not all the way to the top state.
19535                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19536                    break;
19537                default:
19538                    // Otherwise, top is a better choice, so take it.
19539                    procState = ActivityManager.PROCESS_STATE_TOP;
19540                    break;
19541            }
19542        }
19543
19544        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19545            if (app.hasClientActivities) {
19546                // This is a cached process, but with client activities.  Mark it so.
19547                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19548                app.adjType = "cch-client-act";
19549            } else if (app.treatLikeActivity) {
19550                // This is a cached process, but somebody wants us to treat it like it has
19551                // an activity, okay!
19552                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19553                app.adjType = "cch-as-act";
19554            }
19555        }
19556
19557        if (adj == ProcessList.SERVICE_ADJ) {
19558            if (doingAll) {
19559                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19560                mNewNumServiceProcs++;
19561                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19562                if (!app.serviceb) {
19563                    // This service isn't far enough down on the LRU list to
19564                    // normally be a B service, but if we are low on RAM and it
19565                    // is large we want to force it down since we would prefer to
19566                    // keep launcher over it.
19567                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19568                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19569                        app.serviceHighRam = true;
19570                        app.serviceb = true;
19571                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19572                    } else {
19573                        mNewNumAServiceProcs++;
19574                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19575                    }
19576                } else {
19577                    app.serviceHighRam = false;
19578                }
19579            }
19580            if (app.serviceb) {
19581                adj = ProcessList.SERVICE_B_ADJ;
19582            }
19583        }
19584
19585        app.curRawAdj = adj;
19586
19587        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19588        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19589        if (adj > app.maxAdj) {
19590            adj = app.maxAdj;
19591            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19592                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19593            }
19594        }
19595
19596        // Do final modification to adj.  Everything we do between here and applying
19597        // the final setAdj must be done in this function, because we will also use
19598        // it when computing the final cached adj later.  Note that we don't need to
19599        // worry about this for max adj above, since max adj will always be used to
19600        // keep it out of the cached vaues.
19601        app.curAdj = app.modifyRawOomAdj(adj);
19602        app.curSchedGroup = schedGroup;
19603        app.curProcState = procState;
19604        app.foregroundActivities = foregroundActivities;
19605
19606        return app.curRawAdj;
19607    }
19608
19609    /**
19610     * Record new PSS sample for a process.
19611     */
19612    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19613            long now) {
19614        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19615                swapPss * 1024);
19616        proc.lastPssTime = now;
19617        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19618        if (DEBUG_PSS) Slog.d(TAG_PSS,
19619                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19620                + " state=" + ProcessList.makeProcStateString(procState));
19621        if (proc.initialIdlePss == 0) {
19622            proc.initialIdlePss = pss;
19623        }
19624        proc.lastPss = pss;
19625        proc.lastSwapPss = swapPss;
19626        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19627            proc.lastCachedPss = pss;
19628            proc.lastCachedSwapPss = swapPss;
19629        }
19630
19631        final SparseArray<Pair<Long, String>> watchUids
19632                = mMemWatchProcesses.getMap().get(proc.processName);
19633        Long check = null;
19634        if (watchUids != null) {
19635            Pair<Long, String> val = watchUids.get(proc.uid);
19636            if (val == null) {
19637                val = watchUids.get(0);
19638            }
19639            if (val != null) {
19640                check = val.first;
19641            }
19642        }
19643        if (check != null) {
19644            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19645                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19646                if (!isDebuggable) {
19647                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19648                        isDebuggable = true;
19649                    }
19650                }
19651                if (isDebuggable) {
19652                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19653                    final ProcessRecord myProc = proc;
19654                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19655                    mMemWatchDumpProcName = proc.processName;
19656                    mMemWatchDumpFile = heapdumpFile.toString();
19657                    mMemWatchDumpPid = proc.pid;
19658                    mMemWatchDumpUid = proc.uid;
19659                    BackgroundThread.getHandler().post(new Runnable() {
19660                        @Override
19661                        public void run() {
19662                            revokeUriPermission(ActivityThread.currentActivityThread()
19663                                            .getApplicationThread(),
19664                                    DumpHeapActivity.JAVA_URI,
19665                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19666                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19667                                    UserHandle.myUserId());
19668                            ParcelFileDescriptor fd = null;
19669                            try {
19670                                heapdumpFile.delete();
19671                                fd = ParcelFileDescriptor.open(heapdumpFile,
19672                                        ParcelFileDescriptor.MODE_CREATE |
19673                                                ParcelFileDescriptor.MODE_TRUNCATE |
19674                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19675                                                ParcelFileDescriptor.MODE_APPEND);
19676                                IApplicationThread thread = myProc.thread;
19677                                if (thread != null) {
19678                                    try {
19679                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19680                                                "Requesting dump heap from "
19681                                                + myProc + " to " + heapdumpFile);
19682                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19683                                    } catch (RemoteException e) {
19684                                    }
19685                                }
19686                            } catch (FileNotFoundException e) {
19687                                e.printStackTrace();
19688                            } finally {
19689                                if (fd != null) {
19690                                    try {
19691                                        fd.close();
19692                                    } catch (IOException e) {
19693                                    }
19694                                }
19695                            }
19696                        }
19697                    });
19698                } else {
19699                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19700                            + ", but debugging not enabled");
19701                }
19702            }
19703        }
19704    }
19705
19706    /**
19707     * Schedule PSS collection of a process.
19708     */
19709    void requestPssLocked(ProcessRecord proc, int procState) {
19710        if (mPendingPssProcesses.contains(proc)) {
19711            return;
19712        }
19713        if (mPendingPssProcesses.size() == 0) {
19714            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19715        }
19716        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19717        proc.pssProcState = procState;
19718        mPendingPssProcesses.add(proc);
19719    }
19720
19721    /**
19722     * Schedule PSS collection of all processes.
19723     */
19724    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19725        if (!always) {
19726            if (now < (mLastFullPssTime +
19727                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19728                return;
19729            }
19730        }
19731        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19732        mLastFullPssTime = now;
19733        mFullPssPending = true;
19734        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19735        mPendingPssProcesses.clear();
19736        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19737            ProcessRecord app = mLruProcesses.get(i);
19738            if (app.thread == null
19739                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19740                continue;
19741            }
19742            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19743                app.pssProcState = app.setProcState;
19744                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19745                        mTestPssMode, isSleeping(), now);
19746                mPendingPssProcesses.add(app);
19747            }
19748        }
19749        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19750    }
19751
19752    public void setTestPssMode(boolean enabled) {
19753        synchronized (this) {
19754            mTestPssMode = enabled;
19755            if (enabled) {
19756                // Whenever we enable the mode, we want to take a snapshot all of current
19757                // process mem use.
19758                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19759            }
19760        }
19761    }
19762
19763    /**
19764     * Ask a given process to GC right now.
19765     */
19766    final void performAppGcLocked(ProcessRecord app) {
19767        try {
19768            app.lastRequestedGc = SystemClock.uptimeMillis();
19769            if (app.thread != null) {
19770                if (app.reportLowMemory) {
19771                    app.reportLowMemory = false;
19772                    app.thread.scheduleLowMemory();
19773                } else {
19774                    app.thread.processInBackground();
19775                }
19776            }
19777        } catch (Exception e) {
19778            // whatever.
19779        }
19780    }
19781
19782    /**
19783     * Returns true if things are idle enough to perform GCs.
19784     */
19785    private final boolean canGcNowLocked() {
19786        boolean processingBroadcasts = false;
19787        for (BroadcastQueue q : mBroadcastQueues) {
19788            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19789                processingBroadcasts = true;
19790            }
19791        }
19792        return !processingBroadcasts
19793                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19794    }
19795
19796    /**
19797     * Perform GCs on all processes that are waiting for it, but only
19798     * if things are idle.
19799     */
19800    final void performAppGcsLocked() {
19801        final int N = mProcessesToGc.size();
19802        if (N <= 0) {
19803            return;
19804        }
19805        if (canGcNowLocked()) {
19806            while (mProcessesToGc.size() > 0) {
19807                ProcessRecord proc = mProcessesToGc.remove(0);
19808                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19809                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19810                            <= SystemClock.uptimeMillis()) {
19811                        // To avoid spamming the system, we will GC processes one
19812                        // at a time, waiting a few seconds between each.
19813                        performAppGcLocked(proc);
19814                        scheduleAppGcsLocked();
19815                        return;
19816                    } else {
19817                        // It hasn't been long enough since we last GCed this
19818                        // process...  put it in the list to wait for its time.
19819                        addProcessToGcListLocked(proc);
19820                        break;
19821                    }
19822                }
19823            }
19824
19825            scheduleAppGcsLocked();
19826        }
19827    }
19828
19829    /**
19830     * If all looks good, perform GCs on all processes waiting for them.
19831     */
19832    final void performAppGcsIfAppropriateLocked() {
19833        if (canGcNowLocked()) {
19834            performAppGcsLocked();
19835            return;
19836        }
19837        // Still not idle, wait some more.
19838        scheduleAppGcsLocked();
19839    }
19840
19841    /**
19842     * Schedule the execution of all pending app GCs.
19843     */
19844    final void scheduleAppGcsLocked() {
19845        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19846
19847        if (mProcessesToGc.size() > 0) {
19848            // Schedule a GC for the time to the next process.
19849            ProcessRecord proc = mProcessesToGc.get(0);
19850            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19851
19852            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19853            long now = SystemClock.uptimeMillis();
19854            if (when < (now+GC_TIMEOUT)) {
19855                when = now + GC_TIMEOUT;
19856            }
19857            mHandler.sendMessageAtTime(msg, when);
19858        }
19859    }
19860
19861    /**
19862     * Add a process to the array of processes waiting to be GCed.  Keeps the
19863     * list in sorted order by the last GC time.  The process can't already be
19864     * on the list.
19865     */
19866    final void addProcessToGcListLocked(ProcessRecord proc) {
19867        boolean added = false;
19868        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19869            if (mProcessesToGc.get(i).lastRequestedGc <
19870                    proc.lastRequestedGc) {
19871                added = true;
19872                mProcessesToGc.add(i+1, proc);
19873                break;
19874            }
19875        }
19876        if (!added) {
19877            mProcessesToGc.add(0, proc);
19878        }
19879    }
19880
19881    /**
19882     * Set up to ask a process to GC itself.  This will either do it
19883     * immediately, or put it on the list of processes to gc the next
19884     * time things are idle.
19885     */
19886    final void scheduleAppGcLocked(ProcessRecord app) {
19887        long now = SystemClock.uptimeMillis();
19888        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19889            return;
19890        }
19891        if (!mProcessesToGc.contains(app)) {
19892            addProcessToGcListLocked(app);
19893            scheduleAppGcsLocked();
19894        }
19895    }
19896
19897    final void checkExcessivePowerUsageLocked(boolean doKills) {
19898        updateCpuStatsNow();
19899
19900        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19901        boolean doWakeKills = doKills;
19902        boolean doCpuKills = doKills;
19903        if (mLastPowerCheckRealtime == 0) {
19904            doWakeKills = false;
19905        }
19906        if (mLastPowerCheckUptime == 0) {
19907            doCpuKills = false;
19908        }
19909        if (stats.isScreenOn()) {
19910            doWakeKills = false;
19911        }
19912        final long curRealtime = SystemClock.elapsedRealtime();
19913        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19914        final long curUptime = SystemClock.uptimeMillis();
19915        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19916        mLastPowerCheckRealtime = curRealtime;
19917        mLastPowerCheckUptime = curUptime;
19918        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19919            doWakeKills = false;
19920        }
19921        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19922            doCpuKills = false;
19923        }
19924        int i = mLruProcesses.size();
19925        while (i > 0) {
19926            i--;
19927            ProcessRecord app = mLruProcesses.get(i);
19928            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19929                long wtime;
19930                synchronized (stats) {
19931                    wtime = stats.getProcessWakeTime(app.info.uid,
19932                            app.pid, curRealtime);
19933                }
19934                long wtimeUsed = wtime - app.lastWakeTime;
19935                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19936                if (DEBUG_POWER) {
19937                    StringBuilder sb = new StringBuilder(128);
19938                    sb.append("Wake for ");
19939                    app.toShortString(sb);
19940                    sb.append(": over ");
19941                    TimeUtils.formatDuration(realtimeSince, sb);
19942                    sb.append(" used ");
19943                    TimeUtils.formatDuration(wtimeUsed, sb);
19944                    sb.append(" (");
19945                    sb.append((wtimeUsed*100)/realtimeSince);
19946                    sb.append("%)");
19947                    Slog.i(TAG_POWER, sb.toString());
19948                    sb.setLength(0);
19949                    sb.append("CPU for ");
19950                    app.toShortString(sb);
19951                    sb.append(": over ");
19952                    TimeUtils.formatDuration(uptimeSince, sb);
19953                    sb.append(" used ");
19954                    TimeUtils.formatDuration(cputimeUsed, sb);
19955                    sb.append(" (");
19956                    sb.append((cputimeUsed*100)/uptimeSince);
19957                    sb.append("%)");
19958                    Slog.i(TAG_POWER, sb.toString());
19959                }
19960                // If a process has held a wake lock for more
19961                // than 50% of the time during this period,
19962                // that sounds bad.  Kill!
19963                if (doWakeKills && realtimeSince > 0
19964                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19965                    synchronized (stats) {
19966                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19967                                realtimeSince, wtimeUsed);
19968                    }
19969                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19970                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19971                } else if (doCpuKills && uptimeSince > 0
19972                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19973                    synchronized (stats) {
19974                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19975                                uptimeSince, cputimeUsed);
19976                    }
19977                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19978                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19979                } else {
19980                    app.lastWakeTime = wtime;
19981                    app.lastCpuTime = app.curCpuTime;
19982                }
19983            }
19984        }
19985    }
19986
19987    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19988            long nowElapsed) {
19989        boolean success = true;
19990
19991        if (app.curRawAdj != app.setRawAdj) {
19992            app.setRawAdj = app.curRawAdj;
19993        }
19994
19995        int changes = 0;
19996
19997        if (app.curAdj != app.setAdj) {
19998            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19999            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20000                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20001                    + app.adjType);
20002            app.setAdj = app.curAdj;
20003        }
20004
20005        if (app.setSchedGroup != app.curSchedGroup) {
20006            app.setSchedGroup = app.curSchedGroup;
20007            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20008                    "Setting sched group of " + app.processName
20009                    + " to " + app.curSchedGroup);
20010            if (app.waitingToKill != null && app.curReceiver == null
20011                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20012                app.kill(app.waitingToKill, true);
20013                success = false;
20014            } else {
20015                int processGroup;
20016                switch (app.curSchedGroup) {
20017                    case ProcessList.SCHED_GROUP_BACKGROUND:
20018                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20019                        break;
20020                    case ProcessList.SCHED_GROUP_TOP_APP:
20021                        processGroup = Process.THREAD_GROUP_TOP_APP;
20022                        break;
20023                    default:
20024                        processGroup = Process.THREAD_GROUP_DEFAULT;
20025                        break;
20026                }
20027                if (true) {
20028                    long oldId = Binder.clearCallingIdentity();
20029                    try {
20030                        Process.setProcessGroup(app.pid, processGroup);
20031                    } catch (Exception e) {
20032                        Slog.w(TAG, "Failed setting process group of " + app.pid
20033                                + " to " + app.curSchedGroup);
20034                        e.printStackTrace();
20035                    } finally {
20036                        Binder.restoreCallingIdentity(oldId);
20037                    }
20038                } else {
20039                    if (app.thread != null) {
20040                        try {
20041                            app.thread.setSchedulingGroup(processGroup);
20042                        } catch (RemoteException e) {
20043                        }
20044                    }
20045                }
20046            }
20047        }
20048        if (app.repForegroundActivities != app.foregroundActivities) {
20049            app.repForegroundActivities = app.foregroundActivities;
20050            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20051        }
20052        if (app.repProcState != app.curProcState) {
20053            app.repProcState = app.curProcState;
20054            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20055            if (app.thread != null) {
20056                try {
20057                    if (false) {
20058                        //RuntimeException h = new RuntimeException("here");
20059                        Slog.i(TAG, "Sending new process state " + app.repProcState
20060                                + " to " + app /*, h*/);
20061                    }
20062                    app.thread.setProcessState(app.repProcState);
20063                } catch (RemoteException e) {
20064                }
20065            }
20066        }
20067        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20068                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20069            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20070                // Experimental code to more aggressively collect pss while
20071                // running test...  the problem is that this tends to collect
20072                // the data right when a process is transitioning between process
20073                // states, which well tend to give noisy data.
20074                long start = SystemClock.uptimeMillis();
20075                long pss = Debug.getPss(app.pid, mTmpLong, null);
20076                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20077                mPendingPssProcesses.remove(app);
20078                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20079                        + " to " + app.curProcState + ": "
20080                        + (SystemClock.uptimeMillis()-start) + "ms");
20081            }
20082            app.lastStateTime = now;
20083            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20084                    mTestPssMode, isSleeping(), now);
20085            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20086                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20087                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20088                    + (app.nextPssTime-now) + ": " + app);
20089        } else {
20090            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20091                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20092                    mTestPssMode)))) {
20093                requestPssLocked(app, app.setProcState);
20094                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20095                        mTestPssMode, isSleeping(), now);
20096            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20097                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20098        }
20099        if (app.setProcState != app.curProcState) {
20100            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20101                    "Proc state change of " + app.processName
20102                            + " to " + app.curProcState);
20103            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20104            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20105            if (setImportant && !curImportant) {
20106                // This app is no longer something we consider important enough to allow to
20107                // use arbitrary amounts of battery power.  Note
20108                // its current wake lock time to later know to kill it if
20109                // it is not behaving well.
20110                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20111                synchronized (stats) {
20112                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20113                            app.pid, nowElapsed);
20114                }
20115                app.lastCpuTime = app.curCpuTime;
20116
20117            }
20118            // Inform UsageStats of important process state change
20119            // Must be called before updating setProcState
20120            maybeUpdateUsageStatsLocked(app, nowElapsed);
20121
20122            app.setProcState = app.curProcState;
20123            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20124                app.notCachedSinceIdle = false;
20125            }
20126            if (!doingAll) {
20127                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20128            } else {
20129                app.procStateChanged = true;
20130            }
20131        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20132                > USAGE_STATS_INTERACTION_INTERVAL) {
20133            // For apps that sit around for a long time in the interactive state, we need
20134            // to report this at least once a day so they don't go idle.
20135            maybeUpdateUsageStatsLocked(app, nowElapsed);
20136        }
20137
20138        if (changes != 0) {
20139            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20140                    "Changes in " + app + ": " + changes);
20141            int i = mPendingProcessChanges.size()-1;
20142            ProcessChangeItem item = null;
20143            while (i >= 0) {
20144                item = mPendingProcessChanges.get(i);
20145                if (item.pid == app.pid) {
20146                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20147                            "Re-using existing item: " + item);
20148                    break;
20149                }
20150                i--;
20151            }
20152            if (i < 0) {
20153                // No existing item in pending changes; need a new one.
20154                final int NA = mAvailProcessChanges.size();
20155                if (NA > 0) {
20156                    item = mAvailProcessChanges.remove(NA-1);
20157                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20158                            "Retrieving available item: " + item);
20159                } else {
20160                    item = new ProcessChangeItem();
20161                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20162                            "Allocating new item: " + item);
20163                }
20164                item.changes = 0;
20165                item.pid = app.pid;
20166                item.uid = app.info.uid;
20167                if (mPendingProcessChanges.size() == 0) {
20168                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20169                            "*** Enqueueing dispatch processes changed!");
20170                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20171                }
20172                mPendingProcessChanges.add(item);
20173            }
20174            item.changes |= changes;
20175            item.processState = app.repProcState;
20176            item.foregroundActivities = app.repForegroundActivities;
20177            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20178                    "Item " + Integer.toHexString(System.identityHashCode(item))
20179                    + " " + app.toShortString() + ": changes=" + item.changes
20180                    + " procState=" + item.processState
20181                    + " foreground=" + item.foregroundActivities
20182                    + " type=" + app.adjType + " source=" + app.adjSource
20183                    + " target=" + app.adjTarget);
20184        }
20185
20186        return success;
20187    }
20188
20189    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20190        final UidRecord.ChangeItem pendingChange;
20191        if (uidRec == null || uidRec.pendingChange == null) {
20192            if (mPendingUidChanges.size() == 0) {
20193                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20194                        "*** Enqueueing dispatch uid changed!");
20195                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20196            }
20197            final int NA = mAvailUidChanges.size();
20198            if (NA > 0) {
20199                pendingChange = mAvailUidChanges.remove(NA-1);
20200                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20201                        "Retrieving available item: " + pendingChange);
20202            } else {
20203                pendingChange = new UidRecord.ChangeItem();
20204                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20205                        "Allocating new item: " + pendingChange);
20206            }
20207            if (uidRec != null) {
20208                uidRec.pendingChange = pendingChange;
20209                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20210                    // If this uid is going away, and we haven't yet reported it is gone,
20211                    // then do so now.
20212                    change = UidRecord.CHANGE_GONE_IDLE;
20213                }
20214            } else if (uid < 0) {
20215                throw new IllegalArgumentException("No UidRecord or uid");
20216            }
20217            pendingChange.uidRecord = uidRec;
20218            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20219            mPendingUidChanges.add(pendingChange);
20220        } else {
20221            pendingChange = uidRec.pendingChange;
20222            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20223                change = UidRecord.CHANGE_GONE_IDLE;
20224            }
20225        }
20226        pendingChange.change = change;
20227        pendingChange.processState = uidRec != null
20228                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20229    }
20230
20231    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20232            String authority) {
20233        if (app == null) return;
20234        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20235            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20236            if (userState == null) return;
20237            final long now = SystemClock.elapsedRealtime();
20238            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20239            if (lastReported == null || lastReported < now - 60 * 1000L) {
20240                mUsageStatsService.reportContentProviderUsage(
20241                        authority, providerPkgName, app.userId);
20242                userState.mProviderLastReportedFg.put(authority, now);
20243            }
20244        }
20245    }
20246
20247    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20248        if (DEBUG_USAGE_STATS) {
20249            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20250                    + "] state changes: old = " + app.setProcState + ", new = "
20251                    + app.curProcState);
20252        }
20253        if (mUsageStatsService == null) {
20254            return;
20255        }
20256        boolean isInteraction;
20257        // To avoid some abuse patterns, we are going to be careful about what we consider
20258        // to be an app interaction.  Being the top activity doesn't count while the display
20259        // is sleeping, nor do short foreground services.
20260        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20261            isInteraction = true;
20262            app.fgInteractionTime = 0;
20263        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20264            if (app.fgInteractionTime == 0) {
20265                app.fgInteractionTime = nowElapsed;
20266                isInteraction = false;
20267            } else {
20268                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20269            }
20270        } else {
20271            isInteraction = app.curProcState
20272                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20273            app.fgInteractionTime = 0;
20274        }
20275        if (isInteraction && (!app.reportedInteraction
20276                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20277            app.interactionEventTime = nowElapsed;
20278            String[] packages = app.getPackageList();
20279            if (packages != null) {
20280                for (int i = 0; i < packages.length; i++) {
20281                    mUsageStatsService.reportEvent(packages[i], app.userId,
20282                            UsageEvents.Event.SYSTEM_INTERACTION);
20283                }
20284            }
20285        }
20286        app.reportedInteraction = isInteraction;
20287        if (!isInteraction) {
20288            app.interactionEventTime = 0;
20289        }
20290    }
20291
20292    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20293        if (proc.thread != null) {
20294            if (proc.baseProcessTracker != null) {
20295                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20296            }
20297        }
20298    }
20299
20300    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20301            ProcessRecord TOP_APP, boolean doingAll, long now) {
20302        if (app.thread == null) {
20303            return false;
20304        }
20305
20306        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20307
20308        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20309    }
20310
20311    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20312            boolean oomAdj) {
20313        if (isForeground != proc.foregroundServices) {
20314            proc.foregroundServices = isForeground;
20315            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20316                    proc.info.uid);
20317            if (isForeground) {
20318                if (curProcs == null) {
20319                    curProcs = new ArrayList<ProcessRecord>();
20320                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20321                }
20322                if (!curProcs.contains(proc)) {
20323                    curProcs.add(proc);
20324                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20325                            proc.info.packageName, proc.info.uid);
20326                }
20327            } else {
20328                if (curProcs != null) {
20329                    if (curProcs.remove(proc)) {
20330                        mBatteryStatsService.noteEvent(
20331                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20332                                proc.info.packageName, proc.info.uid);
20333                        if (curProcs.size() <= 0) {
20334                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20335                        }
20336                    }
20337                }
20338            }
20339            if (oomAdj) {
20340                updateOomAdjLocked();
20341            }
20342        }
20343    }
20344
20345    private final ActivityRecord resumedAppLocked() {
20346        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20347        String pkg;
20348        int uid;
20349        if (act != null) {
20350            pkg = act.packageName;
20351            uid = act.info.applicationInfo.uid;
20352        } else {
20353            pkg = null;
20354            uid = -1;
20355        }
20356        // Has the UID or resumed package name changed?
20357        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20358                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20359            if (mCurResumedPackage != null) {
20360                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20361                        mCurResumedPackage, mCurResumedUid);
20362            }
20363            mCurResumedPackage = pkg;
20364            mCurResumedUid = uid;
20365            if (mCurResumedPackage != null) {
20366                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20367                        mCurResumedPackage, mCurResumedUid);
20368            }
20369        }
20370        return act;
20371    }
20372
20373    final boolean updateOomAdjLocked(ProcessRecord app) {
20374        final ActivityRecord TOP_ACT = resumedAppLocked();
20375        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20376        final boolean wasCached = app.cached;
20377
20378        mAdjSeq++;
20379
20380        // This is the desired cached adjusment we want to tell it to use.
20381        // If our app is currently cached, we know it, and that is it.  Otherwise,
20382        // we don't know it yet, and it needs to now be cached we will then
20383        // need to do a complete oom adj.
20384        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20385                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20386        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20387                SystemClock.uptimeMillis());
20388        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20389            // Changed to/from cached state, so apps after it in the LRU
20390            // list may also be changed.
20391            updateOomAdjLocked();
20392        }
20393        return success;
20394    }
20395
20396    final void updateOomAdjLocked() {
20397        final ActivityRecord TOP_ACT = resumedAppLocked();
20398        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20399        final long now = SystemClock.uptimeMillis();
20400        final long nowElapsed = SystemClock.elapsedRealtime();
20401        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20402        final int N = mLruProcesses.size();
20403
20404        if (false) {
20405            RuntimeException e = new RuntimeException();
20406            e.fillInStackTrace();
20407            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20408        }
20409
20410        // Reset state in all uid records.
20411        for (int i=mActiveUids.size()-1; i>=0; i--) {
20412            final UidRecord uidRec = mActiveUids.valueAt(i);
20413            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20414                    "Starting update of " + uidRec);
20415            uidRec.reset();
20416        }
20417
20418        mStackSupervisor.rankTaskLayersIfNeeded();
20419
20420        mAdjSeq++;
20421        mNewNumServiceProcs = 0;
20422        mNewNumAServiceProcs = 0;
20423
20424        final int emptyProcessLimit;
20425        final int cachedProcessLimit;
20426        if (mProcessLimit <= 0) {
20427            emptyProcessLimit = cachedProcessLimit = 0;
20428        } else if (mProcessLimit == 1) {
20429            emptyProcessLimit = 1;
20430            cachedProcessLimit = 0;
20431        } else {
20432            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20433            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20434        }
20435
20436        // Let's determine how many processes we have running vs.
20437        // how many slots we have for background processes; we may want
20438        // to put multiple processes in a slot of there are enough of
20439        // them.
20440        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20441                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20442        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20443        if (numEmptyProcs > cachedProcessLimit) {
20444            // If there are more empty processes than our limit on cached
20445            // processes, then use the cached process limit for the factor.
20446            // This ensures that the really old empty processes get pushed
20447            // down to the bottom, so if we are running low on memory we will
20448            // have a better chance at keeping around more cached processes
20449            // instead of a gazillion empty processes.
20450            numEmptyProcs = cachedProcessLimit;
20451        }
20452        int emptyFactor = numEmptyProcs/numSlots;
20453        if (emptyFactor < 1) emptyFactor = 1;
20454        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20455        if (cachedFactor < 1) cachedFactor = 1;
20456        int stepCached = 0;
20457        int stepEmpty = 0;
20458        int numCached = 0;
20459        int numEmpty = 0;
20460        int numTrimming = 0;
20461
20462        mNumNonCachedProcs = 0;
20463        mNumCachedHiddenProcs = 0;
20464
20465        // First update the OOM adjustment for each of the
20466        // application processes based on their current state.
20467        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20468        int nextCachedAdj = curCachedAdj+1;
20469        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20470        int nextEmptyAdj = curEmptyAdj+2;
20471        for (int i=N-1; i>=0; i--) {
20472            ProcessRecord app = mLruProcesses.get(i);
20473            if (!app.killedByAm && app.thread != null) {
20474                app.procStateChanged = false;
20475                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20476
20477                // If we haven't yet assigned the final cached adj
20478                // to the process, do that now.
20479                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20480                    switch (app.curProcState) {
20481                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20482                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20483                            // This process is a cached process holding activities...
20484                            // assign it the next cached value for that type, and then
20485                            // step that cached level.
20486                            app.curRawAdj = curCachedAdj;
20487                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20488                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20489                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20490                                    + ")");
20491                            if (curCachedAdj != nextCachedAdj) {
20492                                stepCached++;
20493                                if (stepCached >= cachedFactor) {
20494                                    stepCached = 0;
20495                                    curCachedAdj = nextCachedAdj;
20496                                    nextCachedAdj += 2;
20497                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20498                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20499                                    }
20500                                }
20501                            }
20502                            break;
20503                        default:
20504                            // For everything else, assign next empty cached process
20505                            // level and bump that up.  Note that this means that
20506                            // long-running services that have dropped down to the
20507                            // cached level will be treated as empty (since their process
20508                            // state is still as a service), which is what we want.
20509                            app.curRawAdj = curEmptyAdj;
20510                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20511                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20512                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20513                                    + ")");
20514                            if (curEmptyAdj != nextEmptyAdj) {
20515                                stepEmpty++;
20516                                if (stepEmpty >= emptyFactor) {
20517                                    stepEmpty = 0;
20518                                    curEmptyAdj = nextEmptyAdj;
20519                                    nextEmptyAdj += 2;
20520                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20521                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20522                                    }
20523                                }
20524                            }
20525                            break;
20526                    }
20527                }
20528
20529                applyOomAdjLocked(app, true, now, nowElapsed);
20530
20531                // Count the number of process types.
20532                switch (app.curProcState) {
20533                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20534                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20535                        mNumCachedHiddenProcs++;
20536                        numCached++;
20537                        if (numCached > cachedProcessLimit) {
20538                            app.kill("cached #" + numCached, true);
20539                        }
20540                        break;
20541                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20542                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20543                                && app.lastActivityTime < oldTime) {
20544                            app.kill("empty for "
20545                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20546                                    / 1000) + "s", true);
20547                        } else {
20548                            numEmpty++;
20549                            if (numEmpty > emptyProcessLimit) {
20550                                app.kill("empty #" + numEmpty, true);
20551                            }
20552                        }
20553                        break;
20554                    default:
20555                        mNumNonCachedProcs++;
20556                        break;
20557                }
20558
20559                if (app.isolated && app.services.size() <= 0) {
20560                    // If this is an isolated process, and there are no
20561                    // services running in it, then the process is no longer
20562                    // needed.  We agressively kill these because we can by
20563                    // definition not re-use the same process again, and it is
20564                    // good to avoid having whatever code was running in them
20565                    // left sitting around after no longer needed.
20566                    app.kill("isolated not needed", true);
20567                } else {
20568                    // Keeping this process, update its uid.
20569                    final UidRecord uidRec = app.uidRecord;
20570                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20571                        uidRec.curProcState = app.curProcState;
20572                    }
20573                }
20574
20575                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20576                        && !app.killedByAm) {
20577                    numTrimming++;
20578                }
20579            }
20580        }
20581
20582        mNumServiceProcs = mNewNumServiceProcs;
20583
20584        // Now determine the memory trimming level of background processes.
20585        // Unfortunately we need to start at the back of the list to do this
20586        // properly.  We only do this if the number of background apps we
20587        // are managing to keep around is less than half the maximum we desire;
20588        // if we are keeping a good number around, we'll let them use whatever
20589        // memory they want.
20590        final int numCachedAndEmpty = numCached + numEmpty;
20591        int memFactor;
20592        if (numCached <= ProcessList.TRIM_CACHED_APPS
20593                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20594            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20595                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20596            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20597                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20598            } else {
20599                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20600            }
20601        } else {
20602            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20603        }
20604        // We always allow the memory level to go up (better).  We only allow it to go
20605        // down if we are in a state where that is allowed, *and* the total number of processes
20606        // has gone down since last time.
20607        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20608                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20609                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20610        if (memFactor > mLastMemoryLevel) {
20611            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20612                memFactor = mLastMemoryLevel;
20613                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20614            }
20615        }
20616        if (memFactor != mLastMemoryLevel) {
20617            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20618        }
20619        mLastMemoryLevel = memFactor;
20620        mLastNumProcesses = mLruProcesses.size();
20621        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20622        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20623        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20624            if (mLowRamStartTime == 0) {
20625                mLowRamStartTime = now;
20626            }
20627            int step = 0;
20628            int fgTrimLevel;
20629            switch (memFactor) {
20630                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20631                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20632                    break;
20633                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20634                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20635                    break;
20636                default:
20637                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20638                    break;
20639            }
20640            int factor = numTrimming/3;
20641            int minFactor = 2;
20642            if (mHomeProcess != null) minFactor++;
20643            if (mPreviousProcess != null) minFactor++;
20644            if (factor < minFactor) factor = minFactor;
20645            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20646            for (int i=N-1; i>=0; i--) {
20647                ProcessRecord app = mLruProcesses.get(i);
20648                if (allChanged || app.procStateChanged) {
20649                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20650                    app.procStateChanged = false;
20651                }
20652                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20653                        && !app.killedByAm) {
20654                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20655                        try {
20656                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20657                                    "Trimming memory of " + app.processName + " to " + curLevel);
20658                            app.thread.scheduleTrimMemory(curLevel);
20659                        } catch (RemoteException e) {
20660                        }
20661                        if (false) {
20662                            // For now we won't do this; our memory trimming seems
20663                            // to be good enough at this point that destroying
20664                            // activities causes more harm than good.
20665                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20666                                    && app != mHomeProcess && app != mPreviousProcess) {
20667                                // Need to do this on its own message because the stack may not
20668                                // be in a consistent state at this point.
20669                                // For these apps we will also finish their activities
20670                                // to help them free memory.
20671                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20672                            }
20673                        }
20674                    }
20675                    app.trimMemoryLevel = curLevel;
20676                    step++;
20677                    if (step >= factor) {
20678                        step = 0;
20679                        switch (curLevel) {
20680                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20681                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20682                                break;
20683                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20684                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20685                                break;
20686                        }
20687                    }
20688                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20689                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20690                            && app.thread != null) {
20691                        try {
20692                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20693                                    "Trimming memory of heavy-weight " + app.processName
20694                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20695                            app.thread.scheduleTrimMemory(
20696                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20697                        } catch (RemoteException e) {
20698                        }
20699                    }
20700                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20701                } else {
20702                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20703                            || app.systemNoUi) && app.pendingUiClean) {
20704                        // If this application is now in the background and it
20705                        // had done UI, then give it the special trim level to
20706                        // have it free UI resources.
20707                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20708                        if (app.trimMemoryLevel < level && app.thread != null) {
20709                            try {
20710                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20711                                        "Trimming memory of bg-ui " + app.processName
20712                                        + " to " + level);
20713                                app.thread.scheduleTrimMemory(level);
20714                            } catch (RemoteException e) {
20715                            }
20716                        }
20717                        app.pendingUiClean = false;
20718                    }
20719                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20720                        try {
20721                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20722                                    "Trimming memory of fg " + app.processName
20723                                    + " to " + fgTrimLevel);
20724                            app.thread.scheduleTrimMemory(fgTrimLevel);
20725                        } catch (RemoteException e) {
20726                        }
20727                    }
20728                    app.trimMemoryLevel = fgTrimLevel;
20729                }
20730            }
20731        } else {
20732            if (mLowRamStartTime != 0) {
20733                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20734                mLowRamStartTime = 0;
20735            }
20736            for (int i=N-1; i>=0; i--) {
20737                ProcessRecord app = mLruProcesses.get(i);
20738                if (allChanged || app.procStateChanged) {
20739                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20740                    app.procStateChanged = false;
20741                }
20742                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20743                        || app.systemNoUi) && app.pendingUiClean) {
20744                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20745                            && app.thread != null) {
20746                        try {
20747                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20748                                    "Trimming memory of ui hidden " + app.processName
20749                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20750                            app.thread.scheduleTrimMemory(
20751                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20752                        } catch (RemoteException e) {
20753                        }
20754                    }
20755                    app.pendingUiClean = false;
20756                }
20757                app.trimMemoryLevel = 0;
20758            }
20759        }
20760
20761        if (mAlwaysFinishActivities) {
20762            // Need to do this on its own message because the stack may not
20763            // be in a consistent state at this point.
20764            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20765        }
20766
20767        if (allChanged) {
20768            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20769        }
20770
20771        // Update from any uid changes.
20772        for (int i=mActiveUids.size()-1; i>=0; i--) {
20773            final UidRecord uidRec = mActiveUids.valueAt(i);
20774            int uidChange = UidRecord.CHANGE_PROCSTATE;
20775            if (uidRec.setProcState != uidRec.curProcState) {
20776                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20777                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20778                        + " to " + uidRec.curProcState);
20779                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20780                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20781                        uidRec.lastBackgroundTime = nowElapsed;
20782                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20783                            // Note: the background settle time is in elapsed realtime, while
20784                            // the handler time base is uptime.  All this means is that we may
20785                            // stop background uids later than we had intended, but that only
20786                            // happens because the device was sleeping so we are okay anyway.
20787                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20788                        }
20789                    }
20790                } else {
20791                    if (uidRec.idle) {
20792                        uidChange = UidRecord.CHANGE_ACTIVE;
20793                        uidRec.idle = false;
20794                    }
20795                    uidRec.lastBackgroundTime = 0;
20796                }
20797                uidRec.setProcState = uidRec.curProcState;
20798                enqueueUidChangeLocked(uidRec, -1, uidChange);
20799                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20800            }
20801        }
20802
20803        if (mProcessStats.shouldWriteNowLocked(now)) {
20804            mHandler.post(new Runnable() {
20805                @Override public void run() {
20806                    synchronized (ActivityManagerService.this) {
20807                        mProcessStats.writeStateAsyncLocked();
20808                    }
20809                }
20810            });
20811        }
20812
20813        if (DEBUG_OOM_ADJ) {
20814            final long duration = SystemClock.uptimeMillis() - now;
20815            if (false) {
20816                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20817                        new RuntimeException("here").fillInStackTrace());
20818            } else {
20819                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20820            }
20821        }
20822    }
20823
20824    final void idleUids() {
20825        synchronized (this) {
20826            final long nowElapsed = SystemClock.elapsedRealtime();
20827            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20828            long nextTime = 0;
20829            for (int i=mActiveUids.size()-1; i>=0; i--) {
20830                final UidRecord uidRec = mActiveUids.valueAt(i);
20831                final long bgTime = uidRec.lastBackgroundTime;
20832                if (bgTime > 0 && !uidRec.idle) {
20833                    if (bgTime <= maxBgTime) {
20834                        uidRec.idle = true;
20835                        doStopUidLocked(uidRec.uid, uidRec);
20836                    } else {
20837                        if (nextTime == 0 || nextTime > bgTime) {
20838                            nextTime = bgTime;
20839                        }
20840                    }
20841                }
20842            }
20843            if (nextTime > 0) {
20844                mHandler.removeMessages(IDLE_UIDS_MSG);
20845                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20846                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20847            }
20848        }
20849    }
20850
20851    final void runInBackgroundDisabled(int uid) {
20852        synchronized (this) {
20853            UidRecord uidRec = mActiveUids.get(uid);
20854            if (uidRec != null) {
20855                // This uid is actually running...  should it be considered background now?
20856                if (uidRec.idle) {
20857                    doStopUidLocked(uidRec.uid, uidRec);
20858                }
20859            } else {
20860                // This uid isn't actually running...  still send a report about it being "stopped".
20861                doStopUidLocked(uid, null);
20862            }
20863        }
20864    }
20865
20866    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20867        mServices.stopInBackgroundLocked(uid);
20868        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20869    }
20870
20871    final void trimApplications() {
20872        synchronized (this) {
20873            int i;
20874
20875            // First remove any unused application processes whose package
20876            // has been removed.
20877            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20878                final ProcessRecord app = mRemovedProcesses.get(i);
20879                if (app.activities.size() == 0
20880                        && app.curReceiver == null && app.services.size() == 0) {
20881                    Slog.i(
20882                        TAG, "Exiting empty application process "
20883                        + app.toShortString() + " ("
20884                        + (app.thread != null ? app.thread.asBinder() : null)
20885                        + ")\n");
20886                    if (app.pid > 0 && app.pid != MY_PID) {
20887                        app.kill("empty", false);
20888                    } else {
20889                        try {
20890                            app.thread.scheduleExit();
20891                        } catch (Exception e) {
20892                            // Ignore exceptions.
20893                        }
20894                    }
20895                    cleanUpApplicationRecordLocked(app, false, true, -1);
20896                    mRemovedProcesses.remove(i);
20897
20898                    if (app.persistent) {
20899                        addAppLocked(app.info, false, null /* ABI override */);
20900                    }
20901                }
20902            }
20903
20904            // Now update the oom adj for all processes.
20905            updateOomAdjLocked();
20906        }
20907    }
20908
20909    /** This method sends the specified signal to each of the persistent apps */
20910    public void signalPersistentProcesses(int sig) throws RemoteException {
20911        if (sig != Process.SIGNAL_USR1) {
20912            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20913        }
20914
20915        synchronized (this) {
20916            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20917                    != PackageManager.PERMISSION_GRANTED) {
20918                throw new SecurityException("Requires permission "
20919                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20920            }
20921
20922            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20923                ProcessRecord r = mLruProcesses.get(i);
20924                if (r.thread != null && r.persistent) {
20925                    Process.sendSignal(r.pid, sig);
20926                }
20927            }
20928        }
20929    }
20930
20931    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20932        if (proc == null || proc == mProfileProc) {
20933            proc = mProfileProc;
20934            profileType = mProfileType;
20935            clearProfilerLocked();
20936        }
20937        if (proc == null) {
20938            return;
20939        }
20940        try {
20941            proc.thread.profilerControl(false, null, profileType);
20942        } catch (RemoteException e) {
20943            throw new IllegalStateException("Process disappeared");
20944        }
20945    }
20946
20947    private void clearProfilerLocked() {
20948        if (mProfileFd != null) {
20949            try {
20950                mProfileFd.close();
20951            } catch (IOException e) {
20952            }
20953        }
20954        mProfileApp = null;
20955        mProfileProc = null;
20956        mProfileFile = null;
20957        mProfileType = 0;
20958        mAutoStopProfiler = false;
20959        mSamplingInterval = 0;
20960    }
20961
20962    public boolean profileControl(String process, int userId, boolean start,
20963            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20964
20965        try {
20966            synchronized (this) {
20967                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20968                // its own permission.
20969                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20970                        != PackageManager.PERMISSION_GRANTED) {
20971                    throw new SecurityException("Requires permission "
20972                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20973                }
20974
20975                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20976                    throw new IllegalArgumentException("null profile info or fd");
20977                }
20978
20979                ProcessRecord proc = null;
20980                if (process != null) {
20981                    proc = findProcessLocked(process, userId, "profileControl");
20982                }
20983
20984                if (start && (proc == null || proc.thread == null)) {
20985                    throw new IllegalArgumentException("Unknown process: " + process);
20986                }
20987
20988                if (start) {
20989                    stopProfilerLocked(null, 0);
20990                    setProfileApp(proc.info, proc.processName, profilerInfo);
20991                    mProfileProc = proc;
20992                    mProfileType = profileType;
20993                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20994                    try {
20995                        fd = fd.dup();
20996                    } catch (IOException e) {
20997                        fd = null;
20998                    }
20999                    profilerInfo.profileFd = fd;
21000                    proc.thread.profilerControl(start, profilerInfo, profileType);
21001                    fd = null;
21002                    mProfileFd = null;
21003                } else {
21004                    stopProfilerLocked(proc, profileType);
21005                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21006                        try {
21007                            profilerInfo.profileFd.close();
21008                        } catch (IOException e) {
21009                        }
21010                    }
21011                }
21012
21013                return true;
21014            }
21015        } catch (RemoteException e) {
21016            throw new IllegalStateException("Process disappeared");
21017        } finally {
21018            if (profilerInfo != null && profilerInfo.profileFd != null) {
21019                try {
21020                    profilerInfo.profileFd.close();
21021                } catch (IOException e) {
21022                }
21023            }
21024        }
21025    }
21026
21027    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21028        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21029                userId, true, ALLOW_FULL_ONLY, callName, null);
21030        ProcessRecord proc = null;
21031        try {
21032            int pid = Integer.parseInt(process);
21033            synchronized (mPidsSelfLocked) {
21034                proc = mPidsSelfLocked.get(pid);
21035            }
21036        } catch (NumberFormatException e) {
21037        }
21038
21039        if (proc == null) {
21040            ArrayMap<String, SparseArray<ProcessRecord>> all
21041                    = mProcessNames.getMap();
21042            SparseArray<ProcessRecord> procs = all.get(process);
21043            if (procs != null && procs.size() > 0) {
21044                proc = procs.valueAt(0);
21045                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21046                    for (int i=1; i<procs.size(); i++) {
21047                        ProcessRecord thisProc = procs.valueAt(i);
21048                        if (thisProc.userId == userId) {
21049                            proc = thisProc;
21050                            break;
21051                        }
21052                    }
21053                }
21054            }
21055        }
21056
21057        return proc;
21058    }
21059
21060    public boolean dumpHeap(String process, int userId, boolean managed,
21061            String path, ParcelFileDescriptor fd) throws RemoteException {
21062
21063        try {
21064            synchronized (this) {
21065                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21066                // its own permission (same as profileControl).
21067                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21068                        != PackageManager.PERMISSION_GRANTED) {
21069                    throw new SecurityException("Requires permission "
21070                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21071                }
21072
21073                if (fd == null) {
21074                    throw new IllegalArgumentException("null fd");
21075                }
21076
21077                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21078                if (proc == null || proc.thread == null) {
21079                    throw new IllegalArgumentException("Unknown process: " + process);
21080                }
21081
21082                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21083                if (!isDebuggable) {
21084                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21085                        throw new SecurityException("Process not debuggable: " + proc);
21086                    }
21087                }
21088
21089                proc.thread.dumpHeap(managed, path, fd);
21090                fd = null;
21091                return true;
21092            }
21093        } catch (RemoteException e) {
21094            throw new IllegalStateException("Process disappeared");
21095        } finally {
21096            if (fd != null) {
21097                try {
21098                    fd.close();
21099                } catch (IOException e) {
21100                }
21101            }
21102        }
21103    }
21104
21105    @Override
21106    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21107            String reportPackage) {
21108        if (processName != null) {
21109            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21110                    "setDumpHeapDebugLimit()");
21111        } else {
21112            synchronized (mPidsSelfLocked) {
21113                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21114                if (proc == null) {
21115                    throw new SecurityException("No process found for calling pid "
21116                            + Binder.getCallingPid());
21117                }
21118                if (!Build.IS_DEBUGGABLE
21119                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21120                    throw new SecurityException("Not running a debuggable build");
21121                }
21122                processName = proc.processName;
21123                uid = proc.uid;
21124                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21125                    throw new SecurityException("Package " + reportPackage + " is not running in "
21126                            + proc);
21127                }
21128            }
21129        }
21130        synchronized (this) {
21131            if (maxMemSize > 0) {
21132                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21133            } else {
21134                if (uid != 0) {
21135                    mMemWatchProcesses.remove(processName, uid);
21136                } else {
21137                    mMemWatchProcesses.getMap().remove(processName);
21138                }
21139            }
21140        }
21141    }
21142
21143    @Override
21144    public void dumpHeapFinished(String path) {
21145        synchronized (this) {
21146            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21147                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21148                        + " does not match last pid " + mMemWatchDumpPid);
21149                return;
21150            }
21151            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21152                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21153                        + " does not match last path " + mMemWatchDumpFile);
21154                return;
21155            }
21156            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21157            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21158        }
21159    }
21160
21161    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21162    public void monitor() {
21163        synchronized (this) { }
21164    }
21165
21166    void onCoreSettingsChange(Bundle settings) {
21167        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21168            ProcessRecord processRecord = mLruProcesses.get(i);
21169            try {
21170                if (processRecord.thread != null) {
21171                    processRecord.thread.setCoreSettings(settings);
21172                }
21173            } catch (RemoteException re) {
21174                /* ignore */
21175            }
21176        }
21177    }
21178
21179    // Multi-user methods
21180
21181    /**
21182     * Start user, if its not already running, but don't bring it to foreground.
21183     */
21184    @Override
21185    public boolean startUserInBackground(final int userId) {
21186        return mUserController.startUser(userId, /* foreground */ false);
21187    }
21188
21189    @Override
21190    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21191        return mUserController.unlockUser(userId, token, secret, listener);
21192    }
21193
21194    @Override
21195    public boolean switchUser(final int targetUserId) {
21196        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21197        UserInfo currentUserInfo;
21198        UserInfo targetUserInfo;
21199        synchronized (this) {
21200            int currentUserId = mUserController.getCurrentUserIdLocked();
21201            currentUserInfo = mUserController.getUserInfo(currentUserId);
21202            targetUserInfo = mUserController.getUserInfo(targetUserId);
21203            if (targetUserInfo == null) {
21204                Slog.w(TAG, "No user info for user #" + targetUserId);
21205                return false;
21206            }
21207            if (!targetUserInfo.supportsSwitchTo()) {
21208                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21209                return false;
21210            }
21211            if (targetUserInfo.isManagedProfile()) {
21212                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21213                return false;
21214            }
21215            mUserController.setTargetUserIdLocked(targetUserId);
21216        }
21217        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21218        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21219        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21220        return true;
21221    }
21222
21223    void scheduleStartProfilesLocked() {
21224        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21225            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21226                    DateUtils.SECOND_IN_MILLIS);
21227        }
21228    }
21229
21230    @Override
21231    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21232        return mUserController.stopUser(userId, force, callback);
21233    }
21234
21235    @Override
21236    public UserInfo getCurrentUser() {
21237        return mUserController.getCurrentUser();
21238    }
21239
21240    @Override
21241    public boolean isUserRunning(int userId, int flags) {
21242        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21243                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21244            String msg = "Permission Denial: isUserRunning() from pid="
21245                    + Binder.getCallingPid()
21246                    + ", uid=" + Binder.getCallingUid()
21247                    + " requires " + INTERACT_ACROSS_USERS;
21248            Slog.w(TAG, msg);
21249            throw new SecurityException(msg);
21250        }
21251        synchronized (this) {
21252            return mUserController.isUserRunningLocked(userId, flags);
21253        }
21254    }
21255
21256    @Override
21257    public int[] getRunningUserIds() {
21258        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21259                != PackageManager.PERMISSION_GRANTED) {
21260            String msg = "Permission Denial: isUserRunning() from pid="
21261                    + Binder.getCallingPid()
21262                    + ", uid=" + Binder.getCallingUid()
21263                    + " requires " + INTERACT_ACROSS_USERS;
21264            Slog.w(TAG, msg);
21265            throw new SecurityException(msg);
21266        }
21267        synchronized (this) {
21268            return mUserController.getStartedUserArrayLocked();
21269        }
21270    }
21271
21272    @Override
21273    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21274        mUserController.registerUserSwitchObserver(observer);
21275    }
21276
21277    @Override
21278    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21279        mUserController.unregisterUserSwitchObserver(observer);
21280    }
21281
21282    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21283        if (info == null) return null;
21284        ApplicationInfo newInfo = new ApplicationInfo(info);
21285        newInfo.initForUser(userId);
21286        return newInfo;
21287    }
21288
21289    public boolean isUserStopped(int userId) {
21290        synchronized (this) {
21291            return mUserController.getStartedUserStateLocked(userId) == null;
21292        }
21293    }
21294
21295    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21296        if (aInfo == null
21297                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21298            return aInfo;
21299        }
21300
21301        ActivityInfo info = new ActivityInfo(aInfo);
21302        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21303        return info;
21304    }
21305
21306    private boolean processSanityChecksLocked(ProcessRecord process) {
21307        if (process == null || process.thread == null) {
21308            return false;
21309        }
21310
21311        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21312        if (!isDebuggable) {
21313            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21314                return false;
21315            }
21316        }
21317
21318        return true;
21319    }
21320
21321    public boolean startBinderTracking() throws RemoteException {
21322        synchronized (this) {
21323            mBinderTransactionTrackingEnabled = true;
21324            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21325            // permission (same as profileControl).
21326            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21327                    != PackageManager.PERMISSION_GRANTED) {
21328                throw new SecurityException("Requires permission "
21329                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21330            }
21331
21332            for (int i = 0; i < mLruProcesses.size(); i++) {
21333                ProcessRecord process = mLruProcesses.get(i);
21334                if (!processSanityChecksLocked(process)) {
21335                    continue;
21336                }
21337                try {
21338                    process.thread.startBinderTracking();
21339                } catch (RemoteException e) {
21340                    Log.v(TAG, "Process disappared");
21341                }
21342            }
21343            return true;
21344        }
21345    }
21346
21347    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21348        try {
21349            synchronized (this) {
21350                mBinderTransactionTrackingEnabled = false;
21351                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21352                // permission (same as profileControl).
21353                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21354                        != PackageManager.PERMISSION_GRANTED) {
21355                    throw new SecurityException("Requires permission "
21356                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21357                }
21358
21359                if (fd == null) {
21360                    throw new IllegalArgumentException("null fd");
21361                }
21362
21363                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21364                pw.println("Binder transaction traces for all processes.\n");
21365                for (ProcessRecord process : mLruProcesses) {
21366                    if (!processSanityChecksLocked(process)) {
21367                        continue;
21368                    }
21369
21370                    pw.println("Traces for process: " + process.processName);
21371                    pw.flush();
21372                    try {
21373                        TransferPipe tp = new TransferPipe();
21374                        try {
21375                            process.thread.stopBinderTrackingAndDump(
21376                                    tp.getWriteFd().getFileDescriptor());
21377                            tp.go(fd.getFileDescriptor());
21378                        } finally {
21379                            tp.kill();
21380                        }
21381                    } catch (IOException e) {
21382                        pw.println("Failure while dumping IPC traces from " + process +
21383                                ".  Exception: " + e);
21384                        pw.flush();
21385                    } catch (RemoteException e) {
21386                        pw.println("Got a RemoteException while dumping IPC traces from " +
21387                                process + ".  Exception: " + e);
21388                        pw.flush();
21389                    }
21390                }
21391                fd = null;
21392                return true;
21393            }
21394        } finally {
21395            if (fd != null) {
21396                try {
21397                    fd.close();
21398                } catch (IOException e) {
21399                }
21400            }
21401        }
21402    }
21403
21404    private final class LocalService extends ActivityManagerInternal {
21405        @Override
21406        public void onWakefulnessChanged(int wakefulness) {
21407            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21408        }
21409
21410        @Override
21411        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21412                String processName, String abiOverride, int uid, Runnable crashHandler) {
21413            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21414                    processName, abiOverride, uid, crashHandler);
21415        }
21416
21417        @Override
21418        public SleepToken acquireSleepToken(String tag) {
21419            Preconditions.checkNotNull(tag);
21420
21421            ComponentName requestedVrService = null;
21422            ComponentName callingVrActivity = null;
21423            int userId = -1;
21424            synchronized (ActivityManagerService.this) {
21425                if (mFocusedActivity != null) {
21426                    requestedVrService = mFocusedActivity.requestedVrComponent;
21427                    callingVrActivity = mFocusedActivity.info.getComponentName();
21428                    userId = mFocusedActivity.userId;
21429                }
21430            }
21431
21432            if (requestedVrService != null) {
21433                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21434            }
21435
21436            synchronized (ActivityManagerService.this) {
21437                SleepTokenImpl token = new SleepTokenImpl(tag);
21438                mSleepTokens.add(token);
21439                updateSleepIfNeededLocked();
21440                return token;
21441            }
21442        }
21443
21444        @Override
21445        public ComponentName getHomeActivityForUser(int userId) {
21446            synchronized (ActivityManagerService.this) {
21447                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21448                return homeActivity == null ? null : homeActivity.realActivity;
21449            }
21450        }
21451
21452        @Override
21453        public void onUserRemoved(int userId) {
21454            synchronized (ActivityManagerService.this) {
21455                ActivityManagerService.this.onUserStoppedLocked(userId);
21456            }
21457        }
21458
21459        @Override
21460        public void onLocalVoiceInteractionStarted(IBinder activity,
21461                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21462            synchronized (ActivityManagerService.this) {
21463                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21464                        voiceSession, voiceInteractor);
21465            }
21466        }
21467
21468        @Override
21469        public void notifyStartingWindowDrawn() {
21470            synchronized (ActivityManagerService.this) {
21471                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21472            }
21473        }
21474
21475        @Override
21476        public void notifyAppTransitionStarting(int reason) {
21477            synchronized (ActivityManagerService.this) {
21478                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21479            }
21480        }
21481
21482        @Override
21483        public void notifyAppTransitionFinished() {
21484            synchronized (ActivityManagerService.this) {
21485                mStackSupervisor.notifyAppTransitionDone();
21486            }
21487        }
21488
21489        @Override
21490        public void notifyAppTransitionCancelled() {
21491            synchronized (ActivityManagerService.this) {
21492                mStackSupervisor.notifyAppTransitionDone();
21493            }
21494        }
21495
21496        @Override
21497        public List<IBinder> getTopVisibleActivities() {
21498            synchronized (ActivityManagerService.this) {
21499                return mStackSupervisor.getTopVisibleActivities();
21500            }
21501        }
21502
21503        @Override
21504        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21505            synchronized (ActivityManagerService.this) {
21506                mStackSupervisor.setDockedStackMinimized(minimized);
21507            }
21508        }
21509
21510        @Override
21511        public void killForegroundAppsForUser(int userHandle) {
21512            synchronized (ActivityManagerService.this) {
21513                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21514                final int NP = mProcessNames.getMap().size();
21515                for (int ip = 0; ip < NP; ip++) {
21516                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21517                    final int NA = apps.size();
21518                    for (int ia = 0; ia < NA; ia++) {
21519                        final ProcessRecord app = apps.valueAt(ia);
21520                        if (app.persistent) {
21521                            // We don't kill persistent processes.
21522                            continue;
21523                        }
21524                        if (app.removed) {
21525                            procs.add(app);
21526                        } else if (app.userId == userHandle && app.foregroundActivities) {
21527                            app.removed = true;
21528                            procs.add(app);
21529                        }
21530                    }
21531                }
21532
21533                final int N = procs.size();
21534                for (int i = 0; i < N; i++) {
21535                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21536                }
21537            }
21538        }
21539
21540        @Override
21541        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21542            if (!(target instanceof PendingIntentRecord)) {
21543                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21544                return;
21545            }
21546            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21547        }
21548    }
21549
21550    private final class SleepTokenImpl extends SleepToken {
21551        private final String mTag;
21552        private final long mAcquireTime;
21553
21554        public SleepTokenImpl(String tag) {
21555            mTag = tag;
21556            mAcquireTime = SystemClock.uptimeMillis();
21557        }
21558
21559        @Override
21560        public void release() {
21561            synchronized (ActivityManagerService.this) {
21562                if (mSleepTokens.remove(this)) {
21563                    updateSleepIfNeededLocked();
21564                }
21565            }
21566        }
21567
21568        @Override
21569        public String toString() {
21570            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21571        }
21572    }
21573
21574    /**
21575     * An implementation of IAppTask, that allows an app to manage its own tasks via
21576     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21577     * only the process that calls getAppTasks() can call the AppTask methods.
21578     */
21579    class AppTaskImpl extends IAppTask.Stub {
21580        private int mTaskId;
21581        private int mCallingUid;
21582
21583        public AppTaskImpl(int taskId, int callingUid) {
21584            mTaskId = taskId;
21585            mCallingUid = callingUid;
21586        }
21587
21588        private void checkCaller() {
21589            if (mCallingUid != Binder.getCallingUid()) {
21590                throw new SecurityException("Caller " + mCallingUid
21591                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21592            }
21593        }
21594
21595        @Override
21596        public void finishAndRemoveTask() {
21597            checkCaller();
21598
21599            synchronized (ActivityManagerService.this) {
21600                long origId = Binder.clearCallingIdentity();
21601                try {
21602                    // We remove the task from recents to preserve backwards
21603                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21604                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21605                    }
21606                } finally {
21607                    Binder.restoreCallingIdentity(origId);
21608                }
21609            }
21610        }
21611
21612        @Override
21613        public ActivityManager.RecentTaskInfo getTaskInfo() {
21614            checkCaller();
21615
21616            synchronized (ActivityManagerService.this) {
21617                long origId = Binder.clearCallingIdentity();
21618                try {
21619                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21620                    if (tr == null) {
21621                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21622                    }
21623                    return createRecentTaskInfoFromTaskRecord(tr);
21624                } finally {
21625                    Binder.restoreCallingIdentity(origId);
21626                }
21627            }
21628        }
21629
21630        @Override
21631        public void moveToFront() {
21632            checkCaller();
21633            // Will bring task to front if it already has a root activity.
21634            final long origId = Binder.clearCallingIdentity();
21635            try {
21636                synchronized (this) {
21637                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21638                }
21639            } finally {
21640                Binder.restoreCallingIdentity(origId);
21641            }
21642        }
21643
21644        @Override
21645        public int startActivity(IBinder whoThread, String callingPackage,
21646                Intent intent, String resolvedType, Bundle bOptions) {
21647            checkCaller();
21648
21649            int callingUser = UserHandle.getCallingUserId();
21650            TaskRecord tr;
21651            IApplicationThread appThread;
21652            synchronized (ActivityManagerService.this) {
21653                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21654                if (tr == null) {
21655                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21656                }
21657                appThread = ApplicationThreadNative.asInterface(whoThread);
21658                if (appThread == null) {
21659                    throw new IllegalArgumentException("Bad app thread " + appThread);
21660                }
21661            }
21662            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21663                    resolvedType, null, null, null, null, 0, 0, null, null,
21664                    null, bOptions, false, callingUser, null, tr);
21665        }
21666
21667        @Override
21668        public void setExcludeFromRecents(boolean exclude) {
21669            checkCaller();
21670
21671            synchronized (ActivityManagerService.this) {
21672                long origId = Binder.clearCallingIdentity();
21673                try {
21674                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21675                    if (tr == null) {
21676                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21677                    }
21678                    Intent intent = tr.getBaseIntent();
21679                    if (exclude) {
21680                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21681                    } else {
21682                        intent.setFlags(intent.getFlags()
21683                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21684                    }
21685                } finally {
21686                    Binder.restoreCallingIdentity(origId);
21687                }
21688            }
21689        }
21690    }
21691
21692    /**
21693     * Kill processes for the user with id userId and that depend on the package named packageName
21694     */
21695    @Override
21696    public void killPackageDependents(String packageName, int userId) {
21697        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21698        if (packageName == null) {
21699            throw new NullPointerException(
21700                    "Cannot kill the dependents of a package without its name.");
21701        }
21702
21703        long callingId = Binder.clearCallingIdentity();
21704        IPackageManager pm = AppGlobals.getPackageManager();
21705        int pkgUid = -1;
21706        try {
21707            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21708        } catch (RemoteException e) {
21709        }
21710        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21711            throw new IllegalArgumentException(
21712                    "Cannot kill dependents of non-existing package " + packageName);
21713        }
21714        try {
21715            synchronized(this) {
21716                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21717                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21718                        "dep: " + packageName);
21719            }
21720        } finally {
21721            Binder.restoreCallingIdentity(callingId);
21722        }
21723    }
21724}
21725