ActivityManagerService.java revision 0814666bec852341bba0306872dd300b4efcbbac
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                    VrManagerInternal vrService =
2296                            LocalServices.getService(VrManagerInternal.class);
2297                    boolean enable = msg.arg1 == 1;
2298                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2299                            r.info.getComponentName());
2300                }
2301            } break;
2302            }
2303        }
2304    };
2305
2306    static final int COLLECT_PSS_BG_MSG = 1;
2307
2308    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2309        @Override
2310        public void handleMessage(Message msg) {
2311            switch (msg.what) {
2312            case COLLECT_PSS_BG_MSG: {
2313                long start = SystemClock.uptimeMillis();
2314                MemInfoReader memInfo = null;
2315                synchronized (ActivityManagerService.this) {
2316                    if (mFullPssPending) {
2317                        mFullPssPending = false;
2318                        memInfo = new MemInfoReader();
2319                    }
2320                }
2321                if (memInfo != null) {
2322                    updateCpuStatsNow();
2323                    long nativeTotalPss = 0;
2324                    synchronized (mProcessCpuTracker) {
2325                        final int N = mProcessCpuTracker.countStats();
2326                        for (int j=0; j<N; j++) {
2327                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2328                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2329                                // This is definitely an application process; skip it.
2330                                continue;
2331                            }
2332                            synchronized (mPidsSelfLocked) {
2333                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2334                                    // This is one of our own processes; skip it.
2335                                    continue;
2336                                }
2337                            }
2338                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2339                        }
2340                    }
2341                    memInfo.readMemInfo();
2342                    synchronized (ActivityManagerService.this) {
2343                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2344                                + (SystemClock.uptimeMillis()-start) + "ms");
2345                        final long cachedKb = memInfo.getCachedSizeKb();
2346                        final long freeKb = memInfo.getFreeSizeKb();
2347                        final long zramKb = memInfo.getZramTotalSizeKb();
2348                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2349                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2350                                kernelKb*1024, nativeTotalPss*1024);
2351                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2352                                nativeTotalPss);
2353                    }
2354                }
2355
2356                int num = 0;
2357                long[] tmp = new long[2];
2358                do {
2359                    ProcessRecord proc;
2360                    int procState;
2361                    int pid;
2362                    long lastPssTime;
2363                    synchronized (ActivityManagerService.this) {
2364                        if (mPendingPssProcesses.size() <= 0) {
2365                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2366                                    "Collected PSS of " + num + " processes in "
2367                                    + (SystemClock.uptimeMillis() - start) + "ms");
2368                            mPendingPssProcesses.clear();
2369                            return;
2370                        }
2371                        proc = mPendingPssProcesses.remove(0);
2372                        procState = proc.pssProcState;
2373                        lastPssTime = proc.lastPssTime;
2374                        if (proc.thread != null && procState == proc.setProcState
2375                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2376                                        < SystemClock.uptimeMillis()) {
2377                            pid = proc.pid;
2378                        } else {
2379                            proc = null;
2380                            pid = 0;
2381                        }
2382                    }
2383                    if (proc != null) {
2384                        long pss = Debug.getPss(pid, tmp, null);
2385                        synchronized (ActivityManagerService.this) {
2386                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2387                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2388                                num++;
2389                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2390                                        SystemClock.uptimeMillis());
2391                            }
2392                        }
2393                    }
2394                } while (true);
2395            }
2396            }
2397        }
2398    };
2399
2400    public void setSystemProcess() {
2401        try {
2402            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2403            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2404            ServiceManager.addService("meminfo", new MemBinder(this));
2405            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2406            ServiceManager.addService("dbinfo", new DbBinder(this));
2407            if (MONITOR_CPU_USAGE) {
2408                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2409            }
2410            ServiceManager.addService("permission", new PermissionController(this));
2411            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2412
2413            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2414                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2415            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2416
2417            synchronized (this) {
2418                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2419                app.persistent = true;
2420                app.pid = MY_PID;
2421                app.maxAdj = ProcessList.SYSTEM_ADJ;
2422                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2423                synchronized (mPidsSelfLocked) {
2424                    mPidsSelfLocked.put(app.pid, app);
2425                }
2426                updateLruProcessLocked(app, false, null);
2427                updateOomAdjLocked();
2428            }
2429        } catch (PackageManager.NameNotFoundException e) {
2430            throw new RuntimeException(
2431                    "Unable to find android system package", e);
2432        }
2433    }
2434
2435    public void setWindowManager(WindowManagerService wm) {
2436        mWindowManager = wm;
2437        mStackSupervisor.setWindowManager(wm);
2438        mActivityStarter.setWindowManager(wm);
2439    }
2440
2441    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2442        mUsageStatsService = usageStatsManager;
2443    }
2444
2445    public void startObservingNativeCrashes() {
2446        final NativeCrashListener ncl = new NativeCrashListener(this);
2447        ncl.start();
2448    }
2449
2450    public IAppOpsService getAppOpsService() {
2451        return mAppOpsService;
2452    }
2453
2454    static class MemBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        MemBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump meminfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2471        }
2472    }
2473
2474    static class GraphicsBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        GraphicsBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2491        }
2492    }
2493
2494    static class DbBinder extends Binder {
2495        ActivityManagerService mActivityManagerService;
2496        DbBinder(ActivityManagerService activityManagerService) {
2497            mActivityManagerService = activityManagerService;
2498        }
2499
2500        @Override
2501        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                    != PackageManager.PERMISSION_GRANTED) {
2504                pw.println("Permission Denial: can't dump dbinfo from from pid="
2505                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                        + " without permission " + android.Manifest.permission.DUMP);
2507                return;
2508            }
2509
2510            mActivityManagerService.dumpDbInfo(fd, pw, args);
2511        }
2512    }
2513
2514    static class CpuBinder extends Binder {
2515        ActivityManagerService mActivityManagerService;
2516        CpuBinder(ActivityManagerService activityManagerService) {
2517            mActivityManagerService = activityManagerService;
2518        }
2519
2520        @Override
2521        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                    != PackageManager.PERMISSION_GRANTED) {
2524                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2525                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                        + " without permission " + android.Manifest.permission.DUMP);
2527                return;
2528            }
2529
2530            synchronized (mActivityManagerService.mProcessCpuTracker) {
2531                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2532                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2533                        SystemClock.uptimeMillis()));
2534            }
2535        }
2536    }
2537
2538    public static final class Lifecycle extends SystemService {
2539        private final ActivityManagerService mService;
2540
2541        public Lifecycle(Context context) {
2542            super(context);
2543            mService = new ActivityManagerService(context);
2544        }
2545
2546        @Override
2547        public void onStart() {
2548            mService.start();
2549        }
2550
2551        public ActivityManagerService getService() {
2552            return mService;
2553        }
2554    }
2555
2556    // Note: This method is invoked on the main thread but may need to attach various
2557    // handlers to other threads.  So take care to be explicit about the looper.
2558    public ActivityManagerService(Context systemContext) {
2559        mContext = systemContext;
2560        mFactoryTest = FactoryTest.getMode();
2561        mSystemThread = ActivityThread.currentActivityThread();
2562
2563        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2564
2565        mHandlerThread = new ServiceThread(TAG,
2566                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2567        mHandlerThread.start();
2568        mHandler = new MainHandler(mHandlerThread.getLooper());
2569        mUiHandler = new UiHandler();
2570
2571        /* static; one-time init here */
2572        if (sKillHandler == null) {
2573            sKillThread = new ServiceThread(TAG + ":kill",
2574                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2575            sKillThread.start();
2576            sKillHandler = new KillHandler(sKillThread.getLooper());
2577        }
2578
2579        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580                "foreground", BROADCAST_FG_TIMEOUT, false);
2581        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2582                "background", BROADCAST_BG_TIMEOUT, true);
2583        mBroadcastQueues[0] = mFgBroadcastQueue;
2584        mBroadcastQueues[1] = mBgBroadcastQueue;
2585
2586        mServices = new ActiveServices(this);
2587        mProviderMap = new ProviderMap(this);
2588        mAppErrors = new AppErrors(mContext, this);
2589
2590        // TODO: Move creation of battery stats service outside of activity manager service.
2591        File dataDir = Environment.getDataDirectory();
2592        File systemDir = new File(dataDir, "system");
2593        systemDir.mkdirs();
2594        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2595        mBatteryStatsService.getActiveStatistics().readLocked();
2596        mBatteryStatsService.scheduleWriteToDisk();
2597        mOnBattery = DEBUG_POWER ? true
2598                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2599        mBatteryStatsService.getActiveStatistics().setCallback(this);
2600
2601        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2602
2603        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2604        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2605                new IAppOpsCallback.Stub() {
2606                    @Override public void opChanged(int op, int uid, String packageName) {
2607                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2608                            if (mAppOpsService.checkOperation(op, uid, packageName)
2609                                    != AppOpsManager.MODE_ALLOWED) {
2610                                runInBackgroundDisabled(uid);
2611                            }
2612                        }
2613                    }
2614                });
2615
2616        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2617
2618        mUserController = new UserController(this);
2619
2620        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2621            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2622
2623        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2624
2625        mConfiguration.setToDefaults();
2626        mConfiguration.setLocales(LocaleList.getDefault());
2627
2628        mConfigurationSeq = mConfiguration.seq = 1;
2629        mProcessCpuTracker.init();
2630
2631        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2632        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2633        mStackSupervisor = new ActivityStackSupervisor(this);
2634        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637        mProcessCpuThread = new Thread("CpuTracker") {
2638            @Override
2639            public void run() {
2640                while (true) {
2641                    try {
2642                        try {
2643                            synchronized(this) {
2644                                final long now = SystemClock.uptimeMillis();
2645                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                //        + ", write delay=" + nextWriteDelay);
2649                                if (nextWriteDelay < nextCpuDelay) {
2650                                    nextCpuDelay = nextWriteDelay;
2651                                }
2652                                if (nextCpuDelay > 0) {
2653                                    mProcessCpuMutexFree.set(true);
2654                                    this.wait(nextCpuDelay);
2655                                }
2656                            }
2657                        } catch (InterruptedException e) {
2658                        }
2659                        updateCpuStatsNow();
2660                    } catch (Exception e) {
2661                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                    }
2663                }
2664            }
2665        };
2666
2667        Watchdog.getInstance().addMonitor(this);
2668        Watchdog.getInstance().addThread(mHandler);
2669    }
2670
2671    public void setSystemServiceManager(SystemServiceManager mgr) {
2672        mSystemServiceManager = mgr;
2673    }
2674
2675    public void setInstaller(Installer installer) {
2676        mInstaller = installer;
2677    }
2678
2679    private void start() {
2680        Process.removeAllProcessGroups();
2681        mProcessCpuThread.start();
2682
2683        mBatteryStatsService.publish(mContext);
2684        mAppOpsService.publish(mContext);
2685        Slog.d("AppOps", "AppOpsService published");
2686        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687    }
2688
2689    void onUserStoppedLocked(int userId) {
2690        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691    }
2692
2693    public void initPowerManagement() {
2694        mStackSupervisor.initPowerManagement();
2695        mBatteryStatsService.initPowerManagement();
2696        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699        mVoiceWakeLock.setReferenceCounted(false);
2700    }
2701
2702    @Override
2703    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704            throws RemoteException {
2705        if (code == SYSPROPS_TRANSACTION) {
2706            // We need to tell all apps about the system property change.
2707            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708            synchronized(this) {
2709                final int NP = mProcessNames.getMap().size();
2710                for (int ip=0; ip<NP; ip++) {
2711                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                    final int NA = apps.size();
2713                    for (int ia=0; ia<NA; ia++) {
2714                        ProcessRecord app = apps.valueAt(ia);
2715                        if (app.thread != null) {
2716                            procs.add(app.thread.asBinder());
2717                        }
2718                    }
2719                }
2720            }
2721
2722            int N = procs.size();
2723            for (int i=0; i<N; i++) {
2724                Parcel data2 = Parcel.obtain();
2725                try {
2726                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                } catch (RemoteException e) {
2728                }
2729                data2.recycle();
2730            }
2731        }
2732        try {
2733            return super.onTransact(code, data, reply, flags);
2734        } catch (RuntimeException e) {
2735            // The activity manager only throws security exceptions, so let's
2736            // log all others.
2737            if (!(e instanceof SecurityException)) {
2738                Slog.wtf(TAG, "Activity Manager Crash", e);
2739            }
2740            throw e;
2741        }
2742    }
2743
2744    void updateCpuStats() {
2745        final long now = SystemClock.uptimeMillis();
2746        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747            return;
2748        }
2749        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750            synchronized (mProcessCpuThread) {
2751                mProcessCpuThread.notify();
2752            }
2753        }
2754    }
2755
2756    void updateCpuStatsNow() {
2757        synchronized (mProcessCpuTracker) {
2758            mProcessCpuMutexFree.set(false);
2759            final long now = SystemClock.uptimeMillis();
2760            boolean haveNewCpuStats = false;
2761
2762            if (MONITOR_CPU_USAGE &&
2763                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                mLastCpuTime.set(now);
2765                mProcessCpuTracker.update();
2766                if (mProcessCpuTracker.hasGoodLastStats()) {
2767                    haveNewCpuStats = true;
2768                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                    //Slog.i(TAG, "Total CPU usage: "
2770                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                    // Slog the cpu usage if the property is set.
2773                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                        int user = mProcessCpuTracker.getLastUserTime();
2775                        int system = mProcessCpuTracker.getLastSystemTime();
2776                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                        int irq = mProcessCpuTracker.getLastIrqTime();
2778                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                        int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                        int total = user + system + iowait + irq + softIrq + idle;
2782                        if (total == 0) total = 1;
2783
2784                        EventLog.writeEvent(EventLogTags.CPU,
2785                                ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                (user * 100) / total,
2787                                (system * 100) / total,
2788                                (iowait * 100) / total,
2789                                (irq * 100) / total,
2790                                (softIrq * 100) / total);
2791                    }
2792                }
2793            }
2794
2795            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796            synchronized(bstats) {
2797                synchronized(mPidsSelfLocked) {
2798                    if (haveNewCpuStats) {
2799                        if (bstats.startAddingCpuLocked()) {
2800                            int totalUTime = 0;
2801                            int totalSTime = 0;
2802                            final int N = mProcessCpuTracker.countStats();
2803                            for (int i=0; i<N; i++) {
2804                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                if (!st.working) {
2806                                    continue;
2807                                }
2808                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                totalUTime += st.rel_utime;
2810                                totalSTime += st.rel_stime;
2811                                if (pr != null) {
2812                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                    if (ps == null || !ps.isActive()) {
2814                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                pr.info.uid, pr.processName);
2816                                    }
2817                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                } else {
2820                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                    if (ps == null || !ps.isActive()) {
2822                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                bstats.mapUid(st.uid), st.name);
2824                                    }
2825                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                }
2827                            }
2828                            final int userTime = mProcessCpuTracker.getLastUserTime();
2829                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                        }
2837                    }
2838                }
2839
2840                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                    mLastWriteTime = now;
2842                    mBatteryStatsService.scheduleWriteToDisk();
2843                }
2844            }
2845        }
2846    }
2847
2848    @Override
2849    public void batteryNeedsCpuUpdate() {
2850        updateCpuStatsNow();
2851    }
2852
2853    @Override
2854    public void batteryPowerChanged(boolean onBattery) {
2855        // When plugging in, update the CPU stats first before changing
2856        // the plug state.
2857        updateCpuStatsNow();
2858        synchronized (this) {
2859            synchronized(mPidsSelfLocked) {
2860                mOnBattery = DEBUG_POWER ? true : onBattery;
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batterySendBroadcast(Intent intent) {
2867        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                AppOpsManager.OP_NONE, null, false, false,
2869                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870    }
2871
2872    /**
2873     * Initialize the application bind args. These are passed to each
2874     * process when the bindApplication() IPC is sent to the process. They're
2875     * lazily setup to make sure the services are running when they're asked for.
2876     */
2877    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878        if (mAppBindArgs == null) {
2879            mAppBindArgs = new HashMap<>();
2880
2881            // Isolated processes won't get this optimization, so that we don't
2882            // violate the rules about which services they have access to.
2883            if (!isolated) {
2884                // Setup the application init args
2885                mAppBindArgs.put("package", ServiceManager.getService("package"));
2886                mAppBindArgs.put("window", ServiceManager.getService("window"));
2887                mAppBindArgs.put(Context.ALARM_SERVICE,
2888                        ServiceManager.getService(Context.ALARM_SERVICE));
2889            }
2890        }
2891        return mAppBindArgs;
2892    }
2893
2894    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2895        if (r == null || mFocusedActivity == r) {
2896            return false;
2897        }
2898
2899        if (!r.isFocusable()) {
2900            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2901            return false;
2902        }
2903
2904        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2905
2906        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2907        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2908                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2909        mDoingSetFocusedActivity = true;
2910
2911        final ActivityRecord last = mFocusedActivity;
2912        mFocusedActivity = r;
2913        if (r.task.isApplicationTask()) {
2914            if (mCurAppTimeTracker != r.appTimeTracker) {
2915                // We are switching app tracking.  Complete the current one.
2916                if (mCurAppTimeTracker != null) {
2917                    mCurAppTimeTracker.stop();
2918                    mHandler.obtainMessage(
2919                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2920                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2921                    mCurAppTimeTracker = null;
2922                }
2923                if (r.appTimeTracker != null) {
2924                    mCurAppTimeTracker = r.appTimeTracker;
2925                    startTimeTrackingFocusedActivityLocked();
2926                }
2927            } else {
2928                startTimeTrackingFocusedActivityLocked();
2929            }
2930        } else {
2931            r.appTimeTracker = null;
2932        }
2933        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2934        // TODO: Probably not, because we don't want to resume voice on switching
2935        // back to this activity
2936        if (r.task.voiceInteractor != null) {
2937            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2938        } else {
2939            finishRunningVoiceLocked();
2940            IVoiceInteractionSession session;
2941            if (last != null && ((session = last.task.voiceSession) != null
2942                    || (session = last.voiceSession) != null)) {
2943                // We had been in a voice interaction session, but now focused has
2944                // move to something different.  Just finish the session, we can't
2945                // return to it and retain the proper state and synchronization with
2946                // the voice interaction service.
2947                finishVoiceTask(session);
2948            }
2949        }
2950        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2951            mWindowManager.setFocusedApp(r.appToken, true);
2952        }
2953        applyUpdateLockStateLocked(r);
2954        applyUpdateVrModeLocked(r);
2955        if (mFocusedActivity.userId != mLastFocusedUserId) {
2956            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2957            mHandler.obtainMessage(
2958                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2959            mLastFocusedUserId = mFocusedActivity.userId;
2960        }
2961
2962        // Log a warning if the focused app is changed during the process. This could
2963        // indicate a problem of the focus setting logic!
2964        if (mFocusedActivity != r) Slog.w(TAG,
2965                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2966        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2967
2968        EventLogTags.writeAmFocusedActivity(
2969                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2970                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2971                reason);
2972        return true;
2973    }
2974
2975    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2976        if (mFocusedActivity != goingAway) {
2977            return;
2978        }
2979
2980        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2981        if (focusedStack != null) {
2982            final ActivityRecord top = focusedStack.topActivity();
2983            if (top != null && top.userId != mLastFocusedUserId) {
2984                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2985                mHandler.sendMessage(
2986                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2987                mLastFocusedUserId = top.userId;
2988            }
2989        }
2990
2991        // Try to move focus to another activity if possible.
2992        if (setFocusedActivityLocked(
2993                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2994            return;
2995        }
2996
2997        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2998                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2999        mFocusedActivity = null;
3000        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3001    }
3002
3003    @Override
3004    public void setFocusedStack(int stackId) {
3005        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3006        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3007        final long callingId = Binder.clearCallingIdentity();
3008        try {
3009            synchronized (this) {
3010                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3011                if (stack == null) {
3012                    return;
3013                }
3014                final ActivityRecord r = stack.topRunningActivityLocked();
3015                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3016                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3017                }
3018            }
3019        } finally {
3020            Binder.restoreCallingIdentity(callingId);
3021        }
3022    }
3023
3024    @Override
3025    public void setFocusedTask(int taskId) {
3026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3027        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3028        final long callingId = Binder.clearCallingIdentity();
3029        try {
3030            synchronized (this) {
3031                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3032                if (task == null) {
3033                    return;
3034                }
3035                final ActivityRecord r = task.topRunningActivityLocked();
3036                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3037                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3038                }
3039            }
3040        } finally {
3041            Binder.restoreCallingIdentity(callingId);
3042        }
3043    }
3044
3045    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3046    @Override
3047    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3049        synchronized (this) {
3050            if (listener != null) {
3051                mTaskStackListeners.register(listener);
3052            }
3053        }
3054    }
3055
3056    @Override
3057    public void notifyActivityDrawn(IBinder token) {
3058        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3059        synchronized (this) {
3060            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3061            if (r != null) {
3062                r.task.stack.notifyActivityDrawnLocked(r);
3063            }
3064        }
3065    }
3066
3067    final void applyUpdateLockStateLocked(ActivityRecord r) {
3068        // Modifications to the UpdateLock state are done on our handler, outside
3069        // the activity manager's locks.  The new state is determined based on the
3070        // state *now* of the relevant activity record.  The object is passed to
3071        // the handler solely for logging detail, not to be consulted/modified.
3072        final boolean nextState = r != null && r.immersive;
3073        mHandler.sendMessage(
3074                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3075    }
3076
3077    final void applyUpdateVrModeLocked(ActivityRecord r) {
3078        mHandler.sendMessage(
3079                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3080    }
3081
3082    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3083        mHandler.sendMessage(
3084                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3085    }
3086
3087    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3088        Message msg = Message.obtain();
3089        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3090        msg.obj = r.task.askedCompatMode ? null : r;
3091        mUiHandler.sendMessage(msg);
3092    }
3093
3094    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3095            String what, Object obj, ProcessRecord srcApp) {
3096        app.lastActivityTime = now;
3097
3098        if (app.activities.size() > 0) {
3099            // Don't want to touch dependent processes that are hosting activities.
3100            return index;
3101        }
3102
3103        int lrui = mLruProcesses.lastIndexOf(app);
3104        if (lrui < 0) {
3105            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3106                    + what + " " + obj + " from " + srcApp);
3107            return index;
3108        }
3109
3110        if (lrui >= index) {
3111            // Don't want to cause this to move dependent processes *back* in the
3112            // list as if they were less frequently used.
3113            return index;
3114        }
3115
3116        if (lrui >= mLruProcessActivityStart) {
3117            // Don't want to touch dependent processes that are hosting activities.
3118            return index;
3119        }
3120
3121        mLruProcesses.remove(lrui);
3122        if (index > 0) {
3123            index--;
3124        }
3125        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3126                + " in LRU list: " + app);
3127        mLruProcesses.add(index, app);
3128        return index;
3129    }
3130
3131    static void killProcessGroup(int uid, int pid) {
3132        if (sKillHandler != null) {
3133            sKillHandler.sendMessage(
3134                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3135        } else {
3136            Slog.w(TAG, "Asked to kill process group before system bringup!");
3137            Process.killProcessGroup(uid, pid);
3138        }
3139    }
3140
3141    final void removeLruProcessLocked(ProcessRecord app) {
3142        int lrui = mLruProcesses.lastIndexOf(app);
3143        if (lrui >= 0) {
3144            if (!app.killed) {
3145                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3146                Process.killProcessQuiet(app.pid);
3147                killProcessGroup(app.uid, app.pid);
3148            }
3149            if (lrui <= mLruProcessActivityStart) {
3150                mLruProcessActivityStart--;
3151            }
3152            if (lrui <= mLruProcessServiceStart) {
3153                mLruProcessServiceStart--;
3154            }
3155            mLruProcesses.remove(lrui);
3156        }
3157    }
3158
3159    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3160            ProcessRecord client) {
3161        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3162                || app.treatLikeActivity;
3163        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3164        if (!activityChange && hasActivity) {
3165            // The process has activities, so we are only allowing activity-based adjustments
3166            // to move it.  It should be kept in the front of the list with other
3167            // processes that have activities, and we don't want those to change their
3168            // order except due to activity operations.
3169            return;
3170        }
3171
3172        mLruSeq++;
3173        final long now = SystemClock.uptimeMillis();
3174        app.lastActivityTime = now;
3175
3176        // First a quick reject: if the app is already at the position we will
3177        // put it, then there is nothing to do.
3178        if (hasActivity) {
3179            final int N = mLruProcesses.size();
3180            if (N > 0 && mLruProcesses.get(N-1) == app) {
3181                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3182                return;
3183            }
3184        } else {
3185            if (mLruProcessServiceStart > 0
3186                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3187                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3188                return;
3189            }
3190        }
3191
3192        int lrui = mLruProcesses.lastIndexOf(app);
3193
3194        if (app.persistent && lrui >= 0) {
3195            // We don't care about the position of persistent processes, as long as
3196            // they are in the list.
3197            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3198            return;
3199        }
3200
3201        /* In progress: compute new position first, so we can avoid doing work
3202           if the process is not actually going to move.  Not yet working.
3203        int addIndex;
3204        int nextIndex;
3205        boolean inActivity = false, inService = false;
3206        if (hasActivity) {
3207            // Process has activities, put it at the very tipsy-top.
3208            addIndex = mLruProcesses.size();
3209            nextIndex = mLruProcessServiceStart;
3210            inActivity = true;
3211        } else if (hasService) {
3212            // Process has services, put it at the top of the service list.
3213            addIndex = mLruProcessActivityStart;
3214            nextIndex = mLruProcessServiceStart;
3215            inActivity = true;
3216            inService = true;
3217        } else  {
3218            // Process not otherwise of interest, it goes to the top of the non-service area.
3219            addIndex = mLruProcessServiceStart;
3220            if (client != null) {
3221                int clientIndex = mLruProcesses.lastIndexOf(client);
3222                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3223                        + app);
3224                if (clientIndex >= 0 && addIndex > clientIndex) {
3225                    addIndex = clientIndex;
3226                }
3227            }
3228            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3229        }
3230
3231        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3232                + mLruProcessActivityStart + "): " + app);
3233        */
3234
3235        if (lrui >= 0) {
3236            if (lrui < mLruProcessActivityStart) {
3237                mLruProcessActivityStart--;
3238            }
3239            if (lrui < mLruProcessServiceStart) {
3240                mLruProcessServiceStart--;
3241            }
3242            /*
3243            if (addIndex > lrui) {
3244                addIndex--;
3245            }
3246            if (nextIndex > lrui) {
3247                nextIndex--;
3248            }
3249            */
3250            mLruProcesses.remove(lrui);
3251        }
3252
3253        /*
3254        mLruProcesses.add(addIndex, app);
3255        if (inActivity) {
3256            mLruProcessActivityStart++;
3257        }
3258        if (inService) {
3259            mLruProcessActivityStart++;
3260        }
3261        */
3262
3263        int nextIndex;
3264        if (hasActivity) {
3265            final int N = mLruProcesses.size();
3266            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3267                // Process doesn't have activities, but has clients with
3268                // activities...  move it up, but one below the top (the top
3269                // should always have a real activity).
3270                if (DEBUG_LRU) Slog.d(TAG_LRU,
3271                        "Adding to second-top of LRU activity list: " + app);
3272                mLruProcesses.add(N - 1, app);
3273                // To keep it from spamming the LRU list (by making a bunch of clients),
3274                // we will push down any other entries owned by the app.
3275                final int uid = app.info.uid;
3276                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3277                    ProcessRecord subProc = mLruProcesses.get(i);
3278                    if (subProc.info.uid == uid) {
3279                        // We want to push this one down the list.  If the process after
3280                        // it is for the same uid, however, don't do so, because we don't
3281                        // want them internally to be re-ordered.
3282                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3283                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3284                                    "Pushing uid " + uid + " swapping at " + i + ": "
3285                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3286                            ProcessRecord tmp = mLruProcesses.get(i);
3287                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3288                            mLruProcesses.set(i - 1, tmp);
3289                            i--;
3290                        }
3291                    } else {
3292                        // A gap, we can stop here.
3293                        break;
3294                    }
3295                }
3296            } else {
3297                // Process has activities, put it at the very tipsy-top.
3298                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3299                mLruProcesses.add(app);
3300            }
3301            nextIndex = mLruProcessServiceStart;
3302        } else if (hasService) {
3303            // Process has services, put it at the top of the service list.
3304            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3305            mLruProcesses.add(mLruProcessActivityStart, app);
3306            nextIndex = mLruProcessServiceStart;
3307            mLruProcessActivityStart++;
3308        } else  {
3309            // Process not otherwise of interest, it goes to the top of the non-service area.
3310            int index = mLruProcessServiceStart;
3311            if (client != null) {
3312                // If there is a client, don't allow the process to be moved up higher
3313                // in the list than that client.
3314                int clientIndex = mLruProcesses.lastIndexOf(client);
3315                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3316                        + " when updating " + app);
3317                if (clientIndex <= lrui) {
3318                    // Don't allow the client index restriction to push it down farther in the
3319                    // list than it already is.
3320                    clientIndex = lrui;
3321                }
3322                if (clientIndex >= 0 && index > clientIndex) {
3323                    index = clientIndex;
3324                }
3325            }
3326            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3327            mLruProcesses.add(index, app);
3328            nextIndex = index-1;
3329            mLruProcessActivityStart++;
3330            mLruProcessServiceStart++;
3331        }
3332
3333        // If the app is currently using a content provider or service,
3334        // bump those processes as well.
3335        for (int j=app.connections.size()-1; j>=0; j--) {
3336            ConnectionRecord cr = app.connections.valueAt(j);
3337            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3338                    && cr.binding.service.app != null
3339                    && cr.binding.service.app.lruSeq != mLruSeq
3340                    && !cr.binding.service.app.persistent) {
3341                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3342                        "service connection", cr, app);
3343            }
3344        }
3345        for (int j=app.conProviders.size()-1; j>=0; j--) {
3346            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3347            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3348                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3349                        "provider reference", cpr, app);
3350            }
3351        }
3352    }
3353
3354    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3355        if (uid == Process.SYSTEM_UID) {
3356            // The system gets to run in any process.  If there are multiple
3357            // processes with the same uid, just pick the first (this
3358            // should never happen).
3359            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3360            if (procs == null) return null;
3361            final int procCount = procs.size();
3362            for (int i = 0; i < procCount; i++) {
3363                final int procUid = procs.keyAt(i);
3364                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3365                    // Don't use an app process or different user process for system component.
3366                    continue;
3367                }
3368                return procs.valueAt(i);
3369            }
3370        }
3371        ProcessRecord proc = mProcessNames.get(processName, uid);
3372        if (false && proc != null && !keepIfLarge
3373                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3374                && proc.lastCachedPss >= 4000) {
3375            // Turn this condition on to cause killing to happen regularly, for testing.
3376            if (proc.baseProcessTracker != null) {
3377                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3378            }
3379            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3380        } else if (proc != null && !keepIfLarge
3381                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3382                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3383            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3384            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3385                if (proc.baseProcessTracker != null) {
3386                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3387                }
3388                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3389            }
3390        }
3391        return proc;
3392    }
3393
3394    void notifyPackageUse(String packageName, int reason) {
3395        IPackageManager pm = AppGlobals.getPackageManager();
3396        try {
3397            pm.notifyPackageUse(packageName, reason);
3398        } catch (RemoteException e) {
3399        }
3400    }
3401
3402    boolean isNextTransitionForward() {
3403        int transit = mWindowManager.getPendingAppTransition();
3404        return transit == TRANSIT_ACTIVITY_OPEN
3405                || transit == TRANSIT_TASK_OPEN
3406                || transit == TRANSIT_TASK_TO_FRONT;
3407    }
3408
3409    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3410            String processName, String abiOverride, int uid, Runnable crashHandler) {
3411        synchronized(this) {
3412            ApplicationInfo info = new ApplicationInfo();
3413            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3414            // For isolated processes, the former contains the parent's uid and the latter the
3415            // actual uid of the isolated process.
3416            // In the special case introduced by this method (which is, starting an isolated
3417            // process directly from the SystemServer without an actual parent app process) the
3418            // closest thing to a parent's uid is SYSTEM_UID.
3419            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3420            // the |isolated| logic in the ProcessRecord constructor.
3421            info.uid = Process.SYSTEM_UID;
3422            info.processName = processName;
3423            info.className = entryPoint;
3424            info.packageName = "android";
3425            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3426                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3427                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3428                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3429                    crashHandler);
3430            return proc != null ? proc.pid : 0;
3431        }
3432    }
3433
3434    final ProcessRecord startProcessLocked(String processName,
3435            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3436            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3437            boolean isolated, boolean keepIfLarge) {
3438        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3439                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3440                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3441                null /* crashHandler */);
3442    }
3443
3444    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3445            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3446            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3447            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3448        long startTime = SystemClock.elapsedRealtime();
3449        ProcessRecord app;
3450        if (!isolated) {
3451            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3452            checkTime(startTime, "startProcess: after getProcessRecord");
3453
3454            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3455                // If we are in the background, then check to see if this process
3456                // is bad.  If so, we will just silently fail.
3457                if (mAppErrors.isBadProcessLocked(info)) {
3458                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3459                            + "/" + info.processName);
3460                    return null;
3461                }
3462            } else {
3463                // When the user is explicitly starting a process, then clear its
3464                // crash count so that we won't make it bad until they see at
3465                // least one crash dialog again, and make the process good again
3466                // if it had been bad.
3467                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3468                        + "/" + info.processName);
3469                mAppErrors.resetProcessCrashTimeLocked(info);
3470                if (mAppErrors.isBadProcessLocked(info)) {
3471                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3472                            UserHandle.getUserId(info.uid), info.uid,
3473                            info.processName);
3474                    mAppErrors.clearBadProcessLocked(info);
3475                    if (app != null) {
3476                        app.bad = false;
3477                    }
3478                }
3479            }
3480        } else {
3481            // If this is an isolated process, it can't re-use an existing process.
3482            app = null;
3483        }
3484
3485        // app launch boost for big.little configurations
3486        // use cpusets to migrate freshly launched tasks to big cores
3487        synchronized(ActivityManagerService.this) {
3488            nativeMigrateToBoost();
3489            mIsBoosted = true;
3490            mBoostStartTime = SystemClock.uptimeMillis();
3491            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3492            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3493        }
3494
3495        // We don't have to do anything more if:
3496        // (1) There is an existing application record; and
3497        // (2) The caller doesn't think it is dead, OR there is no thread
3498        //     object attached to it so we know it couldn't have crashed; and
3499        // (3) There is a pid assigned to it, so it is either starting or
3500        //     already running.
3501        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3502                + " app=" + app + " knownToBeDead=" + knownToBeDead
3503                + " thread=" + (app != null ? app.thread : null)
3504                + " pid=" + (app != null ? app.pid : -1));
3505        if (app != null && app.pid > 0) {
3506            if (!knownToBeDead || app.thread == null) {
3507                // We already have the app running, or are waiting for it to
3508                // come up (we have a pid but not yet its thread), so keep it.
3509                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3510                // If this is a new package in the process, add the package to the list
3511                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3512                checkTime(startTime, "startProcess: done, added package to proc");
3513                return app;
3514            }
3515
3516            // An application record is attached to a previous process,
3517            // clean it up now.
3518            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3519            checkTime(startTime, "startProcess: bad proc running, killing");
3520            killProcessGroup(app.uid, app.pid);
3521            handleAppDiedLocked(app, true, true);
3522            checkTime(startTime, "startProcess: done killing old proc");
3523        }
3524
3525        String hostingNameStr = hostingName != null
3526                ? hostingName.flattenToShortString() : null;
3527
3528        if (app == null) {
3529            checkTime(startTime, "startProcess: creating new process record");
3530            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3531            if (app == null) {
3532                Slog.w(TAG, "Failed making new process record for "
3533                        + processName + "/" + info.uid + " isolated=" + isolated);
3534                return null;
3535            }
3536            app.crashHandler = crashHandler;
3537            checkTime(startTime, "startProcess: done creating new process record");
3538        } else {
3539            // If this is a new package in the process, add the package to the list
3540            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3541            checkTime(startTime, "startProcess: added package to existing proc");
3542        }
3543
3544        // If the system is not ready yet, then hold off on starting this
3545        // process until it is.
3546        if (!mProcessesReady
3547                && !isAllowedWhileBooting(info)
3548                && !allowWhileBooting) {
3549            if (!mProcessesOnHold.contains(app)) {
3550                mProcessesOnHold.add(app);
3551            }
3552            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3553                    "System not ready, putting on hold: " + app);
3554            checkTime(startTime, "startProcess: returning with proc on hold");
3555            return app;
3556        }
3557
3558        checkTime(startTime, "startProcess: stepping in to startProcess");
3559        startProcessLocked(
3560                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3561        checkTime(startTime, "startProcess: done starting proc!");
3562        return (app.pid != 0) ? app : null;
3563    }
3564
3565    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3566        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3567    }
3568
3569    private final void startProcessLocked(ProcessRecord app,
3570            String hostingType, String hostingNameStr) {
3571        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3572                null /* entryPoint */, null /* entryPointArgs */);
3573    }
3574
3575    private final void startProcessLocked(ProcessRecord app, String hostingType,
3576            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3577        long startTime = SystemClock.elapsedRealtime();
3578        if (app.pid > 0 && app.pid != MY_PID) {
3579            checkTime(startTime, "startProcess: removing from pids map");
3580            synchronized (mPidsSelfLocked) {
3581                mPidsSelfLocked.remove(app.pid);
3582                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3583            }
3584            checkTime(startTime, "startProcess: done removing from pids map");
3585            app.setPid(0);
3586        }
3587
3588        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3589                "startProcessLocked removing on hold: " + app);
3590        mProcessesOnHold.remove(app);
3591
3592        checkTime(startTime, "startProcess: starting to update cpu stats");
3593        updateCpuStats();
3594        checkTime(startTime, "startProcess: done updating cpu stats");
3595
3596        try {
3597            try {
3598                final int userId = UserHandle.getUserId(app.uid);
3599                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3600            } catch (RemoteException e) {
3601                throw e.rethrowAsRuntimeException();
3602            }
3603
3604            int uid = app.uid;
3605            int[] gids = null;
3606            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3607            if (!app.isolated) {
3608                int[] permGids = null;
3609                try {
3610                    checkTime(startTime, "startProcess: getting gids from package manager");
3611                    final IPackageManager pm = AppGlobals.getPackageManager();
3612                    permGids = pm.getPackageGids(app.info.packageName,
3613                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3614                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3615                            MountServiceInternal.class);
3616                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3617                            app.info.packageName);
3618                } catch (RemoteException e) {
3619                    throw e.rethrowAsRuntimeException();
3620                }
3621
3622                /*
3623                 * Add shared application and profile GIDs so applications can share some
3624                 * resources like shared libraries and access user-wide resources
3625                 */
3626                if (ArrayUtils.isEmpty(permGids)) {
3627                    gids = new int[2];
3628                } else {
3629                    gids = new int[permGids.length + 2];
3630                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3631                }
3632                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3633                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3634            }
3635            checkTime(startTime, "startProcess: building args");
3636            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3637                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3638                        && mTopComponent != null
3639                        && app.processName.equals(mTopComponent.getPackageName())) {
3640                    uid = 0;
3641                }
3642                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3643                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3644                    uid = 0;
3645                }
3646            }
3647            int debugFlags = 0;
3648            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3649                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3650                // Also turn on CheckJNI for debuggable apps. It's quite
3651                // awkward to turn on otherwise.
3652                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3653            }
3654            // Run the app in safe mode if its manifest requests so or the
3655            // system is booted in safe mode.
3656            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3657                mSafeMode == true) {
3658                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3659            }
3660            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3661                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3662            }
3663            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3664            if ("true".equals(genDebugInfoProperty)) {
3665                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3669            }
3670            if ("1".equals(SystemProperties.get("debug.assert"))) {
3671                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3672            }
3673            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3674                // Enable all debug flags required by the native debugger.
3675                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3676                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3677                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3678                mNativeDebuggingApp = null;
3679            }
3680
3681            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3682            if (requiredAbi == null) {
3683                requiredAbi = Build.SUPPORTED_ABIS[0];
3684            }
3685
3686            String instructionSet = null;
3687            if (app.info.primaryCpuAbi != null) {
3688                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3689            }
3690
3691            app.gids = gids;
3692            app.requiredAbi = requiredAbi;
3693            app.instructionSet = instructionSet;
3694
3695            // Start the process.  It will either succeed and return a result containing
3696            // the PID of the new process, or else throw a RuntimeException.
3697            boolean isActivityProcess = (entryPoint == null);
3698            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3699            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3700                    app.processName);
3701            checkTime(startTime, "startProcess: asking zygote to start proc");
3702            Process.ProcessStartResult startResult = Process.start(entryPoint,
3703                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3704                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3705                    app.info.dataDir, entryPointArgs);
3706            checkTime(startTime, "startProcess: returned from zygote!");
3707            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3708
3709            if (app.isolated) {
3710                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3711            }
3712            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3713            checkTime(startTime, "startProcess: done updating battery stats");
3714
3715            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3716                    UserHandle.getUserId(uid), startResult.pid, uid,
3717                    app.processName, hostingType,
3718                    hostingNameStr != null ? hostingNameStr : "");
3719
3720            try {
3721                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3722                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3723            } catch (RemoteException ex) {
3724                // Ignore
3725            }
3726
3727            if (app.persistent) {
3728                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3729            }
3730
3731            checkTime(startTime, "startProcess: building log message");
3732            StringBuilder buf = mStringBuilder;
3733            buf.setLength(0);
3734            buf.append("Start proc ");
3735            buf.append(startResult.pid);
3736            buf.append(':');
3737            buf.append(app.processName);
3738            buf.append('/');
3739            UserHandle.formatUid(buf, uid);
3740            if (!isActivityProcess) {
3741                buf.append(" [");
3742                buf.append(entryPoint);
3743                buf.append("]");
3744            }
3745            buf.append(" for ");
3746            buf.append(hostingType);
3747            if (hostingNameStr != null) {
3748                buf.append(" ");
3749                buf.append(hostingNameStr);
3750            }
3751            Slog.i(TAG, buf.toString());
3752            app.setPid(startResult.pid);
3753            app.usingWrapper = startResult.usingWrapper;
3754            app.removed = false;
3755            app.killed = false;
3756            app.killedByAm = false;
3757            checkTime(startTime, "startProcess: starting to update pids map");
3758            synchronized (mPidsSelfLocked) {
3759                this.mPidsSelfLocked.put(startResult.pid, app);
3760                if (isActivityProcess) {
3761                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3762                    msg.obj = app;
3763                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3764                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3765                }
3766            }
3767            checkTime(startTime, "startProcess: done updating pids map");
3768        } catch (RuntimeException e) {
3769            Slog.e(TAG, "Failure starting process " + app.processName, e);
3770
3771            // Something went very wrong while trying to start this process; one
3772            // common case is when the package is frozen due to an active
3773            // upgrade. To recover, clean up any active bookkeeping related to
3774            // starting this process. (We already invoked this method once when
3775            // the package was initially frozen through KILL_APPLICATION_MSG, so
3776            // it doesn't hurt to use it again.)
3777            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3778                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3779        }
3780    }
3781
3782    void updateUsageStats(ActivityRecord component, boolean resumed) {
3783        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3784                "updateUsageStats: comp=" + component + "res=" + resumed);
3785        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3786        if (resumed) {
3787            if (mUsageStatsService != null) {
3788                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3789                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3790            }
3791            synchronized (stats) {
3792                stats.noteActivityResumedLocked(component.app.uid);
3793            }
3794        } else {
3795            if (mUsageStatsService != null) {
3796                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3798            }
3799            synchronized (stats) {
3800                stats.noteActivityPausedLocked(component.app.uid);
3801            }
3802        }
3803    }
3804
3805    Intent getHomeIntent() {
3806        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3807        intent.setComponent(mTopComponent);
3808        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3809        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3810            intent.addCategory(Intent.CATEGORY_HOME);
3811        }
3812        return intent;
3813    }
3814
3815    boolean startHomeActivityLocked(int userId, String reason) {
3816        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3817                && mTopAction == null) {
3818            // We are running in factory test mode, but unable to find
3819            // the factory test app, so just sit around displaying the
3820            // error message and don't try to start anything.
3821            return false;
3822        }
3823        Intent intent = getHomeIntent();
3824        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3825        if (aInfo != null) {
3826            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3827            // Don't do this if the home app is currently being
3828            // instrumented.
3829            aInfo = new ActivityInfo(aInfo);
3830            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3831            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3832                    aInfo.applicationInfo.uid, true);
3833            if (app == null || app.instrumentationClass == null) {
3834                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3835                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3836            }
3837        } else {
3838            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3839        }
3840
3841        return true;
3842    }
3843
3844    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3845        ActivityInfo ai = null;
3846        ComponentName comp = intent.getComponent();
3847        try {
3848            if (comp != null) {
3849                // Factory test.
3850                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3851            } else {
3852                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3853                        intent,
3854                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3855                        flags, userId);
3856
3857                if (info != null) {
3858                    ai = info.activityInfo;
3859                }
3860            }
3861        } catch (RemoteException e) {
3862            // ignore
3863        }
3864
3865        return ai;
3866    }
3867
3868    /**
3869     * Starts the "new version setup screen" if appropriate.
3870     */
3871    void startSetupActivityLocked() {
3872        // Only do this once per boot.
3873        if (mCheckedForSetup) {
3874            return;
3875        }
3876
3877        // We will show this screen if the current one is a different
3878        // version than the last one shown, and we are not running in
3879        // low-level factory test mode.
3880        final ContentResolver resolver = mContext.getContentResolver();
3881        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3882                Settings.Global.getInt(resolver,
3883                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3884            mCheckedForSetup = true;
3885
3886            // See if we should be showing the platform update setup UI.
3887            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3888            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3889                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3890            if (!ris.isEmpty()) {
3891                final ResolveInfo ri = ris.get(0);
3892                String vers = ri.activityInfo.metaData != null
3893                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3894                        : null;
3895                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3896                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3897                            Intent.METADATA_SETUP_VERSION);
3898                }
3899                String lastVers = Settings.Secure.getString(
3900                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3901                if (vers != null && !vers.equals(lastVers)) {
3902                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3903                    intent.setComponent(new ComponentName(
3904                            ri.activityInfo.packageName, ri.activityInfo.name));
3905                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3906                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3907                            null, 0, 0, 0, null, false, false, null, null, null);
3908                }
3909            }
3910        }
3911    }
3912
3913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3915    }
3916
3917    void enforceNotIsolatedCaller(String caller) {
3918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3919            throw new SecurityException("Isolated process not allowed to call " + caller);
3920        }
3921    }
3922
3923    void enforceShellRestriction(String restriction, int userHandle) {
3924        if (Binder.getCallingUid() == Process.SHELL_UID) {
3925            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3926                throw new SecurityException("Shell does not have permission to access user "
3927                        + userHandle);
3928            }
3929        }
3930    }
3931
3932    @Override
3933    public int getFrontActivityScreenCompatMode() {
3934        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3935        synchronized (this) {
3936            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3937        }
3938    }
3939
3940    @Override
3941    public void setFrontActivityScreenCompatMode(int mode) {
3942        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3943                "setFrontActivityScreenCompatMode");
3944        synchronized (this) {
3945            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3946        }
3947    }
3948
3949    @Override
3950    public int getPackageScreenCompatMode(String packageName) {
3951        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3952        synchronized (this) {
3953            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3954        }
3955    }
3956
3957    @Override
3958    public void setPackageScreenCompatMode(String packageName, int mode) {
3959        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3960                "setPackageScreenCompatMode");
3961        synchronized (this) {
3962            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3963        }
3964    }
3965
3966    @Override
3967    public boolean getPackageAskScreenCompat(String packageName) {
3968        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3969        synchronized (this) {
3970            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3971        }
3972    }
3973
3974    @Override
3975    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3976        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977                "setPackageAskScreenCompat");
3978        synchronized (this) {
3979            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3980        }
3981    }
3982
3983    private boolean hasUsageStatsPermission(String callingPackage) {
3984        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3985                Binder.getCallingUid(), callingPackage);
3986        if (mode == AppOpsManager.MODE_DEFAULT) {
3987            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3988                    == PackageManager.PERMISSION_GRANTED;
3989        }
3990        return mode == AppOpsManager.MODE_ALLOWED;
3991    }
3992
3993    @Override
3994    public int getPackageProcessState(String packageName, String callingPackage) {
3995        if (!hasUsageStatsPermission(callingPackage)) {
3996            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3997                    "getPackageProcessState");
3998        }
3999
4000        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4001        synchronized (this) {
4002            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003                final ProcessRecord proc = mLruProcesses.get(i);
4004                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4005                        || procState > proc.setProcState) {
4006                    boolean found = false;
4007                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4008                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4009                            procState = proc.setProcState;
4010                            found = true;
4011                        }
4012                    }
4013                    if (proc.pkgDeps != null && !found) {
4014                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4015                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4016                                procState = proc.setProcState;
4017                                break;
4018                            }
4019                        }
4020                    }
4021                }
4022            }
4023        }
4024        return procState;
4025    }
4026
4027    @Override
4028    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4029        synchronized (this) {
4030            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4031            if (app == null) {
4032                return false;
4033            }
4034            if (app.trimMemoryLevel < level && app.thread != null &&
4035                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4036                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4037                try {
4038                    app.thread.scheduleTrimMemory(level);
4039                    app.trimMemoryLevel = level;
4040                    return true;
4041                } catch (RemoteException e) {
4042                    // Fallthrough to failure case.
4043                }
4044            }
4045        }
4046        return false;
4047    }
4048
4049    private void dispatchProcessesChanged() {
4050        int N;
4051        synchronized (this) {
4052            N = mPendingProcessChanges.size();
4053            if (mActiveProcessChanges.length < N) {
4054                mActiveProcessChanges = new ProcessChangeItem[N];
4055            }
4056            mPendingProcessChanges.toArray(mActiveProcessChanges);
4057            mPendingProcessChanges.clear();
4058            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059                    "*** Delivering " + N + " process changes");
4060        }
4061
4062        int i = mProcessObservers.beginBroadcast();
4063        while (i > 0) {
4064            i--;
4065            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066            if (observer != null) {
4067                try {
4068                    for (int j=0; j<N; j++) {
4069                        ProcessChangeItem item = mActiveProcessChanges[j];
4070                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073                                    + item.uid + ": " + item.foregroundActivities);
4074                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075                                    item.foregroundActivities);
4076                        }
4077                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080                                    + ": " + item.processState);
4081                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4082                        }
4083                    }
4084                } catch (RemoteException e) {
4085                }
4086            }
4087        }
4088        mProcessObservers.finishBroadcast();
4089
4090        synchronized (this) {
4091            for (int j=0; j<N; j++) {
4092                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4093            }
4094        }
4095    }
4096
4097    private void dispatchProcessDied(int pid, int uid) {
4098        int i = mProcessObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102            if (observer != null) {
4103                try {
4104                    observer.onProcessDied(pid, uid);
4105                } catch (RemoteException e) {
4106                }
4107            }
4108        }
4109        mProcessObservers.finishBroadcast();
4110    }
4111
4112    private void dispatchUidsChanged() {
4113        int N;
4114        synchronized (this) {
4115            N = mPendingUidChanges.size();
4116            if (mActiveUidChanges.length < N) {
4117                mActiveUidChanges = new UidRecord.ChangeItem[N];
4118            }
4119            for (int i=0; i<N; i++) {
4120                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121                mActiveUidChanges[i] = change;
4122                if (change.uidRecord != null) {
4123                    change.uidRecord.pendingChange = null;
4124                    change.uidRecord = null;
4125                }
4126            }
4127            mPendingUidChanges.clear();
4128            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                    "*** Delivering " + N + " uid changes");
4130        }
4131
4132        if (mLocalPowerManager != null) {
4133            for (int j=0; j<N; j++) {
4134                UidRecord.ChangeItem item = mActiveUidChanges[j];
4135                if (item.change == UidRecord.CHANGE_GONE
4136                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4137                    mLocalPowerManager.uidGone(item.uid);
4138                } else {
4139                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4140                }
4141            }
4142        }
4143
4144        int i = mUidObservers.beginBroadcast();
4145        while (i > 0) {
4146            i--;
4147            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4148            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4149            if (observer != null) {
4150                try {
4151                    for (int j=0; j<N; j++) {
4152                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4153                        final int change = item.change;
4154                        UidRecord validateUid = null;
4155                        if (VALIDATE_UID_STATES && i == 0) {
4156                            validateUid = mValidateUids.get(item.uid);
4157                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4158                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4159                                validateUid = new UidRecord(item.uid);
4160                                mValidateUids.put(item.uid, validateUid);
4161                            }
4162                        }
4163                        if (change == UidRecord.CHANGE_IDLE
4164                                || change == UidRecord.CHANGE_GONE_IDLE) {
4165                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4166                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                                        "UID idle uid=" + item.uid);
4168                                observer.onUidIdle(item.uid);
4169                            }
4170                            if (VALIDATE_UID_STATES && i == 0) {
4171                                if (validateUid != null) {
4172                                    validateUid.idle = true;
4173                                }
4174                            }
4175                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4176                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4177                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178                                        "UID active uid=" + item.uid);
4179                                observer.onUidActive(item.uid);
4180                            }
4181                            if (VALIDATE_UID_STATES && i == 0) {
4182                                validateUid.idle = false;
4183                            }
4184                        }
4185                        if (change == UidRecord.CHANGE_GONE
4186                                || change == UidRecord.CHANGE_GONE_IDLE) {
4187                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4188                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4189                                        "UID gone uid=" + item.uid);
4190                                observer.onUidGone(item.uid);
4191                            }
4192                            if (VALIDATE_UID_STATES && i == 0) {
4193                                if (validateUid != null) {
4194                                    mValidateUids.remove(item.uid);
4195                                }
4196                            }
4197                        } else {
4198                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4199                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                                        "UID CHANGED uid=" + item.uid
4201                                                + ": " + item.processState);
4202                                observer.onUidStateChanged(item.uid, item.processState);
4203                            }
4204                            if (VALIDATE_UID_STATES && i == 0) {
4205                                validateUid.curProcState = validateUid.setProcState
4206                                        = item.processState;
4207                            }
4208                        }
4209                    }
4210                } catch (RemoteException e) {
4211                }
4212            }
4213        }
4214        mUidObservers.finishBroadcast();
4215
4216        synchronized (this) {
4217            for (int j=0; j<N; j++) {
4218                mAvailUidChanges.add(mActiveUidChanges[j]);
4219            }
4220        }
4221    }
4222
4223    @Override
4224    public final int startActivity(IApplicationThread caller, String callingPackage,
4225            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4226            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4227        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4228                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4229                UserHandle.getCallingUserId());
4230    }
4231
4232    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4233        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4234        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4235                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4236                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4237
4238        // TODO: Switch to user app stacks here.
4239        String mimeType = intent.getType();
4240        final Uri data = intent.getData();
4241        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4242            mimeType = getProviderMimeType(data, userId);
4243        }
4244        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4245
4246        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4247        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4248                null, 0, 0, null, null, null, null, false, userId, container, null);
4249    }
4250
4251    @Override
4252    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4253            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4254            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4255        enforceNotIsolatedCaller("startActivity");
4256        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4257                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4258        // TODO: Switch to user app stacks here.
4259        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4260                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4261                profilerInfo, null, null, bOptions, false, userId, null, null);
4262    }
4263
4264    @Override
4265    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4268            int userId) {
4269
4270        // This is very dangerous -- it allows you to perform a start activity (including
4271        // permission grants) as any app that may launch one of your own activities.  So
4272        // we will only allow this to be done from activities that are part of the core framework,
4273        // and then only when they are running as the system.
4274        final ActivityRecord sourceRecord;
4275        final int targetUid;
4276        final String targetPackage;
4277        synchronized (this) {
4278            if (resultTo == null) {
4279                throw new SecurityException("Must be called from an activity");
4280            }
4281            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4282            if (sourceRecord == null) {
4283                throw new SecurityException("Called with bad activity token: " + resultTo);
4284            }
4285            if (!sourceRecord.info.packageName.equals("android")) {
4286                throw new SecurityException(
4287                        "Must be called from an activity that is declared in the android package");
4288            }
4289            if (sourceRecord.app == null) {
4290                throw new SecurityException("Called without a process attached to activity");
4291            }
4292            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4293                // This is still okay, as long as this activity is running under the
4294                // uid of the original calling activity.
4295                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4296                    throw new SecurityException(
4297                            "Calling activity in uid " + sourceRecord.app.uid
4298                                    + " must be system uid or original calling uid "
4299                                    + sourceRecord.launchedFromUid);
4300                }
4301            }
4302            if (ignoreTargetSecurity) {
4303                if (intent.getComponent() == null) {
4304                    throw new SecurityException(
4305                            "Component must be specified with ignoreTargetSecurity");
4306                }
4307                if (intent.getSelector() != null) {
4308                    throw new SecurityException(
4309                            "Selector not allowed with ignoreTargetSecurity");
4310                }
4311            }
4312            targetUid = sourceRecord.launchedFromUid;
4313            targetPackage = sourceRecord.launchedFromPackage;
4314        }
4315
4316        if (userId == UserHandle.USER_NULL) {
4317            userId = UserHandle.getUserId(sourceRecord.app.uid);
4318        }
4319
4320        // TODO: Switch to user app stacks here.
4321        try {
4322            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4323                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4324                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4325            return ret;
4326        } catch (SecurityException e) {
4327            // XXX need to figure out how to propagate to original app.
4328            // A SecurityException here is generally actually a fault of the original
4329            // calling activity (such as a fairly granting permissions), so propagate it
4330            // back to them.
4331            /*
4332            StringBuilder msg = new StringBuilder();
4333            msg.append("While launching");
4334            msg.append(intent.toString());
4335            msg.append(": ");
4336            msg.append(e.getMessage());
4337            */
4338            throw e;
4339        }
4340    }
4341
4342    @Override
4343    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4344            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4345            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4346        enforceNotIsolatedCaller("startActivityAndWait");
4347        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4349        WaitResult res = new WaitResult();
4350        // TODO: Switch to user app stacks here.
4351        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4352                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4353                bOptions, false, userId, null, null);
4354        return res;
4355    }
4356
4357    @Override
4358    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360            int startFlags, Configuration config, Bundle bOptions, int userId) {
4361        enforceNotIsolatedCaller("startActivityWithConfig");
4362        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4364        // TODO: Switch to user app stacks here.
4365        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4366                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4367                null, null, config, bOptions, false, userId, null, null);
4368        return ret;
4369    }
4370
4371    @Override
4372    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4373            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4374            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4375            throws TransactionTooLargeException {
4376        enforceNotIsolatedCaller("startActivityIntentSender");
4377        // Refuse possible leaked file descriptors
4378        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4379            throw new IllegalArgumentException("File descriptors passed in Intent");
4380        }
4381
4382        IIntentSender sender = intent.getTarget();
4383        if (!(sender instanceof PendingIntentRecord)) {
4384            throw new IllegalArgumentException("Bad PendingIntent object");
4385        }
4386
4387        PendingIntentRecord pir = (PendingIntentRecord)sender;
4388
4389        synchronized (this) {
4390            // If this is coming from the currently resumed activity, it is
4391            // effectively saying that app switches are allowed at this point.
4392            final ActivityStack stack = getFocusedStack();
4393            if (stack.mResumedActivity != null &&
4394                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4395                mAppSwitchesAllowedTime = 0;
4396            }
4397        }
4398        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4399                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4400        return ret;
4401    }
4402
4403    @Override
4404    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4405            Intent intent, String resolvedType, IVoiceInteractionSession session,
4406            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4407            Bundle bOptions, int userId) {
4408        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4409                != PackageManager.PERMISSION_GRANTED) {
4410            String msg = "Permission Denial: startVoiceActivity() from pid="
4411                    + Binder.getCallingPid()
4412                    + ", uid=" + Binder.getCallingUid()
4413                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4414            Slog.w(TAG, msg);
4415            throw new SecurityException(msg);
4416        }
4417        if (session == null || interactor == null) {
4418            throw new NullPointerException("null session or interactor");
4419        }
4420        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4421                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4422        // TODO: Switch to user app stacks here.
4423        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4424                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4425                null, bOptions, false, userId, null, null);
4426    }
4427
4428    @Override
4429    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4430            throws RemoteException {
4431        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4432        synchronized (this) {
4433            ActivityRecord activity = getFocusedStack().topActivity();
4434            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4435                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4436            }
4437            if (mRunningVoice != null || activity.task.voiceSession != null
4438                    || activity.voiceSession != null) {
4439                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4440                return;
4441            }
4442            if (activity.pendingVoiceInteractionStart) {
4443                Slog.w(TAG, "Pending start of voice interaction already.");
4444                return;
4445            }
4446            activity.pendingVoiceInteractionStart = true;
4447        }
4448        LocalServices.getService(VoiceInteractionManagerInternal.class)
4449                .startLocalVoiceInteraction(callingActivity, options);
4450    }
4451
4452    @Override
4453    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4454        LocalServices.getService(VoiceInteractionManagerInternal.class)
4455                .stopLocalVoiceInteraction(callingActivity);
4456    }
4457
4458    @Override
4459    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4460        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4461                .supportsLocalVoiceInteraction();
4462    }
4463
4464    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4465            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4466        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4467        if (activityToCallback == null) return;
4468        activityToCallback.setVoiceSessionLocked(voiceSession);
4469
4470        // Inform the activity
4471        try {
4472            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4473                    voiceInteractor);
4474            long token = Binder.clearCallingIdentity();
4475            try {
4476                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4477            } finally {
4478                Binder.restoreCallingIdentity(token);
4479            }
4480            // TODO: VI Should we cache the activity so that it's easier to find later
4481            // rather than scan through all the stacks and activities?
4482        } catch (RemoteException re) {
4483            activityToCallback.clearVoiceSessionLocked();
4484            // TODO: VI Should this terminate the voice session?
4485        }
4486    }
4487
4488    @Override
4489    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4490        synchronized (this) {
4491            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4492                if (keepAwake) {
4493                    mVoiceWakeLock.acquire();
4494                } else {
4495                    mVoiceWakeLock.release();
4496                }
4497            }
4498        }
4499    }
4500
4501    @Override
4502    public boolean startNextMatchingActivity(IBinder callingActivity,
4503            Intent intent, Bundle bOptions) {
4504        // Refuse possible leaked file descriptors
4505        if (intent != null && intent.hasFileDescriptors() == true) {
4506            throw new IllegalArgumentException("File descriptors passed in Intent");
4507        }
4508        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4509
4510        synchronized (this) {
4511            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4512            if (r == null) {
4513                ActivityOptions.abort(options);
4514                return false;
4515            }
4516            if (r.app == null || r.app.thread == null) {
4517                // The caller is not running...  d'oh!
4518                ActivityOptions.abort(options);
4519                return false;
4520            }
4521            intent = new Intent(intent);
4522            // The caller is not allowed to change the data.
4523            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4524            // And we are resetting to find the next component...
4525            intent.setComponent(null);
4526
4527            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4528
4529            ActivityInfo aInfo = null;
4530            try {
4531                List<ResolveInfo> resolves =
4532                    AppGlobals.getPackageManager().queryIntentActivities(
4533                            intent, r.resolvedType,
4534                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4535                            UserHandle.getCallingUserId()).getList();
4536
4537                // Look for the original activity in the list...
4538                final int N = resolves != null ? resolves.size() : 0;
4539                for (int i=0; i<N; i++) {
4540                    ResolveInfo rInfo = resolves.get(i);
4541                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4542                            && rInfo.activityInfo.name.equals(r.info.name)) {
4543                        // We found the current one...  the next matching is
4544                        // after it.
4545                        i++;
4546                        if (i<N) {
4547                            aInfo = resolves.get(i).activityInfo;
4548                        }
4549                        if (debug) {
4550                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4551                                    + "/" + r.info.name);
4552                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4553                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4554                        }
4555                        break;
4556                    }
4557                }
4558            } catch (RemoteException e) {
4559            }
4560
4561            if (aInfo == null) {
4562                // Nobody who is next!
4563                ActivityOptions.abort(options);
4564                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4565                return false;
4566            }
4567
4568            intent.setComponent(new ComponentName(
4569                    aInfo.applicationInfo.packageName, aInfo.name));
4570            intent.setFlags(intent.getFlags()&~(
4571                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4572                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4573                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4574                    Intent.FLAG_ACTIVITY_NEW_TASK));
4575
4576            // Okay now we need to start the new activity, replacing the
4577            // currently running activity.  This is a little tricky because
4578            // we want to start the new one as if the current one is finished,
4579            // but not finish the current one first so that there is no flicker.
4580            // And thus...
4581            final boolean wasFinishing = r.finishing;
4582            r.finishing = true;
4583
4584            // Propagate reply information over to the new activity.
4585            final ActivityRecord resultTo = r.resultTo;
4586            final String resultWho = r.resultWho;
4587            final int requestCode = r.requestCode;
4588            r.resultTo = null;
4589            if (resultTo != null) {
4590                resultTo.removeResultsLocked(r, resultWho, requestCode);
4591            }
4592
4593            final long origId = Binder.clearCallingIdentity();
4594            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4595                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4596                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4597                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4598                    false, false, null, null, null);
4599            Binder.restoreCallingIdentity(origId);
4600
4601            r.finishing = wasFinishing;
4602            if (res != ActivityManager.START_SUCCESS) {
4603                return false;
4604            }
4605            return true;
4606        }
4607    }
4608
4609    @Override
4610    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4611        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4612            String msg = "Permission Denial: startActivityFromRecents called without " +
4613                    START_TASKS_FROM_RECENTS;
4614            Slog.w(TAG, msg);
4615            throw new SecurityException(msg);
4616        }
4617        final long origId = Binder.clearCallingIdentity();
4618        try {
4619            synchronized (this) {
4620                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    final int startActivityInPackage(int uid, String callingPackage,
4628            Intent intent, String resolvedType, IBinder resultTo,
4629            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4630            IActivityContainer container, TaskRecord inTask) {
4631
4632        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4633                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4634
4635        // TODO: Switch to user app stacks here.
4636        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4637                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4638                null, null, null, bOptions, false, userId, container, inTask);
4639        return ret;
4640    }
4641
4642    @Override
4643    public final int startActivities(IApplicationThread caller, String callingPackage,
4644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4645            int userId) {
4646        enforceNotIsolatedCaller("startActivities");
4647        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4648                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4649        // TODO: Switch to user app stacks here.
4650        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4651                resolvedTypes, resultTo, bOptions, userId);
4652        return ret;
4653    }
4654
4655    final int startActivitiesInPackage(int uid, String callingPackage,
4656            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4657            Bundle bOptions, int userId) {
4658
4659        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4660                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4661        // TODO: Switch to user app stacks here.
4662        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4663                resultTo, bOptions, userId);
4664        return ret;
4665    }
4666
4667    @Override
4668    public void reportActivityFullyDrawn(IBinder token) {
4669        synchronized (this) {
4670            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671            if (r == null) {
4672                return;
4673            }
4674            r.reportFullyDrawnLocked();
4675        }
4676    }
4677
4678    @Override
4679    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4680        synchronized (this) {
4681            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682            if (r == null) {
4683                return;
4684            }
4685            TaskRecord task = r.task;
4686            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4687                // Fixed screen orientation isn't supported when activities aren't in full screen
4688                // mode.
4689                return;
4690            }
4691            final long origId = Binder.clearCallingIdentity();
4692            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4693            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4694                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4695            if (config != null) {
4696                r.frozenBeforeDestroy = true;
4697                if (!updateConfigurationLocked(config, r, false)) {
4698                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4699                }
4700            }
4701            Binder.restoreCallingIdentity(origId);
4702        }
4703    }
4704
4705    @Override
4706    public int getRequestedOrientation(IBinder token) {
4707        synchronized (this) {
4708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4709            if (r == null) {
4710                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4711            }
4712            return mWindowManager.getAppOrientation(r.appToken);
4713        }
4714    }
4715
4716    /**
4717     * This is the internal entry point for handling Activity.finish().
4718     *
4719     * @param token The Binder token referencing the Activity we want to finish.
4720     * @param resultCode Result code, if any, from this Activity.
4721     * @param resultData Result data (Intent), if any, from this Activity.
4722     * @param finishTask Whether to finish the task associated with this Activity.
4723     *
4724     * @return Returns true if the activity successfully finished, or false if it is still running.
4725     */
4726    @Override
4727    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4728            int finishTask) {
4729        // Refuse possible leaked file descriptors
4730        if (resultData != null && resultData.hasFileDescriptors() == true) {
4731            throw new IllegalArgumentException("File descriptors passed in Intent");
4732        }
4733
4734        synchronized(this) {
4735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736            if (r == null) {
4737                return true;
4738            }
4739            // Keep track of the root activity of the task before we finish it
4740            TaskRecord tr = r.task;
4741            ActivityRecord rootR = tr.getRootActivity();
4742            if (rootR == null) {
4743                Slog.w(TAG, "Finishing task with all activities already finished");
4744            }
4745            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4746            // finish.
4747            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4748                    mStackSupervisor.isLastLockedTask(tr)) {
4749                Slog.i(TAG, "Not finishing task in lock task mode");
4750                mStackSupervisor.showLockTaskToast();
4751                return false;
4752            }
4753            if (mController != null) {
4754                // Find the first activity that is not finishing.
4755                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4756                if (next != null) {
4757                    // ask watcher if this is allowed
4758                    boolean resumeOK = true;
4759                    try {
4760                        resumeOK = mController.activityResuming(next.packageName);
4761                    } catch (RemoteException e) {
4762                        mController = null;
4763                        Watchdog.getInstance().setActivityController(null);
4764                    }
4765
4766                    if (!resumeOK) {
4767                        Slog.i(TAG, "Not finishing activity because controller resumed");
4768                        return false;
4769                    }
4770                }
4771            }
4772            final long origId = Binder.clearCallingIdentity();
4773            try {
4774                boolean res;
4775                final boolean finishWithRootActivity =
4776                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4777                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4778                        || (finishWithRootActivity && r == rootR)) {
4779                    // If requested, remove the task that is associated to this activity only if it
4780                    // was the root activity in the task. The result code and data is ignored
4781                    // because we don't support returning them across task boundaries. Also, to
4782                    // keep backwards compatibility we remove the task from recents when finishing
4783                    // task with root activity.
4784                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4785                    if (!res) {
4786                        Slog.i(TAG, "Removing task failed to finish activity");
4787                    }
4788                } else {
4789                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4790                            resultData, "app-request", true);
4791                    if (!res) {
4792                        Slog.i(TAG, "Failed to finish by app-request");
4793                    }
4794                }
4795                return res;
4796            } finally {
4797                Binder.restoreCallingIdentity(origId);
4798            }
4799        }
4800    }
4801
4802    @Override
4803    public final void finishHeavyWeightApp() {
4804        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805                != PackageManager.PERMISSION_GRANTED) {
4806            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4807                    + Binder.getCallingPid()
4808                    + ", uid=" + Binder.getCallingUid()
4809                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4810            Slog.w(TAG, msg);
4811            throw new SecurityException(msg);
4812        }
4813
4814        synchronized(this) {
4815            if (mHeavyWeightProcess == null) {
4816                return;
4817            }
4818
4819            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4820            for (int i = 0; i < activities.size(); i++) {
4821                ActivityRecord r = activities.get(i);
4822                if (!r.finishing && r.isInStackLocked()) {
4823                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4824                            null, "finish-heavy", true);
4825                }
4826            }
4827
4828            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4829                    mHeavyWeightProcess.userId, 0));
4830            mHeavyWeightProcess = null;
4831        }
4832    }
4833
4834    @Override
4835    public void crashApplication(int uid, int initialPid, String packageName,
4836            String message) {
4837        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4838                != PackageManager.PERMISSION_GRANTED) {
4839            String msg = "Permission Denial: crashApplication() from pid="
4840                    + Binder.getCallingPid()
4841                    + ", uid=" + Binder.getCallingUid()
4842                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4843            Slog.w(TAG, msg);
4844            throw new SecurityException(msg);
4845        }
4846
4847        synchronized(this) {
4848            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4849        }
4850    }
4851
4852    @Override
4853    public final void finishSubActivity(IBinder token, String resultWho,
4854            int requestCode) {
4855        synchronized(this) {
4856            final long origId = Binder.clearCallingIdentity();
4857            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4858            if (r != null) {
4859                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4860            }
4861            Binder.restoreCallingIdentity(origId);
4862        }
4863    }
4864
4865    @Override
4866    public boolean finishActivityAffinity(IBinder token) {
4867        synchronized(this) {
4868            final long origId = Binder.clearCallingIdentity();
4869            try {
4870                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4871                if (r == null) {
4872                    return false;
4873                }
4874
4875                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4876                // can finish.
4877                final TaskRecord task = r.task;
4878                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4879                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4880                    mStackSupervisor.showLockTaskToast();
4881                    return false;
4882                }
4883                return task.stack.finishActivityAffinityLocked(r);
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void finishVoiceTask(IVoiceInteractionSession session) {
4892        synchronized (this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                // TODO: VI Consider treating local voice interactions and voice tasks
4896                // differently here
4897                mStackSupervisor.finishVoiceTask(session);
4898            } finally {
4899                Binder.restoreCallingIdentity(origId);
4900            }
4901        }
4902
4903    }
4904
4905    @Override
4906    public boolean releaseActivityInstance(IBinder token) {
4907        synchronized(this) {
4908            final long origId = Binder.clearCallingIdentity();
4909            try {
4910                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911                if (r == null) {
4912                    return false;
4913                }
4914                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4915            } finally {
4916                Binder.restoreCallingIdentity(origId);
4917            }
4918        }
4919    }
4920
4921    @Override
4922    public void releaseSomeActivities(IApplicationThread appInt) {
4923        synchronized(this) {
4924            final long origId = Binder.clearCallingIdentity();
4925            try {
4926                ProcessRecord app = getRecordForAppLocked(appInt);
4927                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4928            } finally {
4929                Binder.restoreCallingIdentity(origId);
4930            }
4931        }
4932    }
4933
4934    @Override
4935    public boolean willActivityBeVisible(IBinder token) {
4936        synchronized(this) {
4937            ActivityStack stack = ActivityRecord.getStackLocked(token);
4938            if (stack != null) {
4939                return stack.willActivityBeVisibleLocked(token);
4940            }
4941            return false;
4942        }
4943    }
4944
4945    @Override
4946    public void overridePendingTransition(IBinder token, String packageName,
4947            int enterAnim, int exitAnim) {
4948        synchronized(this) {
4949            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4950            if (self == null) {
4951                return;
4952            }
4953
4954            final long origId = Binder.clearCallingIdentity();
4955
4956            if (self.state == ActivityState.RESUMED
4957                    || self.state == ActivityState.PAUSING) {
4958                mWindowManager.overridePendingAppTransition(packageName,
4959                        enterAnim, exitAnim, null);
4960            }
4961
4962            Binder.restoreCallingIdentity(origId);
4963        }
4964    }
4965
4966    /**
4967     * Main function for removing an existing process from the activity manager
4968     * as a result of that process going away.  Clears out all connections
4969     * to the process.
4970     */
4971    private final void handleAppDiedLocked(ProcessRecord app,
4972            boolean restarting, boolean allowRestart) {
4973        int pid = app.pid;
4974        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4975        if (!kept && !restarting) {
4976            removeLruProcessLocked(app);
4977            if (pid > 0) {
4978                ProcessList.remove(pid);
4979            }
4980        }
4981
4982        if (mProfileProc == app) {
4983            clearProfilerLocked();
4984        }
4985
4986        // Remove this application's activities from active lists.
4987        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4988
4989        app.activities.clear();
4990
4991        if (app.instrumentationClass != null) {
4992            Slog.w(TAG, "Crash of app " + app.processName
4993                  + " running instrumentation " + app.instrumentationClass);
4994            Bundle info = new Bundle();
4995            info.putString("shortMsg", "Process crashed.");
4996            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4997        }
4998
4999        if (!restarting && hasVisibleActivities
5000                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5001            // If there was nothing to resume, and we are not already restarting this process, but
5002            // there is a visible activity that is hosted by the process...  then make sure all
5003            // visible activities are running, taking care of restarting this process.
5004            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5005        }
5006    }
5007
5008    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5009        IBinder threadBinder = thread.asBinder();
5010        // Find the application record.
5011        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012            ProcessRecord rec = mLruProcesses.get(i);
5013            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5014                return i;
5015            }
5016        }
5017        return -1;
5018    }
5019
5020    final ProcessRecord getRecordForAppLocked(
5021            IApplicationThread thread) {
5022        if (thread == null) {
5023            return null;
5024        }
5025
5026        int appIndex = getLRURecordIndexForAppLocked(thread);
5027        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5028    }
5029
5030    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5031        // If there are no longer any background processes running,
5032        // and the app that died was not running instrumentation,
5033        // then tell everyone we are now low on memory.
5034        boolean haveBg = false;
5035        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036            ProcessRecord rec = mLruProcesses.get(i);
5037            if (rec.thread != null
5038                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5039                haveBg = true;
5040                break;
5041            }
5042        }
5043
5044        if (!haveBg) {
5045            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5046            if (doReport) {
5047                long now = SystemClock.uptimeMillis();
5048                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5049                    doReport = false;
5050                } else {
5051                    mLastMemUsageReportTime = now;
5052                }
5053            }
5054            final ArrayList<ProcessMemInfo> memInfos
5055                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5056            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5057            long now = SystemClock.uptimeMillis();
5058            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059                ProcessRecord rec = mLruProcesses.get(i);
5060                if (rec == dyingProc || rec.thread == null) {
5061                    continue;
5062                }
5063                if (doReport) {
5064                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5065                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5066                }
5067                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5068                    // The low memory report is overriding any current
5069                    // state for a GC request.  Make sure to do
5070                    // heavy/important/visible/foreground processes first.
5071                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5072                        rec.lastRequestedGc = 0;
5073                    } else {
5074                        rec.lastRequestedGc = rec.lastLowMemory;
5075                    }
5076                    rec.reportLowMemory = true;
5077                    rec.lastLowMemory = now;
5078                    mProcessesToGc.remove(rec);
5079                    addProcessToGcListLocked(rec);
5080                }
5081            }
5082            if (doReport) {
5083                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5084                mHandler.sendMessage(msg);
5085            }
5086            scheduleAppGcsLocked();
5087        }
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app) {
5091       appDiedLocked(app, app.pid, app.thread, false);
5092    }
5093
5094    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5095            boolean fromBinderDied) {
5096        // First check if this ProcessRecord is actually active for the pid.
5097        synchronized (mPidsSelfLocked) {
5098            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5099            if (curProc != app) {
5100                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5101                return;
5102            }
5103        }
5104
5105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5106        synchronized (stats) {
5107            stats.noteProcessDiedLocked(app.info.uid, pid);
5108        }
5109
5110        if (!app.killed) {
5111            if (!fromBinderDied) {
5112                Process.killProcessQuiet(pid);
5113            }
5114            killProcessGroup(app.uid, pid);
5115            app.killed = true;
5116        }
5117
5118        // Clean up already done if the process has been re-started.
5119        if (app.pid == pid && app.thread != null &&
5120                app.thread.asBinder() == thread.asBinder()) {
5121            boolean doLowMem = app.instrumentationClass == null;
5122            boolean doOomAdj = doLowMem;
5123            if (!app.killedByAm) {
5124                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5125                        + ") has died");
5126                mAllowLowerMemLevel = true;
5127            } else {
5128                // Note that we always want to do oom adj to update our state with the
5129                // new number of procs.
5130                mAllowLowerMemLevel = false;
5131                doLowMem = false;
5132            }
5133            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5134            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5135                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5136            handleAppDiedLocked(app, false, true);
5137
5138            if (doOomAdj) {
5139                updateOomAdjLocked();
5140            }
5141            if (doLowMem) {
5142                doLowMemReportIfNeededLocked(app);
5143            }
5144        } else if (app.pid != pid) {
5145            // A new process has already been started.
5146            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5147                    + ") has died and restarted (pid " + app.pid + ").");
5148            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5149        } else if (DEBUG_PROCESSES) {
5150            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5151                    + thread.asBinder());
5152        }
5153    }
5154
5155    /**
5156     * If a stack trace dump file is configured, dump process stack traces.
5157     * @param clearTraces causes the dump file to be erased prior to the new
5158     *    traces being written, if true; when false, the new traces will be
5159     *    appended to any existing file content.
5160     * @param firstPids of dalvik VM processes to dump stack traces for first
5161     * @param lastPids of dalvik VM processes to dump stack traces for last
5162     * @param nativeProcs optional list of native process names to dump stack crawls
5163     * @return file containing stack traces, or null if no dump file is configured
5164     */
5165    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5166            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5167        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5168        if (tracesPath == null || tracesPath.length() == 0) {
5169            return null;
5170        }
5171
5172        File tracesFile = new File(tracesPath);
5173        try {
5174            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5175            tracesFile.createNewFile();
5176            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5177        } catch (IOException e) {
5178            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5179            return null;
5180        }
5181
5182        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5183        return tracesFile;
5184    }
5185
5186    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5188        // Use a FileObserver to detect when traces finish writing.
5189        // The order of traces is considered important to maintain for legibility.
5190        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5191            @Override
5192            public synchronized void onEvent(int event, String path) { notify(); }
5193        };
5194
5195        try {
5196            observer.startWatching();
5197
5198            // First collect all of the stacks of the most important pids.
5199            if (firstPids != null) {
5200                try {
5201                    int num = firstPids.size();
5202                    for (int i = 0; i < num; i++) {
5203                        synchronized (observer) {
5204                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5205                                    + firstPids.get(i));
5206                            final long sime = SystemClock.elapsedRealtime();
5207                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5208                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5209                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5210                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5211                        }
5212                    }
5213                } catch (InterruptedException e) {
5214                    Slog.wtf(TAG, e);
5215                }
5216            }
5217
5218            // Next collect the stacks of the native pids
5219            if (nativeProcs != null) {
5220                int[] pids = Process.getPidsForCommands(nativeProcs);
5221                if (pids != null) {
5222                    for (int pid : pids) {
5223                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5224                        final long sime = SystemClock.elapsedRealtime();
5225                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5226                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5227                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5228                    }
5229                }
5230            }
5231
5232            // Lastly, measure CPU usage.
5233            if (processCpuTracker != null) {
5234                processCpuTracker.init();
5235                System.gc();
5236                processCpuTracker.update();
5237                try {
5238                    synchronized (processCpuTracker) {
5239                        processCpuTracker.wait(500); // measure over 1/2 second.
5240                    }
5241                } catch (InterruptedException e) {
5242                }
5243                processCpuTracker.update();
5244
5245                // We'll take the stack crawls of just the top apps using CPU.
5246                final int N = processCpuTracker.countWorkingStats();
5247                int numProcs = 0;
5248                for (int i=0; i<N && numProcs<5; i++) {
5249                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5250                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5251                        numProcs++;
5252                        try {
5253                            synchronized (observer) {
5254                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5255                                        + stats.pid);
5256                                final long stime = SystemClock.elapsedRealtime();
5257                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5258                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5259                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5260                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5261                            }
5262                        } catch (InterruptedException e) {
5263                            Slog.wtf(TAG, e);
5264                        }
5265                    } else if (DEBUG_ANR) {
5266                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5267                                + stats.pid);
5268                    }
5269                }
5270            }
5271        } finally {
5272            observer.stopWatching();
5273        }
5274    }
5275
5276    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5277        if (true || IS_USER_BUILD) {
5278            return;
5279        }
5280        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5281        if (tracesPath == null || tracesPath.length() == 0) {
5282            return;
5283        }
5284
5285        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5286        StrictMode.allowThreadDiskWrites();
5287        try {
5288            final File tracesFile = new File(tracesPath);
5289            final File tracesDir = tracesFile.getParentFile();
5290            final File tracesTmp = new File(tracesDir, "__tmp__");
5291            try {
5292                if (tracesFile.exists()) {
5293                    tracesTmp.delete();
5294                    tracesFile.renameTo(tracesTmp);
5295                }
5296                StringBuilder sb = new StringBuilder();
5297                Time tobj = new Time();
5298                tobj.set(System.currentTimeMillis());
5299                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5300                sb.append(": ");
5301                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5302                sb.append(" since ");
5303                sb.append(msg);
5304                FileOutputStream fos = new FileOutputStream(tracesFile);
5305                fos.write(sb.toString().getBytes());
5306                if (app == null) {
5307                    fos.write("\n*** No application process!".getBytes());
5308                }
5309                fos.close();
5310                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311            } catch (IOException e) {
5312                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5313                return;
5314            }
5315
5316            if (app != null) {
5317                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5318                firstPids.add(app.pid);
5319                dumpStackTraces(tracesPath, firstPids, null, null, null);
5320            }
5321
5322            File lastTracesFile = null;
5323            File curTracesFile = null;
5324            for (int i=9; i>=0; i--) {
5325                String name = String.format(Locale.US, "slow%02d.txt", i);
5326                curTracesFile = new File(tracesDir, name);
5327                if (curTracesFile.exists()) {
5328                    if (lastTracesFile != null) {
5329                        curTracesFile.renameTo(lastTracesFile);
5330                    } else {
5331                        curTracesFile.delete();
5332                    }
5333                }
5334                lastTracesFile = curTracesFile;
5335            }
5336            tracesFile.renameTo(curTracesFile);
5337            if (tracesTmp.exists()) {
5338                tracesTmp.renameTo(tracesFile);
5339            }
5340        } finally {
5341            StrictMode.setThreadPolicy(oldPolicy);
5342        }
5343    }
5344
5345    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5346        if (!mLaunchWarningShown) {
5347            mLaunchWarningShown = true;
5348            mUiHandler.post(new Runnable() {
5349                @Override
5350                public void run() {
5351                    synchronized (ActivityManagerService.this) {
5352                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5353                        d.show();
5354                        mUiHandler.postDelayed(new Runnable() {
5355                            @Override
5356                            public void run() {
5357                                synchronized (ActivityManagerService.this) {
5358                                    d.dismiss();
5359                                    mLaunchWarningShown = false;
5360                                }
5361                            }
5362                        }, 4000);
5363                    }
5364                }
5365            });
5366        }
5367    }
5368
5369    @Override
5370    public boolean clearApplicationUserData(final String packageName,
5371            final IPackageDataObserver observer, int userId) {
5372        enforceNotIsolatedCaller("clearApplicationUserData");
5373        int uid = Binder.getCallingUid();
5374        int pid = Binder.getCallingPid();
5375        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5376                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5377
5378        final DevicePolicyManagerInternal dpmi = LocalServices
5379                .getService(DevicePolicyManagerInternal.class);
5380        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5381            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5382        }
5383
5384        long callingId = Binder.clearCallingIdentity();
5385        try {
5386            IPackageManager pm = AppGlobals.getPackageManager();
5387            int pkgUid = -1;
5388            synchronized(this) {
5389                try {
5390                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5391                } catch (RemoteException e) {
5392                }
5393                if (pkgUid == -1) {
5394                    Slog.w(TAG, "Invalid packageName: " + packageName);
5395                    if (observer != null) {
5396                        try {
5397                            observer.onRemoveCompleted(packageName, false);
5398                        } catch (RemoteException e) {
5399                            Slog.i(TAG, "Observer no longer exists.");
5400                        }
5401                    }
5402                    return false;
5403                }
5404                if (uid == pkgUid || checkComponentPermission(
5405                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5406                        pid, uid, -1, true)
5407                        == PackageManager.PERMISSION_GRANTED) {
5408                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5409                } else {
5410                    throw new SecurityException("PID " + pid + " does not have permission "
5411                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5412                                    + " of package " + packageName);
5413                }
5414
5415                // Remove all tasks match the cleared application package and user
5416                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5417                    final TaskRecord tr = mRecentTasks.get(i);
5418                    final String taskPackageName =
5419                            tr.getBaseIntent().getComponent().getPackageName();
5420                    if (tr.userId != userId) continue;
5421                    if (!taskPackageName.equals(packageName)) continue;
5422                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5423                }
5424            }
5425
5426            final int pkgUidF = pkgUid;
5427            final int userIdF = userId;
5428            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5429                @Override
5430                public void onRemoveCompleted(String packageName, boolean succeeded)
5431                        throws RemoteException {
5432                    synchronized (ActivityManagerService.this) {
5433                        finishForceStopPackageLocked(packageName, pkgUidF);
5434                    }
5435
5436                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437                            Uri.fromParts("package", packageName, null));
5438                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5439                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5440                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441                            null, null, 0, null, null, null, null, false, false, userIdF);
5442
5443                    if (observer != null) {
5444                        observer.onRemoveCompleted(packageName, succeeded);
5445                    }
5446                }
5447            };
5448
5449            try {
5450                // Clear application user data
5451                pm.clearApplicationUserData(packageName, localObserver, userId);
5452
5453                synchronized(this) {
5454                    // Remove all permissions granted from/to this package
5455                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5456                }
5457
5458                // Remove all zen rules created by this package; revoke it's zen access.
5459                INotificationManager inm = NotificationManager.getService();
5460                inm.removeAutomaticZenRules(packageName);
5461                inm.setNotificationPolicyAccessGranted(packageName, false);
5462
5463            } catch (RemoteException e) {
5464            }
5465        } finally {
5466            Binder.restoreCallingIdentity(callingId);
5467        }
5468        return true;
5469    }
5470
5471    @Override
5472    public void killBackgroundProcesses(final String packageName, int userId) {
5473        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5474                != PackageManager.PERMISSION_GRANTED &&
5475                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5476                        != PackageManager.PERMISSION_GRANTED) {
5477            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5478                    + Binder.getCallingPid()
5479                    + ", uid=" + Binder.getCallingUid()
5480                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5481            Slog.w(TAG, msg);
5482            throw new SecurityException(msg);
5483        }
5484
5485        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5486                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5487        long callingId = Binder.clearCallingIdentity();
5488        try {
5489            IPackageManager pm = AppGlobals.getPackageManager();
5490            synchronized(this) {
5491                int appId = -1;
5492                try {
5493                    appId = UserHandle.getAppId(
5494                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5495                } catch (RemoteException e) {
5496                }
5497                if (appId == -1) {
5498                    Slog.w(TAG, "Invalid packageName: " + packageName);
5499                    return;
5500                }
5501                killPackageProcessesLocked(packageName, appId, userId,
5502                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507    }
5508
5509    @Override
5510    public void killAllBackgroundProcesses() {
5511        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5512                != PackageManager.PERMISSION_GRANTED) {
5513            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5514                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5515                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5516            Slog.w(TAG, msg);
5517            throw new SecurityException(msg);
5518        }
5519
5520        final long callingId = Binder.clearCallingIdentity();
5521        try {
5522            synchronized (this) {
5523                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5524                final int NP = mProcessNames.getMap().size();
5525                for (int ip = 0; ip < NP; ip++) {
5526                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5527                    final int NA = apps.size();
5528                    for (int ia = 0; ia < NA; ia++) {
5529                        final ProcessRecord app = apps.valueAt(ia);
5530                        if (app.persistent) {
5531                            // We don't kill persistent processes.
5532                            continue;
5533                        }
5534                        if (app.removed) {
5535                            procs.add(app);
5536                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5537                            app.removed = true;
5538                            procs.add(app);
5539                        }
5540                    }
5541                }
5542
5543                final int N = procs.size();
5544                for (int i = 0; i < N; i++) {
5545                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5546                }
5547
5548                mAllowLowerMemLevel = true;
5549
5550                updateOomAdjLocked();
5551                doLowMemReportIfNeededLocked(null);
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(callingId);
5555        }
5556    }
5557
5558    /**
5559     * Kills all background processes, except those matching any of the
5560     * specified properties.
5561     *
5562     * @param minTargetSdk the target SDK version at or above which to preserve
5563     *                     processes, or {@code -1} to ignore the target SDK
5564     * @param maxProcState the process state at or below which to preserve
5565     *                     processes, or {@code -1} to ignore the process state
5566     */
5567    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5568        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5569                != PackageManager.PERMISSION_GRANTED) {
5570            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5571                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5572                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5573            Slog.w(TAG, msg);
5574            throw new SecurityException(msg);
5575        }
5576
5577        final long callingId = Binder.clearCallingIdentity();
5578        try {
5579            synchronized (this) {
5580                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5581                final int NP = mProcessNames.getMap().size();
5582                for (int ip = 0; ip < NP; ip++) {
5583                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584                    final int NA = apps.size();
5585                    for (int ia = 0; ia < NA; ia++) {
5586                        final ProcessRecord app = apps.valueAt(ia);
5587                        if (app.removed) {
5588                            procs.add(app);
5589                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5590                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5591                            app.removed = true;
5592                            procs.add(app);
5593                        }
5594                    }
5595                }
5596
5597                final int N = procs.size();
5598                for (int i = 0; i < N; i++) {
5599                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5600                }
5601            }
5602        } finally {
5603            Binder.restoreCallingIdentity(callingId);
5604        }
5605    }
5606
5607    @Override
5608    public void forceStopPackage(final String packageName, int userId) {
5609        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5610                != PackageManager.PERMISSION_GRANTED) {
5611            String msg = "Permission Denial: forceStopPackage() from pid="
5612                    + Binder.getCallingPid()
5613                    + ", uid=" + Binder.getCallingUid()
5614                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5615            Slog.w(TAG, msg);
5616            throw new SecurityException(msg);
5617        }
5618        final int callingPid = Binder.getCallingPid();
5619        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5620                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5621        long callingId = Binder.clearCallingIdentity();
5622        try {
5623            IPackageManager pm = AppGlobals.getPackageManager();
5624            synchronized(this) {
5625                int[] users = userId == UserHandle.USER_ALL
5626                        ? mUserController.getUsers() : new int[] { userId };
5627                for (int user : users) {
5628                    int pkgUid = -1;
5629                    try {
5630                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5631                                user);
5632                    } catch (RemoteException e) {
5633                    }
5634                    if (pkgUid == -1) {
5635                        Slog.w(TAG, "Invalid packageName: " + packageName);
5636                        continue;
5637                    }
5638                    try {
5639                        pm.setPackageStoppedState(packageName, true, user);
5640                    } catch (RemoteException e) {
5641                    } catch (IllegalArgumentException e) {
5642                        Slog.w(TAG, "Failed trying to unstop package "
5643                                + packageName + ": " + e);
5644                    }
5645                    if (mUserController.isUserRunningLocked(user, 0)) {
5646                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5647                        finishForceStopPackageLocked(packageName, pkgUid);
5648                    }
5649                }
5650            }
5651        } finally {
5652            Binder.restoreCallingIdentity(callingId);
5653        }
5654    }
5655
5656    @Override
5657    public void addPackageDependency(String packageName) {
5658        synchronized (this) {
5659            int callingPid = Binder.getCallingPid();
5660            if (callingPid == Process.myPid()) {
5661                //  Yeah, um, no.
5662                return;
5663            }
5664            ProcessRecord proc;
5665            synchronized (mPidsSelfLocked) {
5666                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5667            }
5668            if (proc != null) {
5669                if (proc.pkgDeps == null) {
5670                    proc.pkgDeps = new ArraySet<String>(1);
5671                }
5672                proc.pkgDeps.add(packageName);
5673            }
5674        }
5675    }
5676
5677    /*
5678     * The pkg name and app id have to be specified.
5679     */
5680    @Override
5681    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5682        if (pkg == null) {
5683            return;
5684        }
5685        // Make sure the uid is valid.
5686        if (appid < 0) {
5687            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5688            return;
5689        }
5690        int callerUid = Binder.getCallingUid();
5691        // Only the system server can kill an application
5692        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5693            // Post an aysnc message to kill the application
5694            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5695            msg.arg1 = appid;
5696            msg.arg2 = 0;
5697            Bundle bundle = new Bundle();
5698            bundle.putString("pkg", pkg);
5699            bundle.putString("reason", reason);
5700            msg.obj = bundle;
5701            mHandler.sendMessage(msg);
5702        } else {
5703            throw new SecurityException(callerUid + " cannot kill pkg: " +
5704                    pkg);
5705        }
5706    }
5707
5708    @Override
5709    public void closeSystemDialogs(String reason) {
5710        enforceNotIsolatedCaller("closeSystemDialogs");
5711
5712        final int pid = Binder.getCallingPid();
5713        final int uid = Binder.getCallingUid();
5714        final long origId = Binder.clearCallingIdentity();
5715        try {
5716            synchronized (this) {
5717                // Only allow this from foreground processes, so that background
5718                // applications can't abuse it to prevent system UI from being shown.
5719                if (uid >= Process.FIRST_APPLICATION_UID) {
5720                    ProcessRecord proc;
5721                    synchronized (mPidsSelfLocked) {
5722                        proc = mPidsSelfLocked.get(pid);
5723                    }
5724                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5725                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5726                                + " from background process " + proc);
5727                        return;
5728                    }
5729                }
5730                closeSystemDialogsLocked(reason);
5731            }
5732        } finally {
5733            Binder.restoreCallingIdentity(origId);
5734        }
5735    }
5736
5737    void closeSystemDialogsLocked(String reason) {
5738        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5740                | Intent.FLAG_RECEIVER_FOREGROUND);
5741        if (reason != null) {
5742            intent.putExtra("reason", reason);
5743        }
5744        mWindowManager.closeSystemDialogs(reason);
5745
5746        mStackSupervisor.closeSystemDialogsLocked();
5747
5748        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5749                AppOpsManager.OP_NONE, null, false, false,
5750                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5751    }
5752
5753    @Override
5754    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5755        enforceNotIsolatedCaller("getProcessMemoryInfo");
5756        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5757        for (int i=pids.length-1; i>=0; i--) {
5758            ProcessRecord proc;
5759            int oomAdj;
5760            synchronized (this) {
5761                synchronized (mPidsSelfLocked) {
5762                    proc = mPidsSelfLocked.get(pids[i]);
5763                    oomAdj = proc != null ? proc.setAdj : 0;
5764                }
5765            }
5766            infos[i] = new Debug.MemoryInfo();
5767            Debug.getMemoryInfo(pids[i], infos[i]);
5768            if (proc != null) {
5769                synchronized (this) {
5770                    if (proc.thread != null && proc.setAdj == oomAdj) {
5771                        // Record this for posterity if the process has been stable.
5772                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5773                                infos[i].getTotalUss(), false, proc.pkgList);
5774                    }
5775                }
5776            }
5777        }
5778        return infos;
5779    }
5780
5781    @Override
5782    public long[] getProcessPss(int[] pids) {
5783        enforceNotIsolatedCaller("getProcessPss");
5784        long[] pss = new long[pids.length];
5785        for (int i=pids.length-1; i>=0; i--) {
5786            ProcessRecord proc;
5787            int oomAdj;
5788            synchronized (this) {
5789                synchronized (mPidsSelfLocked) {
5790                    proc = mPidsSelfLocked.get(pids[i]);
5791                    oomAdj = proc != null ? proc.setAdj : 0;
5792                }
5793            }
5794            long[] tmpUss = new long[1];
5795            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5796            if (proc != null) {
5797                synchronized (this) {
5798                    if (proc.thread != null && proc.setAdj == oomAdj) {
5799                        // Record this for posterity if the process has been stable.
5800                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5801                    }
5802                }
5803            }
5804        }
5805        return pss;
5806    }
5807
5808    @Override
5809    public void killApplicationProcess(String processName, int uid) {
5810        if (processName == null) {
5811            return;
5812        }
5813
5814        int callerUid = Binder.getCallingUid();
5815        // Only the system server can kill an application
5816        if (callerUid == Process.SYSTEM_UID) {
5817            synchronized (this) {
5818                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5819                if (app != null && app.thread != null) {
5820                    try {
5821                        app.thread.scheduleSuicide();
5822                    } catch (RemoteException e) {
5823                        // If the other end already died, then our work here is done.
5824                    }
5825                } else {
5826                    Slog.w(TAG, "Process/uid not found attempting kill of "
5827                            + processName + " / " + uid);
5828                }
5829            }
5830        } else {
5831            throw new SecurityException(callerUid + " cannot kill app process: " +
5832                    processName);
5833        }
5834    }
5835
5836    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5837        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5838                false, true, false, false, UserHandle.getUserId(uid), reason);
5839    }
5840
5841    private void finishForceStopPackageLocked(final String packageName, int uid) {
5842        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5843                Uri.fromParts("package", packageName, null));
5844        if (!mProcessesReady) {
5845            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5846                    | Intent.FLAG_RECEIVER_FOREGROUND);
5847        }
5848        intent.putExtra(Intent.EXTRA_UID, uid);
5849        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5850        broadcastIntentLocked(null, null, intent,
5851                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5852                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5853    }
5854
5855
5856    private final boolean killPackageProcessesLocked(String packageName, int appId,
5857            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5858            boolean doit, boolean evenPersistent, String reason) {
5859        ArrayList<ProcessRecord> procs = new ArrayList<>();
5860
5861        // Remove all processes this package may have touched: all with the
5862        // same UID (except for the system or root user), and all whose name
5863        // matches the package name.
5864        final int NP = mProcessNames.getMap().size();
5865        for (int ip=0; ip<NP; ip++) {
5866            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5867            final int NA = apps.size();
5868            for (int ia=0; ia<NA; ia++) {
5869                ProcessRecord app = apps.valueAt(ia);
5870                if (app.persistent && !evenPersistent) {
5871                    // we don't kill persistent processes
5872                    continue;
5873                }
5874                if (app.removed) {
5875                    if (doit) {
5876                        procs.add(app);
5877                    }
5878                    continue;
5879                }
5880
5881                // Skip process if it doesn't meet our oom adj requirement.
5882                if (app.setAdj < minOomAdj) {
5883                    continue;
5884                }
5885
5886                // If no package is specified, we call all processes under the
5887                // give user id.
5888                if (packageName == null) {
5889                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5890                        continue;
5891                    }
5892                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5893                        continue;
5894                    }
5895                // Package has been specified, we want to hit all processes
5896                // that match it.  We need to qualify this by the processes
5897                // that are running under the specified app and user ID.
5898                } else {
5899                    final boolean isDep = app.pkgDeps != null
5900                            && app.pkgDeps.contains(packageName);
5901                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5902                        continue;
5903                    }
5904                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5905                        continue;
5906                    }
5907                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5908                        continue;
5909                    }
5910                }
5911
5912                // Process has passed all conditions, kill it!
5913                if (!doit) {
5914                    return true;
5915                }
5916                app.removed = true;
5917                procs.add(app);
5918            }
5919        }
5920
5921        int N = procs.size();
5922        for (int i=0; i<N; i++) {
5923            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5924        }
5925        updateOomAdjLocked();
5926        return N > 0;
5927    }
5928
5929    private void cleanupDisabledPackageComponentsLocked(
5930            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5931
5932        Set<String> disabledClasses = null;
5933        boolean packageDisabled = false;
5934        IPackageManager pm = AppGlobals.getPackageManager();
5935
5936        if (changedClasses == null) {
5937            // Nothing changed...
5938            return;
5939        }
5940
5941        // Determine enable/disable state of the package and its components.
5942        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5943        for (int i = changedClasses.length - 1; i >= 0; i--) {
5944            final String changedClass = changedClasses[i];
5945
5946            if (changedClass.equals(packageName)) {
5947                try {
5948                    // Entire package setting changed
5949                    enabled = pm.getApplicationEnabledSetting(packageName,
5950                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5951                } catch (Exception e) {
5952                    // No such package/component; probably racing with uninstall.  In any
5953                    // event it means we have nothing further to do here.
5954                    return;
5955                }
5956                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5957                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5958                if (packageDisabled) {
5959                    // Entire package is disabled.
5960                    // No need to continue to check component states.
5961                    disabledClasses = null;
5962                    break;
5963                }
5964            } else {
5965                try {
5966                    enabled = pm.getComponentEnabledSetting(
5967                            new ComponentName(packageName, changedClass),
5968                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5969                } catch (Exception e) {
5970                    // As above, probably racing with uninstall.
5971                    return;
5972                }
5973                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5974                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5975                    if (disabledClasses == null) {
5976                        disabledClasses = new ArraySet<>(changedClasses.length);
5977                    }
5978                    disabledClasses.add(changedClass);
5979                }
5980            }
5981        }
5982
5983        if (!packageDisabled && disabledClasses == null) {
5984            // Nothing to do here...
5985            return;
5986        }
5987
5988        // Clean-up disabled activities.
5989        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5990                packageName, disabledClasses, true, false, userId) && mBooted) {
5991            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5992            mStackSupervisor.scheduleIdleLocked();
5993        }
5994
5995        // Clean-up disabled tasks
5996        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5997
5998        // Clean-up disabled services.
5999        mServices.bringDownDisabledPackageServicesLocked(
6000                packageName, disabledClasses, userId, false, killProcess, true);
6001
6002        // Clean-up disabled providers.
6003        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6004        mProviderMap.collectPackageProvidersLocked(
6005                packageName, disabledClasses, true, false, userId, providers);
6006        for (int i = providers.size() - 1; i >= 0; i--) {
6007            removeDyingProviderLocked(null, providers.get(i), true);
6008        }
6009
6010        // Clean-up disabled broadcast receivers.
6011        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6012            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6013                    packageName, disabledClasses, userId, true);
6014        }
6015
6016    }
6017
6018    final boolean clearBroadcastQueueForUserLocked(int userId) {
6019        boolean didSomething = false;
6020        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                    null, null, userId, true);
6023        }
6024        return didSomething;
6025    }
6026
6027    final boolean forceStopPackageLocked(String packageName, int appId,
6028            boolean callerWillRestart, boolean purgeCache, boolean doit,
6029            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6030        int i;
6031
6032        if (userId == UserHandle.USER_ALL && packageName == null) {
6033            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6034        }
6035
6036        if (appId < 0 && packageName != null) {
6037            try {
6038                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6039                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6040            } catch (RemoteException e) {
6041            }
6042        }
6043
6044        if (doit) {
6045            if (packageName != null) {
6046                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6047                        + " user=" + userId + ": " + reason);
6048            } else {
6049                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6050            }
6051
6052            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6053        }
6054
6055        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6056                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6057                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6058
6059        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6060                packageName, null, doit, evenPersistent, userId)) {
6061            if (!doit) {
6062                return true;
6063            }
6064            didSomething = true;
6065        }
6066
6067        if (mServices.bringDownDisabledPackageServicesLocked(
6068                packageName, null, userId, evenPersistent, true, doit)) {
6069            if (!doit) {
6070                return true;
6071            }
6072            didSomething = true;
6073        }
6074
6075        if (packageName == null) {
6076            // Remove all sticky broadcasts from this user.
6077            mStickyBroadcasts.remove(userId);
6078        }
6079
6080        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6081        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6082                userId, providers)) {
6083            if (!doit) {
6084                return true;
6085            }
6086            didSomething = true;
6087        }
6088        for (i = providers.size() - 1; i >= 0; i--) {
6089            removeDyingProviderLocked(null, providers.get(i), true);
6090        }
6091
6092        // Remove transient permissions granted from/to this package/user
6093        removeUriPermissionsForPackageLocked(packageName, userId, false);
6094
6095        if (doit) {
6096            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6097                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6098                        packageName, null, userId, doit);
6099            }
6100        }
6101
6102        if (packageName == null || uninstalling) {
6103            // Remove pending intents.  For now we only do this when force
6104            // stopping users, because we have some problems when doing this
6105            // for packages -- app widgets are not currently cleaned up for
6106            // such packages, so they can be left with bad pending intents.
6107            if (mIntentSenderRecords.size() > 0) {
6108                Iterator<WeakReference<PendingIntentRecord>> it
6109                        = mIntentSenderRecords.values().iterator();
6110                while (it.hasNext()) {
6111                    WeakReference<PendingIntentRecord> wpir = it.next();
6112                    if (wpir == null) {
6113                        it.remove();
6114                        continue;
6115                    }
6116                    PendingIntentRecord pir = wpir.get();
6117                    if (pir == null) {
6118                        it.remove();
6119                        continue;
6120                    }
6121                    if (packageName == null) {
6122                        // Stopping user, remove all objects for the user.
6123                        if (pir.key.userId != userId) {
6124                            // Not the same user, skip it.
6125                            continue;
6126                        }
6127                    } else {
6128                        if (UserHandle.getAppId(pir.uid) != appId) {
6129                            // Different app id, skip it.
6130                            continue;
6131                        }
6132                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6133                            // Different user, skip it.
6134                            continue;
6135                        }
6136                        if (!pir.key.packageName.equals(packageName)) {
6137                            // Different package, skip it.
6138                            continue;
6139                        }
6140                    }
6141                    if (!doit) {
6142                        return true;
6143                    }
6144                    didSomething = true;
6145                    it.remove();
6146                    pir.canceled = true;
6147                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6148                        pir.key.activity.pendingResults.remove(pir.ref);
6149                    }
6150                }
6151            }
6152        }
6153
6154        if (doit) {
6155            if (purgeCache && packageName != null) {
6156                AttributeCache ac = AttributeCache.instance();
6157                if (ac != null) {
6158                    ac.removePackage(packageName);
6159                }
6160            }
6161            if (mBooted) {
6162                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6163                mStackSupervisor.scheduleIdleLocked();
6164            }
6165        }
6166
6167        return didSomething;
6168    }
6169
6170    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6171        ProcessRecord old = mProcessNames.remove(name, uid);
6172        if (old != null) {
6173            old.uidRecord.numProcs--;
6174            if (old.uidRecord.numProcs == 0) {
6175                // No more processes using this uid, tell clients it is gone.
6176                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6177                        "No more processes in " + old.uidRecord);
6178                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6179                mActiveUids.remove(uid);
6180                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6181            }
6182            old.uidRecord = null;
6183        }
6184        mIsolatedProcesses.remove(uid);
6185        return old;
6186    }
6187
6188    private final void addProcessNameLocked(ProcessRecord proc) {
6189        // We shouldn't already have a process under this name, but just in case we
6190        // need to clean up whatever may be there now.
6191        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6192        if (old == proc && proc.persistent) {
6193            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6194            Slog.w(TAG, "Re-adding persistent process " + proc);
6195        } else if (old != null) {
6196            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6197        }
6198        UidRecord uidRec = mActiveUids.get(proc.uid);
6199        if (uidRec == null) {
6200            uidRec = new UidRecord(proc.uid);
6201            // This is the first appearance of the uid, report it now!
6202            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6203                    "Creating new process uid: " + uidRec);
6204            mActiveUids.put(proc.uid, uidRec);
6205            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6206            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6207        }
6208        proc.uidRecord = uidRec;
6209        uidRec.numProcs++;
6210        mProcessNames.put(proc.processName, proc.uid, proc);
6211        if (proc.isolated) {
6212            mIsolatedProcesses.put(proc.uid, proc);
6213        }
6214    }
6215
6216    boolean removeProcessLocked(ProcessRecord app,
6217            boolean callerWillRestart, boolean allowRestart, String reason) {
6218        final String name = app.processName;
6219        final int uid = app.uid;
6220        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6221            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6222
6223        ProcessRecord old = mProcessNames.get(name, uid);
6224        if (old != app) {
6225            // This process is no longer active, so nothing to do.
6226            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6227            return false;
6228        }
6229        removeProcessNameLocked(name, uid);
6230        if (mHeavyWeightProcess == app) {
6231            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6232                    mHeavyWeightProcess.userId, 0));
6233            mHeavyWeightProcess = null;
6234        }
6235        boolean needRestart = false;
6236        if (app.pid > 0 && app.pid != MY_PID) {
6237            int pid = app.pid;
6238            synchronized (mPidsSelfLocked) {
6239                mPidsSelfLocked.remove(pid);
6240                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6241            }
6242            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6243            if (app.isolated) {
6244                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6245            }
6246            boolean willRestart = false;
6247            if (app.persistent && !app.isolated) {
6248                if (!callerWillRestart) {
6249                    willRestart = true;
6250                } else {
6251                    needRestart = true;
6252                }
6253            }
6254            app.kill(reason, true);
6255            handleAppDiedLocked(app, willRestart, allowRestart);
6256            if (willRestart) {
6257                removeLruProcessLocked(app);
6258                addAppLocked(app.info, false, null /* ABI override */);
6259            }
6260        } else {
6261            mRemovedProcesses.add(app);
6262        }
6263
6264        return needRestart;
6265    }
6266
6267    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6268        cleanupAppInLaunchingProvidersLocked(app, true);
6269        removeProcessLocked(app, false, true, "timeout publishing content providers");
6270    }
6271
6272    private final void processStartTimedOutLocked(ProcessRecord app) {
6273        final int pid = app.pid;
6274        boolean gone = false;
6275        synchronized (mPidsSelfLocked) {
6276            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6277            if (knownApp != null && knownApp.thread == null) {
6278                mPidsSelfLocked.remove(pid);
6279                gone = true;
6280            }
6281        }
6282
6283        if (gone) {
6284            Slog.w(TAG, "Process " + app + " failed to attach");
6285            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6286                    pid, app.uid, app.processName);
6287            removeProcessNameLocked(app.processName, app.uid);
6288            if (mHeavyWeightProcess == app) {
6289                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6290                        mHeavyWeightProcess.userId, 0));
6291                mHeavyWeightProcess = null;
6292            }
6293            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6294            if (app.isolated) {
6295                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6296            }
6297            // Take care of any launching providers waiting for this process.
6298            cleanupAppInLaunchingProvidersLocked(app, true);
6299            // Take care of any services that are waiting for the process.
6300            mServices.processStartTimedOutLocked(app);
6301            app.kill("start timeout", true);
6302            removeLruProcessLocked(app);
6303            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6304                Slog.w(TAG, "Unattached app died before backup, skipping");
6305                try {
6306                    IBackupManager bm = IBackupManager.Stub.asInterface(
6307                            ServiceManager.getService(Context.BACKUP_SERVICE));
6308                    bm.agentDisconnected(app.info.packageName);
6309                } catch (RemoteException e) {
6310                    // Can't happen; the backup manager is local
6311                }
6312            }
6313            if (isPendingBroadcastProcessLocked(pid)) {
6314                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6315                skipPendingBroadcastLocked(pid);
6316            }
6317        } else {
6318            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6319        }
6320    }
6321
6322    private final boolean attachApplicationLocked(IApplicationThread thread,
6323            int pid) {
6324
6325        // Find the application record that is being attached...  either via
6326        // the pid if we are running in multiple processes, or just pull the
6327        // next app record if we are emulating process with anonymous threads.
6328        ProcessRecord app;
6329        if (pid != MY_PID && pid >= 0) {
6330            synchronized (mPidsSelfLocked) {
6331                app = mPidsSelfLocked.get(pid);
6332            }
6333        } else {
6334            app = null;
6335        }
6336
6337        if (app == null) {
6338            Slog.w(TAG, "No pending application record for pid " + pid
6339                    + " (IApplicationThread " + thread + "); dropping process");
6340            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6341            if (pid > 0 && pid != MY_PID) {
6342                Process.killProcessQuiet(pid);
6343                //TODO: killProcessGroup(app.info.uid, pid);
6344            } else {
6345                try {
6346                    thread.scheduleExit();
6347                } catch (Exception e) {
6348                    // Ignore exceptions.
6349                }
6350            }
6351            return false;
6352        }
6353
6354        // If this application record is still attached to a previous
6355        // process, clean it up now.
6356        if (app.thread != null) {
6357            handleAppDiedLocked(app, true, true);
6358        }
6359
6360        // Tell the process all about itself.
6361
6362        if (DEBUG_ALL) Slog.v(
6363                TAG, "Binding process pid " + pid + " to record " + app);
6364
6365        final String processName = app.processName;
6366        try {
6367            AppDeathRecipient adr = new AppDeathRecipient(
6368                    app, pid, thread);
6369            thread.asBinder().linkToDeath(adr, 0);
6370            app.deathRecipient = adr;
6371        } catch (RemoteException e) {
6372            app.resetPackageList(mProcessStats);
6373            startProcessLocked(app, "link fail", processName);
6374            return false;
6375        }
6376
6377        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6378
6379        app.makeActive(thread, mProcessStats);
6380        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6381        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6382        app.forcingToForeground = null;
6383        updateProcessForegroundLocked(app, false, false);
6384        app.hasShownUi = false;
6385        app.debugging = false;
6386        app.cached = false;
6387        app.killedByAm = false;
6388
6389        // We carefully use the same state that PackageManager uses for
6390        // filtering, since we use this flag to decide if we need to install
6391        // providers when user is unlocked later
6392        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6393
6394        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6395
6396        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6397        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6398
6399        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6400            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6401            msg.obj = app;
6402            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6403        }
6404
6405        if (!normalMode) {
6406            Slog.i(TAG, "Launching preboot mode app: " + app);
6407        }
6408
6409        if (DEBUG_ALL) Slog.v(
6410            TAG, "New app record " + app
6411            + " thread=" + thread.asBinder() + " pid=" + pid);
6412        try {
6413            int testMode = IApplicationThread.DEBUG_OFF;
6414            if (mDebugApp != null && mDebugApp.equals(processName)) {
6415                testMode = mWaitForDebugger
6416                    ? IApplicationThread.DEBUG_WAIT
6417                    : IApplicationThread.DEBUG_ON;
6418                app.debugging = true;
6419                if (mDebugTransient) {
6420                    mDebugApp = mOrigDebugApp;
6421                    mWaitForDebugger = mOrigWaitForDebugger;
6422                }
6423            }
6424            String profileFile = app.instrumentationProfileFile;
6425            ParcelFileDescriptor profileFd = null;
6426            int samplingInterval = 0;
6427            boolean profileAutoStop = false;
6428            if (mProfileApp != null && mProfileApp.equals(processName)) {
6429                mProfileProc = app;
6430                profileFile = mProfileFile;
6431                profileFd = mProfileFd;
6432                samplingInterval = mSamplingInterval;
6433                profileAutoStop = mAutoStopProfiler;
6434            }
6435            boolean enableTrackAllocation = false;
6436            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6437                enableTrackAllocation = true;
6438                mTrackAllocationApp = null;
6439            }
6440
6441            // If the app is being launched for restore or full backup, set it up specially
6442            boolean isRestrictedBackupMode = false;
6443            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6444                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6445                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6446                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6447                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6448            }
6449
6450            if (app.instrumentationClass != null) {
6451                notifyPackageUse(app.instrumentationClass.getPackageName(),
6452                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6453            }
6454            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6455                    + processName + " with config " + mConfiguration);
6456            ApplicationInfo appInfo = app.instrumentationInfo != null
6457                    ? app.instrumentationInfo : app.info;
6458            app.compat = compatibilityInfoForPackageLocked(appInfo);
6459            if (profileFd != null) {
6460                profileFd = profileFd.dup();
6461            }
6462            ProfilerInfo profilerInfo = profileFile == null ? null
6463                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6464            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6465                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6466                    app.instrumentationUiAutomationConnection, testMode,
6467                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6468                    isRestrictedBackupMode || !normalMode, app.persistent,
6469                    new Configuration(mConfiguration), app.compat,
6470                    getCommonServicesLocked(app.isolated),
6471                    mCoreSettingsObserver.getCoreSettingsLocked());
6472            updateLruProcessLocked(app, false, null);
6473            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6474        } catch (Exception e) {
6475            // todo: Yikes!  What should we do?  For now we will try to
6476            // start another process, but that could easily get us in
6477            // an infinite loop of restarting processes...
6478            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6479
6480            app.resetPackageList(mProcessStats);
6481            app.unlinkDeathRecipient();
6482            startProcessLocked(app, "bind fail", processName);
6483            return false;
6484        }
6485
6486        // Remove this record from the list of starting applications.
6487        mPersistentStartingProcesses.remove(app);
6488        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6489                "Attach application locked removing on hold: " + app);
6490        mProcessesOnHold.remove(app);
6491
6492        boolean badApp = false;
6493        boolean didSomething = false;
6494
6495        // See if the top visible activity is waiting to run in this process...
6496        if (normalMode) {
6497            try {
6498                if (mStackSupervisor.attachApplicationLocked(app)) {
6499                    didSomething = true;
6500                }
6501            } catch (Exception e) {
6502                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6503                badApp = true;
6504            }
6505        }
6506
6507        // Find any services that should be running in this process...
6508        if (!badApp) {
6509            try {
6510                didSomething |= mServices.attachApplicationLocked(app, processName);
6511            } catch (Exception e) {
6512                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6513                badApp = true;
6514            }
6515        }
6516
6517        // Check if a next-broadcast receiver is in this process...
6518        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6519            try {
6520                didSomething |= sendPendingBroadcastsLocked(app);
6521            } catch (Exception e) {
6522                // If the app died trying to launch the receiver we declare it 'bad'
6523                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6524                badApp = true;
6525            }
6526        }
6527
6528        // Check whether the next backup agent is in this process...
6529        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6530            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6531                    "New app is backup target, launching agent for " + app);
6532            notifyPackageUse(mBackupTarget.appInfo.packageName,
6533                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6534            try {
6535                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6536                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6537                        mBackupTarget.backupMode);
6538            } catch (Exception e) {
6539                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6540                badApp = true;
6541            }
6542        }
6543
6544        if (badApp) {
6545            app.kill("error during init", true);
6546            handleAppDiedLocked(app, false, true);
6547            return false;
6548        }
6549
6550        if (!didSomething) {
6551            updateOomAdjLocked();
6552        }
6553
6554        return true;
6555    }
6556
6557    @Override
6558    public final void attachApplication(IApplicationThread thread) {
6559        synchronized (this) {
6560            int callingPid = Binder.getCallingPid();
6561            final long origId = Binder.clearCallingIdentity();
6562            attachApplicationLocked(thread, callingPid);
6563            Binder.restoreCallingIdentity(origId);
6564        }
6565    }
6566
6567    @Override
6568    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6569        final long origId = Binder.clearCallingIdentity();
6570        synchronized (this) {
6571            ActivityStack stack = ActivityRecord.getStackLocked(token);
6572            if (stack != null) {
6573                ActivityRecord r =
6574                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6575                if (stopProfiling) {
6576                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6577                        try {
6578                            mProfileFd.close();
6579                        } catch (IOException e) {
6580                        }
6581                        clearProfilerLocked();
6582                    }
6583                }
6584            }
6585        }
6586        Binder.restoreCallingIdentity(origId);
6587    }
6588
6589    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6590        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6591                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6592    }
6593
6594    void enableScreenAfterBoot() {
6595        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6596                SystemClock.uptimeMillis());
6597        mWindowManager.enableScreenAfterBoot();
6598
6599        synchronized (this) {
6600            updateEventDispatchingLocked();
6601        }
6602    }
6603
6604    @Override
6605    public void showBootMessage(final CharSequence msg, final boolean always) {
6606        if (Binder.getCallingUid() != Process.myUid()) {
6607            // These days only the core system can call this, so apps can't get in
6608            // the way of what we show about running them.
6609        }
6610        mWindowManager.showBootMessage(msg, always);
6611    }
6612
6613    @Override
6614    public void keyguardWaitingForActivityDrawn() {
6615        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6616        final long token = Binder.clearCallingIdentity();
6617        try {
6618            synchronized (this) {
6619                if (DEBUG_LOCKSCREEN) logLockScreen("");
6620                mWindowManager.keyguardWaitingForActivityDrawn();
6621                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6622                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6623                    updateSleepIfNeededLocked();
6624                }
6625            }
6626        } finally {
6627            Binder.restoreCallingIdentity(token);
6628        }
6629    }
6630
6631    @Override
6632    public void keyguardGoingAway(int flags) {
6633        enforceNotIsolatedCaller("keyguardGoingAway");
6634        final long token = Binder.clearCallingIdentity();
6635        try {
6636            synchronized (this) {
6637                if (DEBUG_LOCKSCREEN) logLockScreen("");
6638                mWindowManager.keyguardGoingAway(flags);
6639                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6640                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6641                    updateSleepIfNeededLocked();
6642
6643                    // Some stack visibility might change (e.g. docked stack)
6644                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6645                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6646                }
6647            }
6648        } finally {
6649            Binder.restoreCallingIdentity(token);
6650        }
6651    }
6652
6653    final void finishBooting() {
6654        synchronized (this) {
6655            if (!mBootAnimationComplete) {
6656                mCallFinishBooting = true;
6657                return;
6658            }
6659            mCallFinishBooting = false;
6660        }
6661
6662        ArraySet<String> completedIsas = new ArraySet<String>();
6663        for (String abi : Build.SUPPORTED_ABIS) {
6664            Process.establishZygoteConnectionForAbi(abi);
6665            final String instructionSet = VMRuntime.getInstructionSet(abi);
6666            if (!completedIsas.contains(instructionSet)) {
6667                try {
6668                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6669                } catch (InstallerException e) {
6670                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6671                            e.getMessage() +")");
6672                }
6673                completedIsas.add(instructionSet);
6674            }
6675        }
6676
6677        IntentFilter pkgFilter = new IntentFilter();
6678        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6679        pkgFilter.addDataScheme("package");
6680        mContext.registerReceiver(new BroadcastReceiver() {
6681            @Override
6682            public void onReceive(Context context, Intent intent) {
6683                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6684                if (pkgs != null) {
6685                    for (String pkg : pkgs) {
6686                        synchronized (ActivityManagerService.this) {
6687                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6688                                    0, "query restart")) {
6689                                setResultCode(Activity.RESULT_OK);
6690                                return;
6691                            }
6692                        }
6693                    }
6694                }
6695            }
6696        }, pkgFilter);
6697
6698        IntentFilter dumpheapFilter = new IntentFilter();
6699        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6700        mContext.registerReceiver(new BroadcastReceiver() {
6701            @Override
6702            public void onReceive(Context context, Intent intent) {
6703                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6704                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6705                } else {
6706                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6707                }
6708            }
6709        }, dumpheapFilter);
6710
6711        // Let system services know.
6712        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6713
6714        synchronized (this) {
6715            // Ensure that any processes we had put on hold are now started
6716            // up.
6717            final int NP = mProcessesOnHold.size();
6718            if (NP > 0) {
6719                ArrayList<ProcessRecord> procs =
6720                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6721                for (int ip=0; ip<NP; ip++) {
6722                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6723                            + procs.get(ip));
6724                    startProcessLocked(procs.get(ip), "on-hold", null);
6725                }
6726            }
6727
6728            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6729                // Start looking for apps that are abusing wake locks.
6730                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6731                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6732                // Tell anyone interested that we are done booting!
6733                SystemProperties.set("sys.boot_completed", "1");
6734
6735                // And trigger dev.bootcomplete if we are not showing encryption progress
6736                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6737                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6738                    SystemProperties.set("dev.bootcomplete", "1");
6739                }
6740                mUserController.sendBootCompletedLocked(
6741                        new IIntentReceiver.Stub() {
6742                            @Override
6743                            public void performReceive(Intent intent, int resultCode,
6744                                    String data, Bundle extras, boolean ordered,
6745                                    boolean sticky, int sendingUser) {
6746                                synchronized (ActivityManagerService.this) {
6747                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6748                                            true, false);
6749                                }
6750                            }
6751                        });
6752                scheduleStartProfilesLocked();
6753            }
6754        }
6755    }
6756
6757    @Override
6758    public void bootAnimationComplete() {
6759        final boolean callFinishBooting;
6760        synchronized (this) {
6761            callFinishBooting = mCallFinishBooting;
6762            mBootAnimationComplete = true;
6763        }
6764        if (callFinishBooting) {
6765            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6766            finishBooting();
6767            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6768        }
6769    }
6770
6771    final void ensureBootCompleted() {
6772        boolean booting;
6773        boolean enableScreen;
6774        synchronized (this) {
6775            booting = mBooting;
6776            mBooting = false;
6777            enableScreen = !mBooted;
6778            mBooted = true;
6779        }
6780
6781        if (booting) {
6782            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6783            finishBooting();
6784            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6785        }
6786
6787        if (enableScreen) {
6788            enableScreenAfterBoot();
6789        }
6790    }
6791
6792    @Override
6793    public final void activityResumed(IBinder token) {
6794        final long origId = Binder.clearCallingIdentity();
6795        synchronized(this) {
6796            ActivityStack stack = ActivityRecord.getStackLocked(token);
6797            if (stack != null) {
6798                stack.activityResumedLocked(token);
6799            }
6800        }
6801        Binder.restoreCallingIdentity(origId);
6802    }
6803
6804    @Override
6805    public final void activityPaused(IBinder token) {
6806        final long origId = Binder.clearCallingIdentity();
6807        synchronized(this) {
6808            ActivityStack stack = ActivityRecord.getStackLocked(token);
6809            if (stack != null) {
6810                stack.activityPausedLocked(token, false);
6811            }
6812        }
6813        Binder.restoreCallingIdentity(origId);
6814    }
6815
6816    @Override
6817    public final void activityStopped(IBinder token, Bundle icicle,
6818            PersistableBundle persistentState, CharSequence description) {
6819        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6820
6821        // Refuse possible leaked file descriptors
6822        if (icicle != null && icicle.hasFileDescriptors()) {
6823            throw new IllegalArgumentException("File descriptors passed in Bundle");
6824        }
6825
6826        final long origId = Binder.clearCallingIdentity();
6827
6828        synchronized (this) {
6829            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830            if (r != null) {
6831                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6832            }
6833        }
6834
6835        trimApplications();
6836
6837        Binder.restoreCallingIdentity(origId);
6838    }
6839
6840    @Override
6841    public final void activityDestroyed(IBinder token) {
6842        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6843        synchronized (this) {
6844            ActivityStack stack = ActivityRecord.getStackLocked(token);
6845            if (stack != null) {
6846                stack.activityDestroyedLocked(token, "activityDestroyed");
6847            }
6848        }
6849    }
6850
6851    @Override
6852    public final void activityRelaunched(IBinder token) {
6853        final long origId = Binder.clearCallingIdentity();
6854        synchronized (this) {
6855            mStackSupervisor.activityRelaunchedLocked(token);
6856        }
6857        Binder.restoreCallingIdentity(origId);
6858    }
6859
6860    @Override
6861    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6862            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6863        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6864                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6865        synchronized (this) {
6866            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6867            if (record == null) {
6868                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6869                        + "found for: " + token);
6870            }
6871            record.setSizeConfigurations(horizontalSizeConfiguration,
6872                    verticalSizeConfigurations, smallestSizeConfigurations);
6873        }
6874    }
6875
6876    @Override
6877    public final void backgroundResourcesReleased(IBinder token) {
6878        final long origId = Binder.clearCallingIdentity();
6879        try {
6880            synchronized (this) {
6881                ActivityStack stack = ActivityRecord.getStackLocked(token);
6882                if (stack != null) {
6883                    stack.backgroundResourcesReleased();
6884                }
6885            }
6886        } finally {
6887            Binder.restoreCallingIdentity(origId);
6888        }
6889    }
6890
6891    @Override
6892    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6893        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6894    }
6895
6896    @Override
6897    public final void notifyEnterAnimationComplete(IBinder token) {
6898        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6899    }
6900
6901    @Override
6902    public String getCallingPackage(IBinder token) {
6903        synchronized (this) {
6904            ActivityRecord r = getCallingRecordLocked(token);
6905            return r != null ? r.info.packageName : null;
6906        }
6907    }
6908
6909    @Override
6910    public ComponentName getCallingActivity(IBinder token) {
6911        synchronized (this) {
6912            ActivityRecord r = getCallingRecordLocked(token);
6913            return r != null ? r.intent.getComponent() : null;
6914        }
6915    }
6916
6917    private ActivityRecord getCallingRecordLocked(IBinder token) {
6918        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6919        if (r == null) {
6920            return null;
6921        }
6922        return r.resultTo;
6923    }
6924
6925    @Override
6926    public ComponentName getActivityClassForToken(IBinder token) {
6927        synchronized(this) {
6928            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6929            if (r == null) {
6930                return null;
6931            }
6932            return r.intent.getComponent();
6933        }
6934    }
6935
6936    @Override
6937    public String getPackageForToken(IBinder token) {
6938        synchronized(this) {
6939            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6940            if (r == null) {
6941                return null;
6942            }
6943            return r.packageName;
6944        }
6945    }
6946
6947    @Override
6948    public boolean isRootVoiceInteraction(IBinder token) {
6949        synchronized(this) {
6950            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6951            if (r == null) {
6952                return false;
6953            }
6954            return r.rootVoiceInteraction;
6955        }
6956    }
6957
6958    @Override
6959    public IIntentSender getIntentSender(int type,
6960            String packageName, IBinder token, String resultWho,
6961            int requestCode, Intent[] intents, String[] resolvedTypes,
6962            int flags, Bundle bOptions, int userId) {
6963        enforceNotIsolatedCaller("getIntentSender");
6964        // Refuse possible leaked file descriptors
6965        if (intents != null) {
6966            if (intents.length < 1) {
6967                throw new IllegalArgumentException("Intents array length must be >= 1");
6968            }
6969            for (int i=0; i<intents.length; i++) {
6970                Intent intent = intents[i];
6971                if (intent != null) {
6972                    if (intent.hasFileDescriptors()) {
6973                        throw new IllegalArgumentException("File descriptors passed in Intent");
6974                    }
6975                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6976                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6977                        throw new IllegalArgumentException(
6978                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6979                    }
6980                    intents[i] = new Intent(intent);
6981                }
6982            }
6983            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6984                throw new IllegalArgumentException(
6985                        "Intent array length does not match resolvedTypes length");
6986            }
6987        }
6988        if (bOptions != null) {
6989            if (bOptions.hasFileDescriptors()) {
6990                throw new IllegalArgumentException("File descriptors passed in options");
6991            }
6992        }
6993
6994        synchronized(this) {
6995            int callingUid = Binder.getCallingUid();
6996            int origUserId = userId;
6997            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6998                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6999                    ALLOW_NON_FULL, "getIntentSender", null);
7000            if (origUserId == UserHandle.USER_CURRENT) {
7001                // We don't want to evaluate this until the pending intent is
7002                // actually executed.  However, we do want to always do the
7003                // security checking for it above.
7004                userId = UserHandle.USER_CURRENT;
7005            }
7006            try {
7007                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7008                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7009                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7010                    if (!UserHandle.isSameApp(callingUid, uid)) {
7011                        String msg = "Permission Denial: getIntentSender() from pid="
7012                            + Binder.getCallingPid()
7013                            + ", uid=" + Binder.getCallingUid()
7014                            + ", (need uid=" + uid + ")"
7015                            + " is not allowed to send as package " + packageName;
7016                        Slog.w(TAG, msg);
7017                        throw new SecurityException(msg);
7018                    }
7019                }
7020
7021                return getIntentSenderLocked(type, packageName, callingUid, userId,
7022                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7023
7024            } catch (RemoteException e) {
7025                throw new SecurityException(e);
7026            }
7027        }
7028    }
7029
7030    IIntentSender getIntentSenderLocked(int type, String packageName,
7031            int callingUid, int userId, IBinder token, String resultWho,
7032            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7033            Bundle bOptions) {
7034        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7035        ActivityRecord activity = null;
7036        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7037            activity = ActivityRecord.isInStackLocked(token);
7038            if (activity == null) {
7039                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7040                return null;
7041            }
7042            if (activity.finishing) {
7043                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7044                return null;
7045            }
7046        }
7047
7048        // We're going to be splicing together extras before sending, so we're
7049        // okay poking into any contained extras.
7050        if (intents != null) {
7051            for (int i = 0; i < intents.length; i++) {
7052                intents[i].setDefusable(true);
7053            }
7054        }
7055        Bundle.setDefusable(bOptions, true);
7056
7057        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7058        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7059        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7060        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7061                |PendingIntent.FLAG_UPDATE_CURRENT);
7062
7063        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7064                type, packageName, activity, resultWho,
7065                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7066        WeakReference<PendingIntentRecord> ref;
7067        ref = mIntentSenderRecords.get(key);
7068        PendingIntentRecord rec = ref != null ? ref.get() : null;
7069        if (rec != null) {
7070            if (!cancelCurrent) {
7071                if (updateCurrent) {
7072                    if (rec.key.requestIntent != null) {
7073                        rec.key.requestIntent.replaceExtras(intents != null ?
7074                                intents[intents.length - 1] : null);
7075                    }
7076                    if (intents != null) {
7077                        intents[intents.length-1] = rec.key.requestIntent;
7078                        rec.key.allIntents = intents;
7079                        rec.key.allResolvedTypes = resolvedTypes;
7080                    } else {
7081                        rec.key.allIntents = null;
7082                        rec.key.allResolvedTypes = null;
7083                    }
7084                }
7085                return rec;
7086            }
7087            rec.canceled = true;
7088            mIntentSenderRecords.remove(key);
7089        }
7090        if (noCreate) {
7091            return rec;
7092        }
7093        rec = new PendingIntentRecord(this, key, callingUid);
7094        mIntentSenderRecords.put(key, rec.ref);
7095        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7096            if (activity.pendingResults == null) {
7097                activity.pendingResults
7098                        = new HashSet<WeakReference<PendingIntentRecord>>();
7099            }
7100            activity.pendingResults.add(rec.ref);
7101        }
7102        return rec;
7103    }
7104
7105    @Override
7106    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7107            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7108        if (target instanceof PendingIntentRecord) {
7109            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7110                    finishedReceiver, requiredPermission, options);
7111        } else {
7112            if (intent == null) {
7113                // Weird case: someone has given us their own custom IIntentSender, and now
7114                // they have someone else trying to send to it but of course this isn't
7115                // really a PendingIntent, so there is no base Intent, and the caller isn't
7116                // supplying an Intent... but we never want to dispatch a null Intent to
7117                // a receiver, so um...  let's make something up.
7118                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7119                intent = new Intent(Intent.ACTION_MAIN);
7120            }
7121            try {
7122                target.send(code, intent, resolvedType, null, requiredPermission, options);
7123            } catch (RemoteException e) {
7124            }
7125            // Platform code can rely on getting a result back when the send is done, but if
7126            // this intent sender is from outside of the system we can't rely on it doing that.
7127            // So instead we don't give it the result receiver, and instead just directly
7128            // report the finish immediately.
7129            if (finishedReceiver != null) {
7130                try {
7131                    finishedReceiver.performReceive(intent, 0,
7132                            null, null, false, false, UserHandle.getCallingUserId());
7133                } catch (RemoteException e) {
7134                }
7135            }
7136            return 0;
7137        }
7138    }
7139
7140    /**
7141     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7142     *
7143     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7144     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7145     */
7146    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7147        if (DEBUG_WHITELISTS) {
7148            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7149                    + targetUid + ", " + duration + ")");
7150        }
7151        synchronized (mPidsSelfLocked) {
7152            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7153            if (pr == null) {
7154                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7155                return;
7156            }
7157            if (!pr.whitelistManager) {
7158                if (DEBUG_WHITELISTS) {
7159                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7160                            + callerPid + " is not allowed");
7161                }
7162                return;
7163            }
7164        }
7165
7166        final long token = Binder.clearCallingIdentity();
7167        try {
7168            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7169                    true, "pe from uid:" + callerUid);
7170        } finally {
7171            Binder.restoreCallingIdentity(token);
7172        }
7173    }
7174
7175    @Override
7176    public void cancelIntentSender(IIntentSender sender) {
7177        if (!(sender instanceof PendingIntentRecord)) {
7178            return;
7179        }
7180        synchronized(this) {
7181            PendingIntentRecord rec = (PendingIntentRecord)sender;
7182            try {
7183                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7184                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7185                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7186                    String msg = "Permission Denial: cancelIntentSender() from pid="
7187                        + Binder.getCallingPid()
7188                        + ", uid=" + Binder.getCallingUid()
7189                        + " is not allowed to cancel packges "
7190                        + rec.key.packageName;
7191                    Slog.w(TAG, msg);
7192                    throw new SecurityException(msg);
7193                }
7194            } catch (RemoteException e) {
7195                throw new SecurityException(e);
7196            }
7197            cancelIntentSenderLocked(rec, true);
7198        }
7199    }
7200
7201    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7202        rec.canceled = true;
7203        mIntentSenderRecords.remove(rec.key);
7204        if (cleanActivity && rec.key.activity != null) {
7205            rec.key.activity.pendingResults.remove(rec.ref);
7206        }
7207    }
7208
7209    @Override
7210    public String getPackageForIntentSender(IIntentSender pendingResult) {
7211        if (!(pendingResult instanceof PendingIntentRecord)) {
7212            return null;
7213        }
7214        try {
7215            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7216            return res.key.packageName;
7217        } catch (ClassCastException e) {
7218        }
7219        return null;
7220    }
7221
7222    @Override
7223    public int getUidForIntentSender(IIntentSender sender) {
7224        if (sender instanceof PendingIntentRecord) {
7225            try {
7226                PendingIntentRecord res = (PendingIntentRecord)sender;
7227                return res.uid;
7228            } catch (ClassCastException e) {
7229            }
7230        }
7231        return -1;
7232    }
7233
7234    @Override
7235    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7236        if (!(pendingResult instanceof PendingIntentRecord)) {
7237            return false;
7238        }
7239        try {
7240            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7241            if (res.key.allIntents == null) {
7242                return false;
7243            }
7244            for (int i=0; i<res.key.allIntents.length; i++) {
7245                Intent intent = res.key.allIntents[i];
7246                if (intent.getPackage() != null && intent.getComponent() != null) {
7247                    return false;
7248                }
7249            }
7250            return true;
7251        } catch (ClassCastException e) {
7252        }
7253        return false;
7254    }
7255
7256    @Override
7257    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7258        if (!(pendingResult instanceof PendingIntentRecord)) {
7259            return false;
7260        }
7261        try {
7262            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7263            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7264                return true;
7265            }
7266            return false;
7267        } catch (ClassCastException e) {
7268        }
7269        return false;
7270    }
7271
7272    @Override
7273    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7274        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7275                "getIntentForIntentSender()");
7276        if (!(pendingResult instanceof PendingIntentRecord)) {
7277            return null;
7278        }
7279        try {
7280            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7281            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7282        } catch (ClassCastException e) {
7283        }
7284        return null;
7285    }
7286
7287    @Override
7288    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7289        if (!(pendingResult instanceof PendingIntentRecord)) {
7290            return null;
7291        }
7292        try {
7293            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7294            synchronized (this) {
7295                return getTagForIntentSenderLocked(res, prefix);
7296            }
7297        } catch (ClassCastException e) {
7298        }
7299        return null;
7300    }
7301
7302    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7303        final Intent intent = res.key.requestIntent;
7304        if (intent != null) {
7305            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7306                    || res.lastTagPrefix.equals(prefix))) {
7307                return res.lastTag;
7308            }
7309            res.lastTagPrefix = prefix;
7310            final StringBuilder sb = new StringBuilder(128);
7311            if (prefix != null) {
7312                sb.append(prefix);
7313            }
7314            if (intent.getAction() != null) {
7315                sb.append(intent.getAction());
7316            } else if (intent.getComponent() != null) {
7317                intent.getComponent().appendShortString(sb);
7318            } else {
7319                sb.append("?");
7320            }
7321            return res.lastTag = sb.toString();
7322        }
7323        return null;
7324    }
7325
7326    @Override
7327    public void setProcessLimit(int max) {
7328        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329                "setProcessLimit()");
7330        synchronized (this) {
7331            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7332            mProcessLimitOverride = max;
7333        }
7334        trimApplications();
7335    }
7336
7337    @Override
7338    public int getProcessLimit() {
7339        synchronized (this) {
7340            return mProcessLimitOverride;
7341        }
7342    }
7343
7344    void foregroundTokenDied(ForegroundToken token) {
7345        synchronized (ActivityManagerService.this) {
7346            synchronized (mPidsSelfLocked) {
7347                ForegroundToken cur
7348                    = mForegroundProcesses.get(token.pid);
7349                if (cur != token) {
7350                    return;
7351                }
7352                mForegroundProcesses.remove(token.pid);
7353                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7354                if (pr == null) {
7355                    return;
7356                }
7357                pr.forcingToForeground = null;
7358                updateProcessForegroundLocked(pr, false, false);
7359            }
7360            updateOomAdjLocked();
7361        }
7362    }
7363
7364    @Override
7365    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7366        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7367                "setProcessForeground()");
7368        synchronized(this) {
7369            boolean changed = false;
7370
7371            synchronized (mPidsSelfLocked) {
7372                ProcessRecord pr = mPidsSelfLocked.get(pid);
7373                if (pr == null && isForeground) {
7374                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7375                    return;
7376                }
7377                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7378                if (oldToken != null) {
7379                    oldToken.token.unlinkToDeath(oldToken, 0);
7380                    mForegroundProcesses.remove(pid);
7381                    if (pr != null) {
7382                        pr.forcingToForeground = null;
7383                    }
7384                    changed = true;
7385                }
7386                if (isForeground && token != null) {
7387                    ForegroundToken newToken = new ForegroundToken() {
7388                        @Override
7389                        public void binderDied() {
7390                            foregroundTokenDied(this);
7391                        }
7392                    };
7393                    newToken.pid = pid;
7394                    newToken.token = token;
7395                    try {
7396                        token.linkToDeath(newToken, 0);
7397                        mForegroundProcesses.put(pid, newToken);
7398                        pr.forcingToForeground = token;
7399                        changed = true;
7400                    } catch (RemoteException e) {
7401                        // If the process died while doing this, we will later
7402                        // do the cleanup with the process death link.
7403                    }
7404                }
7405            }
7406
7407            if (changed) {
7408                updateOomAdjLocked();
7409            }
7410        }
7411    }
7412
7413    @Override
7414    public boolean isAppForeground(int uid) throws RemoteException {
7415        synchronized (this) {
7416            UidRecord uidRec = mActiveUids.get(uid);
7417            if (uidRec == null || uidRec.idle) {
7418                return false;
7419            }
7420            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7421        }
7422    }
7423
7424    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7425    // be guarded by permission checking.
7426    int getUidState(int uid) {
7427        synchronized (this) {
7428            UidRecord uidRec = mActiveUids.get(uid);
7429            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7430        }
7431    }
7432
7433    @Override
7434    public boolean isInMultiWindowMode(IBinder token) {
7435        final long origId = Binder.clearCallingIdentity();
7436        try {
7437            synchronized(this) {
7438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7439                if (r == null) {
7440                    return false;
7441                }
7442                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7443                return !r.task.mFullscreen;
7444            }
7445        } finally {
7446            Binder.restoreCallingIdentity(origId);
7447        }
7448    }
7449
7450    @Override
7451    public boolean isInPictureInPictureMode(IBinder token) {
7452        final long origId = Binder.clearCallingIdentity();
7453        try {
7454            synchronized(this) {
7455                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7456                if (stack == null) {
7457                    return false;
7458                }
7459                return stack.mStackId == PINNED_STACK_ID;
7460            }
7461        } finally {
7462            Binder.restoreCallingIdentity(origId);
7463        }
7464    }
7465
7466    @Override
7467    public void enterPictureInPictureMode(IBinder token) {
7468        final long origId = Binder.clearCallingIdentity();
7469        try {
7470            synchronized(this) {
7471                if (!mSupportsPictureInPicture) {
7472                    throw new IllegalStateException("enterPictureInPictureMode: "
7473                            + "Device doesn't support picture-in-picture mode.");
7474                }
7475
7476                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7477
7478                if (r == null) {
7479                    throw new IllegalStateException("enterPictureInPictureMode: "
7480                            + "Can't find activity for token=" + token);
7481                }
7482
7483                if (!r.supportsPictureInPicture()) {
7484                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7485                            + "Picture-In-Picture not supported for r=" + r);
7486                }
7487
7488                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7489                // current bounds.
7490                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7491                final Rect bounds = (pinnedStack != null)
7492                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7493
7494                mStackSupervisor.moveActivityToPinnedStackLocked(
7495                        r, "enterPictureInPictureMode", bounds);
7496            }
7497        } finally {
7498            Binder.restoreCallingIdentity(origId);
7499        }
7500    }
7501
7502    // =========================================================
7503    // PROCESS INFO
7504    // =========================================================
7505
7506    static class ProcessInfoService extends IProcessInfoService.Stub {
7507        final ActivityManagerService mActivityManagerService;
7508        ProcessInfoService(ActivityManagerService activityManagerService) {
7509            mActivityManagerService = activityManagerService;
7510        }
7511
7512        @Override
7513        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7514            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7515                    /*in*/ pids, /*out*/ states, null);
7516        }
7517
7518        @Override
7519        public void getProcessStatesAndOomScoresFromPids(
7520                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7521            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7522                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7523        }
7524    }
7525
7526    /**
7527     * For each PID in the given input array, write the current process state
7528     * for that process into the states array, or -1 to indicate that no
7529     * process with the given PID exists. If scores array is provided, write
7530     * the oom score for the process into the scores array, with INVALID_ADJ
7531     * indicating the PID doesn't exist.
7532     */
7533    public void getProcessStatesAndOomScoresForPIDs(
7534            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7535        if (scores != null) {
7536            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7537                    "getProcessStatesAndOomScoresForPIDs()");
7538        }
7539
7540        if (pids == null) {
7541            throw new NullPointerException("pids");
7542        } else if (states == null) {
7543            throw new NullPointerException("states");
7544        } else if (pids.length != states.length) {
7545            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7546        } else if (scores != null && pids.length != scores.length) {
7547            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7548        }
7549
7550        synchronized (mPidsSelfLocked) {
7551            for (int i = 0; i < pids.length; i++) {
7552                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7553                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7554                        pr.curProcState;
7555                if (scores != null) {
7556                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7557                }
7558            }
7559        }
7560    }
7561
7562    // =========================================================
7563    // PERMISSIONS
7564    // =========================================================
7565
7566    static class PermissionController extends IPermissionController.Stub {
7567        ActivityManagerService mActivityManagerService;
7568        PermissionController(ActivityManagerService activityManagerService) {
7569            mActivityManagerService = activityManagerService;
7570        }
7571
7572        @Override
7573        public boolean checkPermission(String permission, int pid, int uid) {
7574            return mActivityManagerService.checkPermission(permission, pid,
7575                    uid) == PackageManager.PERMISSION_GRANTED;
7576        }
7577
7578        @Override
7579        public String[] getPackagesForUid(int uid) {
7580            return mActivityManagerService.mContext.getPackageManager()
7581                    .getPackagesForUid(uid);
7582        }
7583
7584        @Override
7585        public boolean isRuntimePermission(String permission) {
7586            try {
7587                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7588                        .getPermissionInfo(permission, 0);
7589                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7590            } catch (NameNotFoundException nnfe) {
7591                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7592            }
7593            return false;
7594        }
7595    }
7596
7597    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7598        @Override
7599        public int checkComponentPermission(String permission, int pid, int uid,
7600                int owningUid, boolean exported) {
7601            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7602                    owningUid, exported);
7603        }
7604
7605        @Override
7606        public Object getAMSLock() {
7607            return ActivityManagerService.this;
7608        }
7609    }
7610
7611    /**
7612     * This can be called with or without the global lock held.
7613     */
7614    int checkComponentPermission(String permission, int pid, int uid,
7615            int owningUid, boolean exported) {
7616        if (pid == MY_PID) {
7617            return PackageManager.PERMISSION_GRANTED;
7618        }
7619        return ActivityManager.checkComponentPermission(permission, uid,
7620                owningUid, exported);
7621    }
7622
7623    /**
7624     * As the only public entry point for permissions checking, this method
7625     * can enforce the semantic that requesting a check on a null global
7626     * permission is automatically denied.  (Internally a null permission
7627     * string is used when calling {@link #checkComponentPermission} in cases
7628     * when only uid-based security is needed.)
7629     *
7630     * This can be called with or without the global lock held.
7631     */
7632    @Override
7633    public int checkPermission(String permission, int pid, int uid) {
7634        if (permission == null) {
7635            return PackageManager.PERMISSION_DENIED;
7636        }
7637        return checkComponentPermission(permission, pid, uid, -1, true);
7638    }
7639
7640    @Override
7641    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7642        if (permission == null) {
7643            return PackageManager.PERMISSION_DENIED;
7644        }
7645
7646        // We might be performing an operation on behalf of an indirect binder
7647        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7648        // client identity accordingly before proceeding.
7649        Identity tlsIdentity = sCallerIdentity.get();
7650        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7651            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7652                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7653            uid = tlsIdentity.uid;
7654            pid = tlsIdentity.pid;
7655        }
7656
7657        return checkComponentPermission(permission, pid, uid, -1, true);
7658    }
7659
7660    /**
7661     * Binder IPC calls go through the public entry point.
7662     * This can be called with or without the global lock held.
7663     */
7664    int checkCallingPermission(String permission) {
7665        return checkPermission(permission,
7666                Binder.getCallingPid(),
7667                UserHandle.getAppId(Binder.getCallingUid()));
7668    }
7669
7670    /**
7671     * This can be called with or without the global lock held.
7672     */
7673    void enforceCallingPermission(String permission, String func) {
7674        if (checkCallingPermission(permission)
7675                == PackageManager.PERMISSION_GRANTED) {
7676            return;
7677        }
7678
7679        String msg = "Permission Denial: " + func + " from pid="
7680                + Binder.getCallingPid()
7681                + ", uid=" + Binder.getCallingUid()
7682                + " requires " + permission;
7683        Slog.w(TAG, msg);
7684        throw new SecurityException(msg);
7685    }
7686
7687    /**
7688     * Determine if UID is holding permissions required to access {@link Uri} in
7689     * the given {@link ProviderInfo}. Final permission checking is always done
7690     * in {@link ContentProvider}.
7691     */
7692    private final boolean checkHoldingPermissionsLocked(
7693            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7694        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7695                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7696        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7697            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7698                    != PERMISSION_GRANTED) {
7699                return false;
7700            }
7701        }
7702        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7703    }
7704
7705    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7706            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7707        if (pi.applicationInfo.uid == uid) {
7708            return true;
7709        } else if (!pi.exported) {
7710            return false;
7711        }
7712
7713        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7714        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7715        try {
7716            // check if target holds top-level <provider> permissions
7717            if (!readMet && pi.readPermission != null && considerUidPermissions
7718                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7719                readMet = true;
7720            }
7721            if (!writeMet && pi.writePermission != null && considerUidPermissions
7722                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7723                writeMet = true;
7724            }
7725
7726            // track if unprotected read/write is allowed; any denied
7727            // <path-permission> below removes this ability
7728            boolean allowDefaultRead = pi.readPermission == null;
7729            boolean allowDefaultWrite = pi.writePermission == null;
7730
7731            // check if target holds any <path-permission> that match uri
7732            final PathPermission[] pps = pi.pathPermissions;
7733            if (pps != null) {
7734                final String path = grantUri.uri.getPath();
7735                int i = pps.length;
7736                while (i > 0 && (!readMet || !writeMet)) {
7737                    i--;
7738                    PathPermission pp = pps[i];
7739                    if (pp.match(path)) {
7740                        if (!readMet) {
7741                            final String pprperm = pp.getReadPermission();
7742                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7743                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7744                                    + ": match=" + pp.match(path)
7745                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7746                            if (pprperm != null) {
7747                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7748                                        == PERMISSION_GRANTED) {
7749                                    readMet = true;
7750                                } else {
7751                                    allowDefaultRead = false;
7752                                }
7753                            }
7754                        }
7755                        if (!writeMet) {
7756                            final String ppwperm = pp.getWritePermission();
7757                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7759                                    + ": match=" + pp.match(path)
7760                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7761                            if (ppwperm != null) {
7762                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7763                                        == PERMISSION_GRANTED) {
7764                                    writeMet = true;
7765                                } else {
7766                                    allowDefaultWrite = false;
7767                                }
7768                            }
7769                        }
7770                    }
7771                }
7772            }
7773
7774            // grant unprotected <provider> read/write, if not blocked by
7775            // <path-permission> above
7776            if (allowDefaultRead) readMet = true;
7777            if (allowDefaultWrite) writeMet = true;
7778
7779        } catch (RemoteException e) {
7780            return false;
7781        }
7782
7783        return readMet && writeMet;
7784    }
7785
7786    public int getAppStartMode(int uid, String packageName) {
7787        synchronized (this) {
7788            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7789        }
7790    }
7791
7792    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7793            boolean allowWhenForeground) {
7794        UidRecord uidRec = mActiveUids.get(uid);
7795        if (!mLenientBackgroundCheck) {
7796            if (!allowWhenForeground || uidRec == null
7797                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7798                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7799                        packageName) != AppOpsManager.MODE_ALLOWED) {
7800                    return ActivityManager.APP_START_MODE_DELAYED;
7801                }
7802            }
7803
7804        } else if (uidRec == null || uidRec.idle) {
7805            if (callingPid >= 0) {
7806                ProcessRecord proc;
7807                synchronized (mPidsSelfLocked) {
7808                    proc = mPidsSelfLocked.get(callingPid);
7809                }
7810                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7811                    // Whoever is instigating this is in the foreground, so we will allow it
7812                    // to go through.
7813                    return ActivityManager.APP_START_MODE_NORMAL;
7814                }
7815            }
7816            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7817                    != AppOpsManager.MODE_ALLOWED) {
7818                return ActivityManager.APP_START_MODE_DELAYED;
7819            }
7820        }
7821        return ActivityManager.APP_START_MODE_NORMAL;
7822    }
7823
7824    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7825        ProviderInfo pi = null;
7826        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7827        if (cpr != null) {
7828            pi = cpr.info;
7829        } else {
7830            try {
7831                pi = AppGlobals.getPackageManager().resolveContentProvider(
7832                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7833                        userHandle);
7834            } catch (RemoteException ex) {
7835            }
7836        }
7837        return pi;
7838    }
7839
7840    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7841        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7842        if (targetUris != null) {
7843            return targetUris.get(grantUri);
7844        }
7845        return null;
7846    }
7847
7848    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7849            String targetPkg, int targetUid, GrantUri grantUri) {
7850        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7851        if (targetUris == null) {
7852            targetUris = Maps.newArrayMap();
7853            mGrantedUriPermissions.put(targetUid, targetUris);
7854        }
7855
7856        UriPermission perm = targetUris.get(grantUri);
7857        if (perm == null) {
7858            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7859            targetUris.put(grantUri, perm);
7860        }
7861
7862        return perm;
7863    }
7864
7865    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7866            final int modeFlags) {
7867        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7868        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7869                : UriPermission.STRENGTH_OWNED;
7870
7871        // Root gets to do everything.
7872        if (uid == 0) {
7873            return true;
7874        }
7875
7876        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7877        if (perms == null) return false;
7878
7879        // First look for exact match
7880        final UriPermission exactPerm = perms.get(grantUri);
7881        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7882            return true;
7883        }
7884
7885        // No exact match, look for prefixes
7886        final int N = perms.size();
7887        for (int i = 0; i < N; i++) {
7888            final UriPermission perm = perms.valueAt(i);
7889            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7890                    && perm.getStrength(modeFlags) >= minStrength) {
7891                return true;
7892            }
7893        }
7894
7895        return false;
7896    }
7897
7898    /**
7899     * @param uri This uri must NOT contain an embedded userId.
7900     * @param userId The userId in which the uri is to be resolved.
7901     */
7902    @Override
7903    public int checkUriPermission(Uri uri, int pid, int uid,
7904            final int modeFlags, int userId, IBinder callerToken) {
7905        enforceNotIsolatedCaller("checkUriPermission");
7906
7907        // Another redirected-binder-call permissions check as in
7908        // {@link checkPermissionWithToken}.
7909        Identity tlsIdentity = sCallerIdentity.get();
7910        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7911            uid = tlsIdentity.uid;
7912            pid = tlsIdentity.pid;
7913        }
7914
7915        // Our own process gets to do everything.
7916        if (pid == MY_PID) {
7917            return PackageManager.PERMISSION_GRANTED;
7918        }
7919        synchronized (this) {
7920            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7921                    ? PackageManager.PERMISSION_GRANTED
7922                    : PackageManager.PERMISSION_DENIED;
7923        }
7924    }
7925
7926    /**
7927     * Check if the targetPkg can be granted permission to access uri by
7928     * the callingUid using the given modeFlags.  Throws a security exception
7929     * if callingUid is not allowed to do this.  Returns the uid of the target
7930     * if the URI permission grant should be performed; returns -1 if it is not
7931     * needed (for example targetPkg already has permission to access the URI).
7932     * If you already know the uid of the target, you can supply it in
7933     * lastTargetUid else set that to -1.
7934     */
7935    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7936            final int modeFlags, int lastTargetUid) {
7937        if (!Intent.isAccessUriMode(modeFlags)) {
7938            return -1;
7939        }
7940
7941        if (targetPkg != null) {
7942            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7943                    "Checking grant " + targetPkg + " permission to " + grantUri);
7944        }
7945
7946        final IPackageManager pm = AppGlobals.getPackageManager();
7947
7948        // If this is not a content: uri, we can't do anything with it.
7949        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7950            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7951                    "Can't grant URI permission for non-content URI: " + grantUri);
7952            return -1;
7953        }
7954
7955        final String authority = grantUri.uri.getAuthority();
7956        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7957                MATCH_DEBUG_TRIAGED_MISSING);
7958        if (pi == null) {
7959            Slog.w(TAG, "No content provider found for permission check: " +
7960                    grantUri.uri.toSafeString());
7961            return -1;
7962        }
7963
7964        int targetUid = lastTargetUid;
7965        if (targetUid < 0 && targetPkg != null) {
7966            try {
7967                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7968                        UserHandle.getUserId(callingUid));
7969                if (targetUid < 0) {
7970                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7971                            "Can't grant URI permission no uid for: " + targetPkg);
7972                    return -1;
7973                }
7974            } catch (RemoteException ex) {
7975                return -1;
7976            }
7977        }
7978
7979        if (targetUid >= 0) {
7980            // First...  does the target actually need this permission?
7981            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7982                // No need to grant the target this permission.
7983                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7984                        "Target " + targetPkg + " already has full permission to " + grantUri);
7985                return -1;
7986            }
7987        } else {
7988            // First...  there is no target package, so can anyone access it?
7989            boolean allowed = pi.exported;
7990            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7991                if (pi.readPermission != null) {
7992                    allowed = false;
7993                }
7994            }
7995            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7996                if (pi.writePermission != null) {
7997                    allowed = false;
7998                }
7999            }
8000            if (allowed) {
8001                return -1;
8002            }
8003        }
8004
8005        /* There is a special cross user grant if:
8006         * - The target is on another user.
8007         * - Apps on the current user can access the uri without any uid permissions.
8008         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8009         * grant uri permissions.
8010         */
8011        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8012                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8013                modeFlags, false /*without considering the uid permissions*/);
8014
8015        // Second...  is the provider allowing granting of URI permissions?
8016        if (!specialCrossUserGrant) {
8017            if (!pi.grantUriPermissions) {
8018                throw new SecurityException("Provider " + pi.packageName
8019                        + "/" + pi.name
8020                        + " does not allow granting of Uri permissions (uri "
8021                        + grantUri + ")");
8022            }
8023            if (pi.uriPermissionPatterns != null) {
8024                final int N = pi.uriPermissionPatterns.length;
8025                boolean allowed = false;
8026                for (int i=0; i<N; i++) {
8027                    if (pi.uriPermissionPatterns[i] != null
8028                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8029                        allowed = true;
8030                        break;
8031                    }
8032                }
8033                if (!allowed) {
8034                    throw new SecurityException("Provider " + pi.packageName
8035                            + "/" + pi.name
8036                            + " does not allow granting of permission to path of Uri "
8037                            + grantUri);
8038                }
8039            }
8040        }
8041
8042        // Third...  does the caller itself have permission to access
8043        // this uri?
8044        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8045            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8046                // Require they hold a strong enough Uri permission
8047                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8048                    throw new SecurityException("Uid " + callingUid
8049                            + " does not have permission to uri " + grantUri);
8050                }
8051            }
8052        }
8053        return targetUid;
8054    }
8055
8056    /**
8057     * @param uri This uri must NOT contain an embedded userId.
8058     * @param userId The userId in which the uri is to be resolved.
8059     */
8060    @Override
8061    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8062            final int modeFlags, int userId) {
8063        enforceNotIsolatedCaller("checkGrantUriPermission");
8064        synchronized(this) {
8065            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8066                    new GrantUri(userId, uri, false), modeFlags, -1);
8067        }
8068    }
8069
8070    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8071            final int modeFlags, UriPermissionOwner owner) {
8072        if (!Intent.isAccessUriMode(modeFlags)) {
8073            return;
8074        }
8075
8076        // So here we are: the caller has the assumed permission
8077        // to the uri, and the target doesn't.  Let's now give this to
8078        // the target.
8079
8080        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8081                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8082
8083        final String authority = grantUri.uri.getAuthority();
8084        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8085                MATCH_DEBUG_TRIAGED_MISSING);
8086        if (pi == null) {
8087            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8088            return;
8089        }
8090
8091        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8092            grantUri.prefix = true;
8093        }
8094        final UriPermission perm = findOrCreateUriPermissionLocked(
8095                pi.packageName, targetPkg, targetUid, grantUri);
8096        perm.grantModes(modeFlags, owner);
8097    }
8098
8099    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8100            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8101        if (targetPkg == null) {
8102            throw new NullPointerException("targetPkg");
8103        }
8104        int targetUid;
8105        final IPackageManager pm = AppGlobals.getPackageManager();
8106        try {
8107            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8108        } catch (RemoteException ex) {
8109            return;
8110        }
8111
8112        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8113                targetUid);
8114        if (targetUid < 0) {
8115            return;
8116        }
8117
8118        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8119                owner);
8120    }
8121
8122    static class NeededUriGrants extends ArrayList<GrantUri> {
8123        final String targetPkg;
8124        final int targetUid;
8125        final int flags;
8126
8127        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8128            this.targetPkg = targetPkg;
8129            this.targetUid = targetUid;
8130            this.flags = flags;
8131        }
8132    }
8133
8134    /**
8135     * Like checkGrantUriPermissionLocked, but takes an Intent.
8136     */
8137    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8138            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8139        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8140                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8141                + " clip=" + (intent != null ? intent.getClipData() : null)
8142                + " from " + intent + "; flags=0x"
8143                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8144
8145        if (targetPkg == null) {
8146            throw new NullPointerException("targetPkg");
8147        }
8148
8149        if (intent == null) {
8150            return null;
8151        }
8152        Uri data = intent.getData();
8153        ClipData clip = intent.getClipData();
8154        if (data == null && clip == null) {
8155            return null;
8156        }
8157        // Default userId for uris in the intent (if they don't specify it themselves)
8158        int contentUserHint = intent.getContentUserHint();
8159        if (contentUserHint == UserHandle.USER_CURRENT) {
8160            contentUserHint = UserHandle.getUserId(callingUid);
8161        }
8162        final IPackageManager pm = AppGlobals.getPackageManager();
8163        int targetUid;
8164        if (needed != null) {
8165            targetUid = needed.targetUid;
8166        } else {
8167            try {
8168                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8169                        targetUserId);
8170            } catch (RemoteException ex) {
8171                return null;
8172            }
8173            if (targetUid < 0) {
8174                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8175                        "Can't grant URI permission no uid for: " + targetPkg
8176                        + " on user " + targetUserId);
8177                return null;
8178            }
8179        }
8180        if (data != null) {
8181            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8182            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8183                    targetUid);
8184            if (targetUid > 0) {
8185                if (needed == null) {
8186                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8187                }
8188                needed.add(grantUri);
8189            }
8190        }
8191        if (clip != null) {
8192            for (int i=0; i<clip.getItemCount(); i++) {
8193                Uri uri = clip.getItemAt(i).getUri();
8194                if (uri != null) {
8195                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8196                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8197                            targetUid);
8198                    if (targetUid > 0) {
8199                        if (needed == null) {
8200                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8201                        }
8202                        needed.add(grantUri);
8203                    }
8204                } else {
8205                    Intent clipIntent = clip.getItemAt(i).getIntent();
8206                    if (clipIntent != null) {
8207                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8208                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8209                        if (newNeeded != null) {
8210                            needed = newNeeded;
8211                        }
8212                    }
8213                }
8214            }
8215        }
8216
8217        return needed;
8218    }
8219
8220    /**
8221     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8222     */
8223    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8224            UriPermissionOwner owner) {
8225        if (needed != null) {
8226            for (int i=0; i<needed.size(); i++) {
8227                GrantUri grantUri = needed.get(i);
8228                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8229                        grantUri, needed.flags, owner);
8230            }
8231        }
8232    }
8233
8234    void grantUriPermissionFromIntentLocked(int callingUid,
8235            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8236        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8237                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8238        if (needed == null) {
8239            return;
8240        }
8241
8242        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8243    }
8244
8245    /**
8246     * @param uri This uri must NOT contain an embedded userId.
8247     * @param userId The userId in which the uri is to be resolved.
8248     */
8249    @Override
8250    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8251            final int modeFlags, int userId) {
8252        enforceNotIsolatedCaller("grantUriPermission");
8253        GrantUri grantUri = new GrantUri(userId, uri, false);
8254        synchronized(this) {
8255            final ProcessRecord r = getRecordForAppLocked(caller);
8256            if (r == null) {
8257                throw new SecurityException("Unable to find app for caller "
8258                        + caller
8259                        + " when granting permission to uri " + grantUri);
8260            }
8261            if (targetPkg == null) {
8262                throw new IllegalArgumentException("null target");
8263            }
8264            if (grantUri == null) {
8265                throw new IllegalArgumentException("null uri");
8266            }
8267
8268            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8269                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8270                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8271                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8272
8273            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8274                    UserHandle.getUserId(r.uid));
8275        }
8276    }
8277
8278    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8279        if (perm.modeFlags == 0) {
8280            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8281                    perm.targetUid);
8282            if (perms != null) {
8283                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8284                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8285
8286                perms.remove(perm.uri);
8287                if (perms.isEmpty()) {
8288                    mGrantedUriPermissions.remove(perm.targetUid);
8289                }
8290            }
8291        }
8292    }
8293
8294    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8295        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8296                "Revoking all granted permissions to " + grantUri);
8297
8298        final IPackageManager pm = AppGlobals.getPackageManager();
8299        final String authority = grantUri.uri.getAuthority();
8300        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8301                MATCH_DEBUG_TRIAGED_MISSING);
8302        if (pi == null) {
8303            Slog.w(TAG, "No content provider found for permission revoke: "
8304                    + grantUri.toSafeString());
8305            return;
8306        }
8307
8308        // Does the caller have this permission on the URI?
8309        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8310            // If they don't have direct access to the URI, then revoke any
8311            // ownerless URI permissions that have been granted to them.
8312            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8313            if (perms != null) {
8314                boolean persistChanged = false;
8315                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8316                    final UriPermission perm = it.next();
8317                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8318                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8319                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8320                                "Revoking non-owned " + perm.targetUid
8321                                + " permission to " + perm.uri);
8322                        persistChanged |= perm.revokeModes(
8323                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8324                        if (perm.modeFlags == 0) {
8325                            it.remove();
8326                        }
8327                    }
8328                }
8329                if (perms.isEmpty()) {
8330                    mGrantedUriPermissions.remove(callingUid);
8331                }
8332                if (persistChanged) {
8333                    schedulePersistUriGrants();
8334                }
8335            }
8336            return;
8337        }
8338
8339        boolean persistChanged = false;
8340
8341        // Go through all of the permissions and remove any that match.
8342        int N = mGrantedUriPermissions.size();
8343        for (int i = 0; i < N; i++) {
8344            final int targetUid = mGrantedUriPermissions.keyAt(i);
8345            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8346
8347            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8348                final UriPermission perm = it.next();
8349                if (perm.uri.sourceUserId == grantUri.sourceUserId
8350                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8351                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8352                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8353                    persistChanged |= perm.revokeModes(
8354                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8355                    if (perm.modeFlags == 0) {
8356                        it.remove();
8357                    }
8358                }
8359            }
8360
8361            if (perms.isEmpty()) {
8362                mGrantedUriPermissions.remove(targetUid);
8363                N--;
8364                i--;
8365            }
8366        }
8367
8368        if (persistChanged) {
8369            schedulePersistUriGrants();
8370        }
8371    }
8372
8373    /**
8374     * @param uri This uri must NOT contain an embedded userId.
8375     * @param userId The userId in which the uri is to be resolved.
8376     */
8377    @Override
8378    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8379            int userId) {
8380        enforceNotIsolatedCaller("revokeUriPermission");
8381        synchronized(this) {
8382            final ProcessRecord r = getRecordForAppLocked(caller);
8383            if (r == null) {
8384                throw new SecurityException("Unable to find app for caller "
8385                        + caller
8386                        + " when revoking permission to uri " + uri);
8387            }
8388            if (uri == null) {
8389                Slog.w(TAG, "revokeUriPermission: null uri");
8390                return;
8391            }
8392
8393            if (!Intent.isAccessUriMode(modeFlags)) {
8394                return;
8395            }
8396
8397            final String authority = uri.getAuthority();
8398            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8399                    MATCH_DEBUG_TRIAGED_MISSING);
8400            if (pi == null) {
8401                Slog.w(TAG, "No content provider found for permission revoke: "
8402                        + uri.toSafeString());
8403                return;
8404            }
8405
8406            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8407        }
8408    }
8409
8410    /**
8411     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8412     * given package.
8413     *
8414     * @param packageName Package name to match, or {@code null} to apply to all
8415     *            packages.
8416     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8417     *            to all users.
8418     * @param persistable If persistable grants should be removed.
8419     */
8420    private void removeUriPermissionsForPackageLocked(
8421            String packageName, int userHandle, boolean persistable) {
8422        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8423            throw new IllegalArgumentException("Must narrow by either package or user");
8424        }
8425
8426        boolean persistChanged = false;
8427
8428        int N = mGrantedUriPermissions.size();
8429        for (int i = 0; i < N; i++) {
8430            final int targetUid = mGrantedUriPermissions.keyAt(i);
8431            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8432
8433            // Only inspect grants matching user
8434            if (userHandle == UserHandle.USER_ALL
8435                    || userHandle == UserHandle.getUserId(targetUid)) {
8436                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8437                    final UriPermission perm = it.next();
8438
8439                    // Only inspect grants matching package
8440                    if (packageName == null || perm.sourcePkg.equals(packageName)
8441                            || perm.targetPkg.equals(packageName)) {
8442                        persistChanged |= perm.revokeModes(persistable
8443                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8444
8445                        // Only remove when no modes remain; any persisted grants
8446                        // will keep this alive.
8447                        if (perm.modeFlags == 0) {
8448                            it.remove();
8449                        }
8450                    }
8451                }
8452
8453                if (perms.isEmpty()) {
8454                    mGrantedUriPermissions.remove(targetUid);
8455                    N--;
8456                    i--;
8457                }
8458            }
8459        }
8460
8461        if (persistChanged) {
8462            schedulePersistUriGrants();
8463        }
8464    }
8465
8466    @Override
8467    public IBinder newUriPermissionOwner(String name) {
8468        enforceNotIsolatedCaller("newUriPermissionOwner");
8469        synchronized(this) {
8470            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8471            return owner.getExternalTokenLocked();
8472        }
8473    }
8474
8475    @Override
8476    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8477        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8478        synchronized(this) {
8479            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8480            if (r == null) {
8481                throw new IllegalArgumentException("Activity does not exist; token="
8482                        + activityToken);
8483            }
8484            return r.getUriPermissionsLocked().getExternalTokenLocked();
8485        }
8486    }
8487    /**
8488     * @param uri This uri must NOT contain an embedded userId.
8489     * @param sourceUserId The userId in which the uri is to be resolved.
8490     * @param targetUserId The userId of the app that receives the grant.
8491     */
8492    @Override
8493    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8494            final int modeFlags, int sourceUserId, int targetUserId) {
8495        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8496                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8497                "grantUriPermissionFromOwner", null);
8498        synchronized(this) {
8499            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8500            if (owner == null) {
8501                throw new IllegalArgumentException("Unknown owner: " + token);
8502            }
8503            if (fromUid != Binder.getCallingUid()) {
8504                if (Binder.getCallingUid() != Process.myUid()) {
8505                    // Only system code can grant URI permissions on behalf
8506                    // of other users.
8507                    throw new SecurityException("nice try");
8508                }
8509            }
8510            if (targetPkg == null) {
8511                throw new IllegalArgumentException("null target");
8512            }
8513            if (uri == null) {
8514                throw new IllegalArgumentException("null uri");
8515            }
8516
8517            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8518                    modeFlags, owner, targetUserId);
8519        }
8520    }
8521
8522    /**
8523     * @param uri This uri must NOT contain an embedded userId.
8524     * @param userId The userId in which the uri is to be resolved.
8525     */
8526    @Override
8527    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8528        synchronized(this) {
8529            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8530            if (owner == null) {
8531                throw new IllegalArgumentException("Unknown owner: " + token);
8532            }
8533
8534            if (uri == null) {
8535                owner.removeUriPermissionsLocked(mode);
8536            } else {
8537                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8538            }
8539        }
8540    }
8541
8542    private void schedulePersistUriGrants() {
8543        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8544            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8545                    10 * DateUtils.SECOND_IN_MILLIS);
8546        }
8547    }
8548
8549    private void writeGrantedUriPermissions() {
8550        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8551
8552        // Snapshot permissions so we can persist without lock
8553        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8554        synchronized (this) {
8555            final int size = mGrantedUriPermissions.size();
8556            for (int i = 0; i < size; i++) {
8557                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8558                for (UriPermission perm : perms.values()) {
8559                    if (perm.persistedModeFlags != 0) {
8560                        persist.add(perm.snapshot());
8561                    }
8562                }
8563            }
8564        }
8565
8566        FileOutputStream fos = null;
8567        try {
8568            fos = mGrantFile.startWrite();
8569
8570            XmlSerializer out = new FastXmlSerializer();
8571            out.setOutput(fos, StandardCharsets.UTF_8.name());
8572            out.startDocument(null, true);
8573            out.startTag(null, TAG_URI_GRANTS);
8574            for (UriPermission.Snapshot perm : persist) {
8575                out.startTag(null, TAG_URI_GRANT);
8576                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8577                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8578                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8579                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8580                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8581                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8582                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8583                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8584                out.endTag(null, TAG_URI_GRANT);
8585            }
8586            out.endTag(null, TAG_URI_GRANTS);
8587            out.endDocument();
8588
8589            mGrantFile.finishWrite(fos);
8590        } catch (IOException e) {
8591            if (fos != null) {
8592                mGrantFile.failWrite(fos);
8593            }
8594        }
8595    }
8596
8597    private void readGrantedUriPermissionsLocked() {
8598        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8599
8600        final long now = System.currentTimeMillis();
8601
8602        FileInputStream fis = null;
8603        try {
8604            fis = mGrantFile.openRead();
8605            final XmlPullParser in = Xml.newPullParser();
8606            in.setInput(fis, StandardCharsets.UTF_8.name());
8607
8608            int type;
8609            while ((type = in.next()) != END_DOCUMENT) {
8610                final String tag = in.getName();
8611                if (type == START_TAG) {
8612                    if (TAG_URI_GRANT.equals(tag)) {
8613                        final int sourceUserId;
8614                        final int targetUserId;
8615                        final int userHandle = readIntAttribute(in,
8616                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8617                        if (userHandle != UserHandle.USER_NULL) {
8618                            // For backwards compatibility.
8619                            sourceUserId = userHandle;
8620                            targetUserId = userHandle;
8621                        } else {
8622                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8623                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8624                        }
8625                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8626                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8627                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8628                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8629                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8630                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8631
8632                        // Sanity check that provider still belongs to source package
8633                        // Both direct boot aware and unaware packages are fine as we
8634                        // will do filtering at query time to avoid multiple parsing.
8635                        final ProviderInfo pi = getProviderInfoLocked(
8636                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8637                                        | MATCH_DIRECT_BOOT_UNAWARE);
8638                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8639                            int targetUid = -1;
8640                            try {
8641                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8642                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8643                            } catch (RemoteException e) {
8644                            }
8645                            if (targetUid != -1) {
8646                                final UriPermission perm = findOrCreateUriPermissionLocked(
8647                                        sourcePkg, targetPkg, targetUid,
8648                                        new GrantUri(sourceUserId, uri, prefix));
8649                                perm.initPersistedModes(modeFlags, createdTime);
8650                            }
8651                        } else {
8652                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8653                                    + " but instead found " + pi);
8654                        }
8655                    }
8656                }
8657            }
8658        } catch (FileNotFoundException e) {
8659            // Missing grants is okay
8660        } catch (IOException e) {
8661            Slog.wtf(TAG, "Failed reading Uri grants", e);
8662        } catch (XmlPullParserException e) {
8663            Slog.wtf(TAG, "Failed reading Uri grants", e);
8664        } finally {
8665            IoUtils.closeQuietly(fis);
8666        }
8667    }
8668
8669    /**
8670     * @param uri This uri must NOT contain an embedded userId.
8671     * @param userId The userId in which the uri is to be resolved.
8672     */
8673    @Override
8674    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8675        enforceNotIsolatedCaller("takePersistableUriPermission");
8676
8677        Preconditions.checkFlagsArgument(modeFlags,
8678                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8679
8680        synchronized (this) {
8681            final int callingUid = Binder.getCallingUid();
8682            boolean persistChanged = false;
8683            GrantUri grantUri = new GrantUri(userId, uri, false);
8684
8685            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8686                    new GrantUri(userId, uri, false));
8687            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8688                    new GrantUri(userId, uri, true));
8689
8690            final boolean exactValid = (exactPerm != null)
8691                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8692            final boolean prefixValid = (prefixPerm != null)
8693                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8694
8695            if (!(exactValid || prefixValid)) {
8696                throw new SecurityException("No persistable permission grants found for UID "
8697                        + callingUid + " and Uri " + grantUri.toSafeString());
8698            }
8699
8700            if (exactValid) {
8701                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8702            }
8703            if (prefixValid) {
8704                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8705            }
8706
8707            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8708
8709            if (persistChanged) {
8710                schedulePersistUriGrants();
8711            }
8712        }
8713    }
8714
8715    /**
8716     * @param uri This uri must NOT contain an embedded userId.
8717     * @param userId The userId in which the uri is to be resolved.
8718     */
8719    @Override
8720    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8721        enforceNotIsolatedCaller("releasePersistableUriPermission");
8722
8723        Preconditions.checkFlagsArgument(modeFlags,
8724                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8725
8726        synchronized (this) {
8727            final int callingUid = Binder.getCallingUid();
8728            boolean persistChanged = false;
8729
8730            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8731                    new GrantUri(userId, uri, false));
8732            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8733                    new GrantUri(userId, uri, true));
8734            if (exactPerm == null && prefixPerm == null) {
8735                throw new SecurityException("No permission grants found for UID " + callingUid
8736                        + " and Uri " + uri.toSafeString());
8737            }
8738
8739            if (exactPerm != null) {
8740                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8741                removeUriPermissionIfNeededLocked(exactPerm);
8742            }
8743            if (prefixPerm != null) {
8744                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8745                removeUriPermissionIfNeededLocked(prefixPerm);
8746            }
8747
8748            if (persistChanged) {
8749                schedulePersistUriGrants();
8750            }
8751        }
8752    }
8753
8754    /**
8755     * Prune any older {@link UriPermission} for the given UID until outstanding
8756     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8757     *
8758     * @return if any mutations occured that require persisting.
8759     */
8760    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8761        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8762        if (perms == null) return false;
8763        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8764
8765        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8766        for (UriPermission perm : perms.values()) {
8767            if (perm.persistedModeFlags != 0) {
8768                persisted.add(perm);
8769            }
8770        }
8771
8772        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8773        if (trimCount <= 0) return false;
8774
8775        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8776        for (int i = 0; i < trimCount; i++) {
8777            final UriPermission perm = persisted.get(i);
8778
8779            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8780                    "Trimming grant created at " + perm.persistedCreateTime);
8781
8782            perm.releasePersistableModes(~0);
8783            removeUriPermissionIfNeededLocked(perm);
8784        }
8785
8786        return true;
8787    }
8788
8789    @Override
8790    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8791            String packageName, boolean incoming) {
8792        enforceNotIsolatedCaller("getPersistedUriPermissions");
8793        Preconditions.checkNotNull(packageName, "packageName");
8794
8795        final int callingUid = Binder.getCallingUid();
8796        final IPackageManager pm = AppGlobals.getPackageManager();
8797        try {
8798            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8799                    UserHandle.getUserId(callingUid));
8800            if (packageUid != callingUid) {
8801                throw new SecurityException(
8802                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8803            }
8804        } catch (RemoteException e) {
8805            throw new SecurityException("Failed to verify package name ownership");
8806        }
8807
8808        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8809        synchronized (this) {
8810            if (incoming) {
8811                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8812                        callingUid);
8813                if (perms == null) {
8814                    Slog.w(TAG, "No permission grants found for " + packageName);
8815                } else {
8816                    final int userId = UserHandle.getUserId(callingUid);
8817                    Set<String> existingAuthorities = null;
8818
8819                    for (UriPermission perm : perms.values()) {
8820                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8821                            // Is this provider available in the current boot state? If the user
8822                            // is not running and unlocked we check if the provider package exists.
8823                            if (!mUserController.isUserRunningLocked(userId,
8824                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8825                                String authority = perm.uri.uri.getAuthority();
8826                                if (existingAuthorities == null
8827                                        || !existingAuthorities.contains(authority)) {
8828                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8829                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8830                                    if (providerInfo != null) {
8831                                        if (existingAuthorities == null) {
8832                                            existingAuthorities = new ArraySet<>();
8833                                        }
8834                                        existingAuthorities.add(authority);
8835                                    } else {
8836                                        continue;
8837                                    }
8838                                }
8839                            }
8840                            result.add(perm.buildPersistedPublicApiObject());
8841                        }
8842                    }
8843                }
8844            } else {
8845                final int size = mGrantedUriPermissions.size();
8846                for (int i = 0; i < size; i++) {
8847                    final ArrayMap<GrantUri, UriPermission> perms =
8848                            mGrantedUriPermissions.valueAt(i);
8849                    for (UriPermission perm : perms.values()) {
8850                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8851                            result.add(perm.buildPersistedPublicApiObject());
8852                        }
8853                    }
8854                }
8855            }
8856        }
8857        return new ParceledListSlice<android.content.UriPermission>(result);
8858    }
8859
8860    @Override
8861    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8862            String packageName, int userId) {
8863        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8864                "getGrantedUriPermissions");
8865
8866        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8867        synchronized (this) {
8868            final int size = mGrantedUriPermissions.size();
8869            for (int i = 0; i < size; i++) {
8870                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8871                for (UriPermission perm : perms.values()) {
8872                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8873                            && perm.persistedModeFlags != 0) {
8874                        result.add(perm.buildPersistedPublicApiObject());
8875                    }
8876                }
8877            }
8878        }
8879        return new ParceledListSlice<android.content.UriPermission>(result);
8880    }
8881
8882    @Override
8883    public void clearGrantedUriPermissions(String packageName, int userId) {
8884        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8885                "clearGrantedUriPermissions");
8886        removeUriPermissionsForPackageLocked(packageName, userId, true);
8887    }
8888
8889    @Override
8890    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8891        synchronized (this) {
8892            ProcessRecord app =
8893                who != null ? getRecordForAppLocked(who) : null;
8894            if (app == null) return;
8895
8896            Message msg = Message.obtain();
8897            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8898            msg.obj = app;
8899            msg.arg1 = waiting ? 1 : 0;
8900            mUiHandler.sendMessage(msg);
8901        }
8902    }
8903
8904    @Override
8905    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8906        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8907        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8908        outInfo.availMem = Process.getFreeMemory();
8909        outInfo.totalMem = Process.getTotalMemory();
8910        outInfo.threshold = homeAppMem;
8911        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8912        outInfo.hiddenAppThreshold = cachedAppMem;
8913        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8914                ProcessList.SERVICE_ADJ);
8915        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8916                ProcessList.VISIBLE_APP_ADJ);
8917        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8918                ProcessList.FOREGROUND_APP_ADJ);
8919    }
8920
8921    // =========================================================
8922    // TASK MANAGEMENT
8923    // =========================================================
8924
8925    @Override
8926    public List<IAppTask> getAppTasks(String callingPackage) {
8927        int callingUid = Binder.getCallingUid();
8928        long ident = Binder.clearCallingIdentity();
8929
8930        synchronized(this) {
8931            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8932            try {
8933                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8934
8935                final int N = mRecentTasks.size();
8936                for (int i = 0; i < N; i++) {
8937                    TaskRecord tr = mRecentTasks.get(i);
8938                    // Skip tasks that do not match the caller.  We don't need to verify
8939                    // callingPackage, because we are also limiting to callingUid and know
8940                    // that will limit to the correct security sandbox.
8941                    if (tr.effectiveUid != callingUid) {
8942                        continue;
8943                    }
8944                    Intent intent = tr.getBaseIntent();
8945                    if (intent == null ||
8946                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8947                        continue;
8948                    }
8949                    ActivityManager.RecentTaskInfo taskInfo =
8950                            createRecentTaskInfoFromTaskRecord(tr);
8951                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8952                    list.add(taskImpl);
8953                }
8954            } finally {
8955                Binder.restoreCallingIdentity(ident);
8956            }
8957            return list;
8958        }
8959    }
8960
8961    @Override
8962    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8963        final int callingUid = Binder.getCallingUid();
8964        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8965
8966        synchronized(this) {
8967            if (DEBUG_ALL) Slog.v(
8968                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8969
8970            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8971                    callingUid);
8972
8973            // TODO: Improve with MRU list from all ActivityStacks.
8974            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8975        }
8976
8977        return list;
8978    }
8979
8980    /**
8981     * Creates a new RecentTaskInfo from a TaskRecord.
8982     */
8983    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8984        // Update the task description to reflect any changes in the task stack
8985        tr.updateTaskDescription();
8986
8987        // Compose the recent task info
8988        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8989        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8990        rti.persistentId = tr.taskId;
8991        rti.baseIntent = new Intent(tr.getBaseIntent());
8992        rti.origActivity = tr.origActivity;
8993        rti.realActivity = tr.realActivity;
8994        rti.description = tr.lastDescription;
8995        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8996        rti.userId = tr.userId;
8997        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8998        rti.firstActiveTime = tr.firstActiveTime;
8999        rti.lastActiveTime = tr.lastActiveTime;
9000        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9001        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9002        rti.numActivities = 0;
9003        if (tr.mBounds != null) {
9004            rti.bounds = new Rect(tr.mBounds);
9005        }
9006        rti.isDockable = tr.canGoInDockedStack();
9007        rti.resizeMode = tr.mResizeMode;
9008
9009        ActivityRecord base = null;
9010        ActivityRecord top = null;
9011        ActivityRecord tmp;
9012
9013        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9014            tmp = tr.mActivities.get(i);
9015            if (tmp.finishing) {
9016                continue;
9017            }
9018            base = tmp;
9019            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9020                top = base;
9021            }
9022            rti.numActivities++;
9023        }
9024
9025        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9026        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9027
9028        return rti;
9029    }
9030
9031    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9032        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9033                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9034        if (!allowed) {
9035            if (checkPermission(android.Manifest.permission.GET_TASKS,
9036                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9037                // Temporary compatibility: some existing apps on the system image may
9038                // still be requesting the old permission and not switched to the new
9039                // one; if so, we'll still allow them full access.  This means we need
9040                // to see if they are holding the old permission and are a system app.
9041                try {
9042                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9043                        allowed = true;
9044                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9045                                + " is using old GET_TASKS but privileged; allowing");
9046                    }
9047                } catch (RemoteException e) {
9048                }
9049            }
9050        }
9051        if (!allowed) {
9052            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9053                    + " does not hold REAL_GET_TASKS; limiting output");
9054        }
9055        return allowed;
9056    }
9057
9058    @Override
9059    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9060        final int callingUid = Binder.getCallingUid();
9061        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9062                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9063
9064        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9065        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9066        synchronized (this) {
9067            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9068                    callingUid);
9069            final boolean detailed = checkCallingPermission(
9070                    android.Manifest.permission.GET_DETAILED_TASKS)
9071                    == PackageManager.PERMISSION_GRANTED;
9072
9073            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9074                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9075                return Collections.emptyList();
9076            }
9077            mRecentTasks.loadUserRecentsLocked(userId);
9078
9079            final int recentsCount = mRecentTasks.size();
9080            ArrayList<ActivityManager.RecentTaskInfo> res =
9081                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9082
9083            final Set<Integer> includedUsers;
9084            if (includeProfiles) {
9085                includedUsers = mUserController.getProfileIds(userId);
9086            } else {
9087                includedUsers = new HashSet<>();
9088            }
9089            includedUsers.add(Integer.valueOf(userId));
9090
9091            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9092                TaskRecord tr = mRecentTasks.get(i);
9093                // Only add calling user or related users recent tasks
9094                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9095                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9096                    continue;
9097                }
9098
9099                if (tr.realActivitySuspended) {
9100                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9101                    continue;
9102                }
9103
9104                // Return the entry if desired by the caller.  We always return
9105                // the first entry, because callers always expect this to be the
9106                // foreground app.  We may filter others if the caller has
9107                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9108                // we should exclude the entry.
9109
9110                if (i == 0
9111                        || withExcluded
9112                        || (tr.intent == null)
9113                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9114                                == 0)) {
9115                    if (!allowed) {
9116                        // If the caller doesn't have the GET_TASKS permission, then only
9117                        // allow them to see a small subset of tasks -- their own and home.
9118                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9119                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9120                            continue;
9121                        }
9122                    }
9123                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9124                        if (tr.stack != null && tr.stack.isHomeStack()) {
9125                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9126                                    "Skipping, home stack task: " + tr);
9127                            continue;
9128                        }
9129                    }
9130                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9131                        final ActivityStack stack = tr.stack;
9132                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9133                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9134                                    "Skipping, top task in docked stack: " + tr);
9135                            continue;
9136                        }
9137                    }
9138                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9139                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9140                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9141                                    "Skipping, pinned stack task: " + tr);
9142                            continue;
9143                        }
9144                    }
9145                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9146                        // Don't include auto remove tasks that are finished or finishing.
9147                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9148                                "Skipping, auto-remove without activity: " + tr);
9149                        continue;
9150                    }
9151                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9152                            && !tr.isAvailable) {
9153                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9154                                "Skipping, unavail real act: " + tr);
9155                        continue;
9156                    }
9157
9158                    if (!tr.mUserSetupComplete) {
9159                        // Don't include task launched while user is not done setting-up.
9160                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9161                                "Skipping, user setup not complete: " + tr);
9162                        continue;
9163                    }
9164
9165                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9166                    if (!detailed) {
9167                        rti.baseIntent.replaceExtras((Bundle)null);
9168                    }
9169
9170                    res.add(rti);
9171                    maxNum--;
9172                }
9173            }
9174            return res;
9175        }
9176    }
9177
9178    @Override
9179    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9180        synchronized (this) {
9181            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9182                    "getTaskThumbnail()");
9183            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9184                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9185            if (tr != null) {
9186                return tr.getTaskThumbnailLocked();
9187            }
9188        }
9189        return null;
9190    }
9191
9192    @Override
9193    public int addAppTask(IBinder activityToken, Intent intent,
9194            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9195        final int callingUid = Binder.getCallingUid();
9196        final long callingIdent = Binder.clearCallingIdentity();
9197
9198        try {
9199            synchronized (this) {
9200                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9201                if (r == null) {
9202                    throw new IllegalArgumentException("Activity does not exist; token="
9203                            + activityToken);
9204                }
9205                ComponentName comp = intent.getComponent();
9206                if (comp == null) {
9207                    throw new IllegalArgumentException("Intent " + intent
9208                            + " must specify explicit component");
9209                }
9210                if (thumbnail.getWidth() != mThumbnailWidth
9211                        || thumbnail.getHeight() != mThumbnailHeight) {
9212                    throw new IllegalArgumentException("Bad thumbnail size: got "
9213                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9214                            + mThumbnailWidth + "x" + mThumbnailHeight);
9215                }
9216                if (intent.getSelector() != null) {
9217                    intent.setSelector(null);
9218                }
9219                if (intent.getSourceBounds() != null) {
9220                    intent.setSourceBounds(null);
9221                }
9222                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9223                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9224                        // The caller has added this as an auto-remove task...  that makes no
9225                        // sense, so turn off auto-remove.
9226                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9227                    }
9228                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9229                    // Must be a new task.
9230                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9231                }
9232                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9233                    mLastAddedTaskActivity = null;
9234                }
9235                ActivityInfo ainfo = mLastAddedTaskActivity;
9236                if (ainfo == null) {
9237                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9238                            comp, 0, UserHandle.getUserId(callingUid));
9239                    if (ainfo.applicationInfo.uid != callingUid) {
9240                        throw new SecurityException(
9241                                "Can't add task for another application: target uid="
9242                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9243                    }
9244                }
9245
9246                // Use the full screen as the context for the task thumbnail
9247                final Point displaySize = new Point();
9248                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9249                r.task.stack.getDisplaySize(displaySize);
9250                thumbnailInfo.taskWidth = displaySize.x;
9251                thumbnailInfo.taskHeight = displaySize.y;
9252                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9253
9254                TaskRecord task = new TaskRecord(this,
9255                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9256                        ainfo, intent, description, thumbnailInfo);
9257
9258                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9259                if (trimIdx >= 0) {
9260                    // If this would have caused a trim, then we'll abort because that
9261                    // means it would be added at the end of the list but then just removed.
9262                    return INVALID_TASK_ID;
9263                }
9264
9265                final int N = mRecentTasks.size();
9266                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9267                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9268                    tr.removedFromRecents();
9269                }
9270
9271                task.inRecents = true;
9272                mRecentTasks.add(task);
9273                r.task.stack.addTask(task, false, "addAppTask");
9274
9275                task.setLastThumbnailLocked(thumbnail);
9276                task.freeLastThumbnail();
9277
9278                return task.taskId;
9279            }
9280        } finally {
9281            Binder.restoreCallingIdentity(callingIdent);
9282        }
9283    }
9284
9285    @Override
9286    public Point getAppTaskThumbnailSize() {
9287        synchronized (this) {
9288            return new Point(mThumbnailWidth,  mThumbnailHeight);
9289        }
9290    }
9291
9292    @Override
9293    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9294        synchronized (this) {
9295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9296            if (r != null) {
9297                r.setTaskDescription(td);
9298                r.task.updateTaskDescription();
9299            }
9300        }
9301    }
9302
9303    @Override
9304    public void setTaskResizeable(int taskId, int resizeableMode) {
9305        synchronized (this) {
9306            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9307                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9308            if (task == null) {
9309                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9310                return;
9311            }
9312            if (task.mResizeMode != resizeableMode) {
9313                task.mResizeMode = resizeableMode;
9314                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9315                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9316                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9317            }
9318        }
9319    }
9320
9321    @Override
9322    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9323        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9324        long ident = Binder.clearCallingIdentity();
9325        try {
9326            synchronized (this) {
9327                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9328                if (task == null) {
9329                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9330                    return;
9331                }
9332                int stackId = task.stack.mStackId;
9333                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9334                // in crop windows resize mode or if the task size is affected by the docked stack
9335                // changing size. No need to update configuration.
9336                if (bounds != null && task.inCropWindowsResizeMode()
9337                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9338                    mWindowManager.scrollTask(task.taskId, bounds);
9339                    return;
9340                }
9341
9342                // Place the task in the right stack if it isn't there already based on
9343                // the requested bounds.
9344                // The stack transition logic is:
9345                // - a null bounds on a freeform task moves that task to fullscreen
9346                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9347                //   that task to freeform
9348                // - otherwise the task is not moved
9349                if (!StackId.isTaskResizeAllowed(stackId)) {
9350                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9351                }
9352                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9353                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9354                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9355                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9356                }
9357                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9358                if (stackId != task.stack.mStackId) {
9359                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9360                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9361                    preserveWindow = false;
9362                }
9363
9364                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9365                        false /* deferResume */);
9366            }
9367        } finally {
9368            Binder.restoreCallingIdentity(ident);
9369        }
9370    }
9371
9372    @Override
9373    public Rect getTaskBounds(int taskId) {
9374        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9375        long ident = Binder.clearCallingIdentity();
9376        Rect rect = new Rect();
9377        try {
9378            synchronized (this) {
9379                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9380                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9381                if (task == null) {
9382                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9383                    return rect;
9384                }
9385                if (task.stack != null) {
9386                    // Return the bounds from window manager since it will be adjusted for various
9387                    // things like the presense of a docked stack for tasks that aren't resizeable.
9388                    mWindowManager.getTaskBounds(task.taskId, rect);
9389                } else {
9390                    // Task isn't in window manager yet since it isn't associated with a stack.
9391                    // Return the persist value from activity manager
9392                    if (task.mBounds != null) {
9393                        rect.set(task.mBounds);
9394                    } else if (task.mLastNonFullscreenBounds != null) {
9395                        rect.set(task.mLastNonFullscreenBounds);
9396                    }
9397                }
9398            }
9399        } finally {
9400            Binder.restoreCallingIdentity(ident);
9401        }
9402        return rect;
9403    }
9404
9405    @Override
9406    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9407        if (userId != UserHandle.getCallingUserId()) {
9408            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9409                    "getTaskDescriptionIcon");
9410        }
9411        final File passedIconFile = new File(filePath);
9412        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9413                passedIconFile.getName());
9414        if (!legitIconFile.getPath().equals(filePath)
9415                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9416            throw new IllegalArgumentException("Bad file path: " + filePath
9417                    + " passed for userId " + userId);
9418        }
9419        return mRecentTasks.getTaskDescriptionIcon(filePath);
9420    }
9421
9422    @Override
9423    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9424            throws RemoteException {
9425        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9426                opts.getCustomInPlaceResId() == 0) {
9427            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9428                    "with valid animation");
9429        }
9430        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9431        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9432                opts.getCustomInPlaceResId());
9433        mWindowManager.executeAppTransition();
9434    }
9435
9436    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9437            boolean removeFromRecents) {
9438        if (removeFromRecents) {
9439            mRecentTasks.remove(tr);
9440            tr.removedFromRecents();
9441        }
9442        ComponentName component = tr.getBaseIntent().getComponent();
9443        if (component == null) {
9444            Slog.w(TAG, "No component for base intent of task: " + tr);
9445            return;
9446        }
9447
9448        // Find any running services associated with this app and stop if needed.
9449        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9450
9451        if (!killProcess) {
9452            return;
9453        }
9454
9455        // Determine if the process(es) for this task should be killed.
9456        final String pkg = component.getPackageName();
9457        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9458        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9459        for (int i = 0; i < pmap.size(); i++) {
9460
9461            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9462            for (int j = 0; j < uids.size(); j++) {
9463                ProcessRecord proc = uids.valueAt(j);
9464                if (proc.userId != tr.userId) {
9465                    // Don't kill process for a different user.
9466                    continue;
9467                }
9468                if (proc == mHomeProcess) {
9469                    // Don't kill the home process along with tasks from the same package.
9470                    continue;
9471                }
9472                if (!proc.pkgList.containsKey(pkg)) {
9473                    // Don't kill process that is not associated with this task.
9474                    continue;
9475                }
9476
9477                for (int k = 0; k < proc.activities.size(); k++) {
9478                    TaskRecord otherTask = proc.activities.get(k).task;
9479                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9480                        // Don't kill process(es) that has an activity in a different task that is
9481                        // also in recents.
9482                        return;
9483                    }
9484                }
9485
9486                if (proc.foregroundServices) {
9487                    // Don't kill process(es) with foreground service.
9488                    return;
9489                }
9490
9491                // Add process to kill list.
9492                procsToKill.add(proc);
9493            }
9494        }
9495
9496        // Kill the running processes.
9497        for (int i = 0; i < procsToKill.size(); i++) {
9498            ProcessRecord pr = procsToKill.get(i);
9499            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9500                    && pr.curReceiver == null) {
9501                pr.kill("remove task", true);
9502            } else {
9503                // We delay killing processes that are not in the background or running a receiver.
9504                pr.waitingToKill = "remove task";
9505            }
9506        }
9507    }
9508
9509    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9510        // Remove all tasks with activities in the specified package from the list of recent tasks
9511        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9512            TaskRecord tr = mRecentTasks.get(i);
9513            if (tr.userId != userId) continue;
9514
9515            ComponentName cn = tr.intent.getComponent();
9516            if (cn != null && cn.getPackageName().equals(packageName)) {
9517                // If the package name matches, remove the task.
9518                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9519            }
9520        }
9521    }
9522
9523    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9524            int userId) {
9525
9526        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9527            TaskRecord tr = mRecentTasks.get(i);
9528            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9529                continue;
9530            }
9531
9532            ComponentName cn = tr.intent.getComponent();
9533            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9534                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9535            if (sameComponent) {
9536                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9537            }
9538        }
9539    }
9540
9541    /**
9542     * Removes the task with the specified task id.
9543     *
9544     * @param taskId Identifier of the task to be removed.
9545     * @param killProcess Kill any process associated with the task if possible.
9546     * @param removeFromRecents Whether to also remove the task from recents.
9547     * @return Returns true if the given task was found and removed.
9548     */
9549    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9550            boolean removeFromRecents) {
9551        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9552                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9553        if (tr != null) {
9554            tr.removeTaskActivitiesLocked();
9555            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9556            if (tr.isPersistable) {
9557                notifyTaskPersisterLocked(null, true);
9558            }
9559            return true;
9560        }
9561        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9562        return false;
9563    }
9564
9565    @Override
9566    public void removeStack(int stackId) {
9567        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9568        if (stackId == HOME_STACK_ID) {
9569            throw new IllegalArgumentException("Removing home stack is not allowed.");
9570        }
9571
9572        synchronized (this) {
9573            final long ident = Binder.clearCallingIdentity();
9574            try {
9575                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9576                if (stack == null) {
9577                    return;
9578                }
9579                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9580                for (int i = tasks.size() - 1; i >= 0; i--) {
9581                    removeTaskByIdLocked(
9582                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9583                }
9584            } finally {
9585                Binder.restoreCallingIdentity(ident);
9586            }
9587        }
9588    }
9589
9590    @Override
9591    public boolean removeTask(int taskId) {
9592        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9593        synchronized (this) {
9594            final long ident = Binder.clearCallingIdentity();
9595            try {
9596                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9597            } finally {
9598                Binder.restoreCallingIdentity(ident);
9599            }
9600        }
9601    }
9602
9603    /**
9604     * TODO: Add mController hook
9605     */
9606    @Override
9607    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9608        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9609
9610        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9611        synchronized(this) {
9612            moveTaskToFrontLocked(taskId, flags, bOptions);
9613        }
9614    }
9615
9616    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9617        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9618
9619        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9620                Binder.getCallingUid(), -1, -1, "Task to front")) {
9621            ActivityOptions.abort(options);
9622            return;
9623        }
9624        final long origId = Binder.clearCallingIdentity();
9625        try {
9626            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9627            if (task == null) {
9628                Slog.d(TAG, "Could not find task for id: "+ taskId);
9629                return;
9630            }
9631            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9632                mStackSupervisor.showLockTaskToast();
9633                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9634                return;
9635            }
9636            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9637            if (prev != null && prev.isRecentsActivity()) {
9638                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9639            }
9640            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9641                    false /* forceNonResizable */);
9642        } finally {
9643            Binder.restoreCallingIdentity(origId);
9644        }
9645        ActivityOptions.abort(options);
9646    }
9647
9648    /**
9649     * Moves an activity, and all of the other activities within the same task, to the bottom
9650     * of the history stack.  The activity's order within the task is unchanged.
9651     *
9652     * @param token A reference to the activity we wish to move
9653     * @param nonRoot If false then this only works if the activity is the root
9654     *                of a task; if true it will work for any activity in a task.
9655     * @return Returns true if the move completed, false if not.
9656     */
9657    @Override
9658    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9659        enforceNotIsolatedCaller("moveActivityTaskToBack");
9660        synchronized(this) {
9661            final long origId = Binder.clearCallingIdentity();
9662            try {
9663                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9664                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9665                if (task != null) {
9666                    if (mStackSupervisor.isLockedTask(task)) {
9667                        mStackSupervisor.showLockTaskToast();
9668                        return false;
9669                    }
9670                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9671                }
9672            } finally {
9673                Binder.restoreCallingIdentity(origId);
9674            }
9675        }
9676        return false;
9677    }
9678
9679    @Override
9680    public void moveTaskBackwards(int task) {
9681        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9682                "moveTaskBackwards()");
9683
9684        synchronized(this) {
9685            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9686                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9687                return;
9688            }
9689            final long origId = Binder.clearCallingIdentity();
9690            moveTaskBackwardsLocked(task);
9691            Binder.restoreCallingIdentity(origId);
9692        }
9693    }
9694
9695    private final void moveTaskBackwardsLocked(int task) {
9696        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9697    }
9698
9699    @Override
9700    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9701            IActivityContainerCallback callback) throws RemoteException {
9702        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9703        synchronized (this) {
9704            if (parentActivityToken == null) {
9705                throw new IllegalArgumentException("parent token must not be null");
9706            }
9707            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9708            if (r == null) {
9709                return null;
9710            }
9711            if (callback == null) {
9712                throw new IllegalArgumentException("callback must not be null");
9713            }
9714            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9715        }
9716    }
9717
9718    @Override
9719    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9720        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9721        synchronized (this) {
9722            mStackSupervisor.deleteActivityContainer(container);
9723        }
9724    }
9725
9726    @Override
9727    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9728        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9729        synchronized (this) {
9730            final int stackId = mStackSupervisor.getNextStackId();
9731            final ActivityStack stack =
9732                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9733            if (stack == null) {
9734                return null;
9735            }
9736            return stack.mActivityContainer;
9737        }
9738    }
9739
9740    @Override
9741    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9742        synchronized (this) {
9743            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9744            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9745                return stack.mActivityContainer.getDisplayId();
9746            }
9747            return Display.DEFAULT_DISPLAY;
9748        }
9749    }
9750
9751    @Override
9752    public int getActivityStackId(IBinder token) throws RemoteException {
9753        synchronized (this) {
9754            ActivityStack stack = ActivityRecord.getStackLocked(token);
9755            if (stack == null) {
9756                return INVALID_STACK_ID;
9757            }
9758            return stack.mStackId;
9759        }
9760    }
9761
9762    @Override
9763    public void exitFreeformMode(IBinder token) throws RemoteException {
9764        synchronized (this) {
9765            long ident = Binder.clearCallingIdentity();
9766            try {
9767                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9768                if (r == null) {
9769                    throw new IllegalArgumentException(
9770                            "exitFreeformMode: No activity record matching token=" + token);
9771                }
9772                final ActivityStack stack = r.getStackLocked(token);
9773                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9774                    throw new IllegalStateException(
9775                            "exitFreeformMode: You can only go fullscreen from freeform.");
9776                }
9777                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9778                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9779                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9780            } finally {
9781                Binder.restoreCallingIdentity(ident);
9782            }
9783        }
9784    }
9785
9786    @Override
9787    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9788        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9789        if (stackId == HOME_STACK_ID) {
9790            throw new IllegalArgumentException(
9791                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9792        }
9793        synchronized (this) {
9794            long ident = Binder.clearCallingIdentity();
9795            try {
9796                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9797                        + " to stackId=" + stackId + " toTop=" + toTop);
9798                if (stackId == DOCKED_STACK_ID) {
9799                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9800                            null /* initialBounds */);
9801                }
9802                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9803                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9804                if (result && stackId == DOCKED_STACK_ID) {
9805                    // If task moved to docked stack - show recents if needed.
9806                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9807                            "moveTaskToDockedStack");
9808                }
9809            } finally {
9810                Binder.restoreCallingIdentity(ident);
9811            }
9812        }
9813    }
9814
9815    @Override
9816    public void swapDockedAndFullscreenStack() throws RemoteException {
9817        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9818        synchronized (this) {
9819            long ident = Binder.clearCallingIdentity();
9820            try {
9821                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9822                        FULLSCREEN_WORKSPACE_STACK_ID);
9823                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9824                        : null;
9825                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9826                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9827                        : null;
9828                if (topTask == null || tasks == null || tasks.size() == 0) {
9829                    Slog.w(TAG,
9830                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9831                    return;
9832                }
9833
9834                // TODO: App transition
9835                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9836
9837                // Defer the resume so resume/pausing while moving stacks is dangerous.
9838                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9839                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9840                        ANIMATE, true /* deferResume */);
9841                final int size = tasks.size();
9842                for (int i = 0; i < size; i++) {
9843                    final int id = tasks.get(i).taskId;
9844                    if (id == topTask.taskId) {
9845                        continue;
9846                    }
9847                    mStackSupervisor.moveTaskToStackLocked(id,
9848                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9849                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9850                }
9851
9852                // Because we deferred the resume, to avoid conflicts with stack switches while
9853                // resuming, we need to do it after all the tasks are moved.
9854                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9855                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9856
9857                mWindowManager.executeAppTransition();
9858            } finally {
9859                Binder.restoreCallingIdentity(ident);
9860            }
9861        }
9862    }
9863
9864    /**
9865     * Moves the input task to the docked stack.
9866     *
9867     * @param taskId Id of task to move.
9868     * @param createMode The mode the docked stack should be created in if it doesn't exist
9869     *                   already. See
9870     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9871     *                   and
9872     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9873     * @param toTop If the task and stack should be moved to the top.
9874     * @param animate Whether we should play an animation for the moving the task
9875     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9876     *                      docked stack. Pass {@code null} to use default bounds.
9877     */
9878    @Override
9879    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9880            Rect initialBounds, boolean moveHomeStackFront) {
9881        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9882        synchronized (this) {
9883            long ident = Binder.clearCallingIdentity();
9884            try {
9885                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9886                        + " to createMode=" + createMode + " toTop=" + toTop);
9887                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9888                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9889                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9890                        animate, DEFER_RESUME);
9891                if (moved) {
9892                    if (moveHomeStackFront) {
9893                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9894                    }
9895                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9896                }
9897                return moved;
9898            } finally {
9899                Binder.restoreCallingIdentity(ident);
9900            }
9901        }
9902    }
9903
9904    /**
9905     * Moves the top activity in the input stackId to the pinned stack.
9906     *
9907     * @param stackId Id of stack to move the top activity to pinned stack.
9908     * @param bounds Bounds to use for pinned stack.
9909     *
9910     * @return True if the top activity of the input stack was successfully moved to the pinned
9911     *          stack.
9912     */
9913    @Override
9914    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9915        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9916        synchronized (this) {
9917            if (!mSupportsPictureInPicture) {
9918                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9919                        + "Device doesn't support picture-in-pciture mode");
9920            }
9921
9922            long ident = Binder.clearCallingIdentity();
9923            try {
9924                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9925            } finally {
9926                Binder.restoreCallingIdentity(ident);
9927            }
9928        }
9929    }
9930
9931    @Override
9932    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9933            boolean preserveWindows, boolean animate, int animationDuration) {
9934        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9935        long ident = Binder.clearCallingIdentity();
9936        try {
9937            synchronized (this) {
9938                if (animate) {
9939                    if (stackId == PINNED_STACK_ID) {
9940                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9941                    } else {
9942                        throw new IllegalArgumentException("Stack: " + stackId
9943                                + " doesn't support animated resize.");
9944                    }
9945                } else {
9946                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9947                            null /* tempTaskInsetBounds */, preserveWindows,
9948                            allowResizeInDockedMode, !DEFER_RESUME);
9949                }
9950            }
9951        } finally {
9952            Binder.restoreCallingIdentity(ident);
9953        }
9954    }
9955
9956    @Override
9957    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9958            Rect tempDockedTaskInsetBounds,
9959            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9960        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9961                "resizeDockedStack()");
9962        long ident = Binder.clearCallingIdentity();
9963        try {
9964            synchronized (this) {
9965                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9966                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9967                        PRESERVE_WINDOWS);
9968            }
9969        } finally {
9970            Binder.restoreCallingIdentity(ident);
9971        }
9972    }
9973
9974    @Override
9975    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9976        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9977                "resizePinnedStack()");
9978        final long ident = Binder.clearCallingIdentity();
9979        try {
9980            synchronized (this) {
9981                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9982            }
9983        } finally {
9984            Binder.restoreCallingIdentity(ident);
9985        }
9986    }
9987
9988    @Override
9989    public void positionTaskInStack(int taskId, int stackId, int position) {
9990        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9991        if (stackId == HOME_STACK_ID) {
9992            throw new IllegalArgumentException(
9993                    "positionTaskInStack: Attempt to change the position of task "
9994                    + taskId + " in/to home stack");
9995        }
9996        synchronized (this) {
9997            long ident = Binder.clearCallingIdentity();
9998            try {
9999                if (DEBUG_STACK) Slog.d(TAG_STACK,
10000                        "positionTaskInStack: positioning task=" + taskId
10001                        + " in stackId=" + stackId + " at position=" + position);
10002                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10003            } finally {
10004                Binder.restoreCallingIdentity(ident);
10005            }
10006        }
10007    }
10008
10009    @Override
10010    public List<StackInfo> getAllStackInfos() {
10011        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10012        long ident = Binder.clearCallingIdentity();
10013        try {
10014            synchronized (this) {
10015                return mStackSupervisor.getAllStackInfosLocked();
10016            }
10017        } finally {
10018            Binder.restoreCallingIdentity(ident);
10019        }
10020    }
10021
10022    @Override
10023    public StackInfo getStackInfo(int stackId) {
10024        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10025        long ident = Binder.clearCallingIdentity();
10026        try {
10027            synchronized (this) {
10028                return mStackSupervisor.getStackInfoLocked(stackId);
10029            }
10030        } finally {
10031            Binder.restoreCallingIdentity(ident);
10032        }
10033    }
10034
10035    @Override
10036    public boolean isInHomeStack(int taskId) {
10037        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10038        long ident = Binder.clearCallingIdentity();
10039        try {
10040            synchronized (this) {
10041                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10042                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10043                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10044            }
10045        } finally {
10046            Binder.restoreCallingIdentity(ident);
10047        }
10048    }
10049
10050    @Override
10051    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10052        synchronized(this) {
10053            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10054        }
10055    }
10056
10057    @Override
10058    public void updateDeviceOwner(String packageName) {
10059        final int callingUid = Binder.getCallingUid();
10060        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10061            throw new SecurityException("updateDeviceOwner called from non-system process");
10062        }
10063        synchronized (this) {
10064            mDeviceOwnerName = packageName;
10065        }
10066    }
10067
10068    @Override
10069    public void updateLockTaskPackages(int userId, String[] packages) {
10070        final int callingUid = Binder.getCallingUid();
10071        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10072            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10073                    "updateLockTaskPackages()");
10074        }
10075        synchronized (this) {
10076            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10077                    Arrays.toString(packages));
10078            mLockTaskPackages.put(userId, packages);
10079            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10080        }
10081    }
10082
10083
10084    void startLockTaskModeLocked(TaskRecord task) {
10085        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10086        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10087            return;
10088        }
10089
10090        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10091        // is initiated by system after the pinning request was shown and locked mode is initiated
10092        // by an authorized app directly
10093        final int callingUid = Binder.getCallingUid();
10094        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10095        long ident = Binder.clearCallingIdentity();
10096        try {
10097            if (!isSystemInitiated) {
10098                task.mLockTaskUid = callingUid;
10099                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10100                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10101                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10102                    StatusBarManagerInternal statusBarManager =
10103                            LocalServices.getService(StatusBarManagerInternal.class);
10104                    if (statusBarManager != null) {
10105                        statusBarManager.showScreenPinningRequest(task.taskId);
10106                    }
10107                    return;
10108                }
10109
10110                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10111                if (stack == null || task != stack.topTask()) {
10112                    throw new IllegalArgumentException("Invalid task, not in foreground");
10113                }
10114            }
10115            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10116                    "Locking fully");
10117            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10118                    ActivityManager.LOCK_TASK_MODE_PINNED :
10119                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10120                    "startLockTask", true);
10121        } finally {
10122            Binder.restoreCallingIdentity(ident);
10123        }
10124    }
10125
10126    @Override
10127    public void startLockTaskMode(int taskId) {
10128        synchronized (this) {
10129            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10130            if (task != null) {
10131                startLockTaskModeLocked(task);
10132            }
10133        }
10134    }
10135
10136    @Override
10137    public void startLockTaskMode(IBinder token) {
10138        synchronized (this) {
10139            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10140            if (r == null) {
10141                return;
10142            }
10143            final TaskRecord task = r.task;
10144            if (task != null) {
10145                startLockTaskModeLocked(task);
10146            }
10147        }
10148    }
10149
10150    @Override
10151    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10152        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10153        // This makes inner call to look as if it was initiated by system.
10154        long ident = Binder.clearCallingIdentity();
10155        try {
10156            synchronized (this) {
10157                startLockTaskMode(taskId);
10158            }
10159        } finally {
10160            Binder.restoreCallingIdentity(ident);
10161        }
10162    }
10163
10164    @Override
10165    public void stopLockTaskMode() {
10166        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10167        if (lockTask == null) {
10168            // Our work here is done.
10169            return;
10170        }
10171
10172        final int callingUid = Binder.getCallingUid();
10173        final int lockTaskUid = lockTask.mLockTaskUid;
10174        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10175        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10176            // Done.
10177            return;
10178        } else {
10179            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10180            // It is possible lockTaskMode was started by the system process because
10181            // android:lockTaskMode is set to a locking value in the application manifest
10182            // instead of the app calling startLockTaskMode. In this case
10183            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10184            // {@link TaskRecord.effectiveUid} instead. Also caller with
10185            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10186            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10187                    && callingUid != lockTaskUid
10188                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10189                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10190                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10191            }
10192        }
10193        long ident = Binder.clearCallingIdentity();
10194        try {
10195            Log.d(TAG, "stopLockTaskMode");
10196            // Stop lock task
10197            synchronized (this) {
10198                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10199                        "stopLockTask", true);
10200            }
10201            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10202            if (tm != null) {
10203                tm.showInCallScreen(false);
10204            }
10205        } finally {
10206            Binder.restoreCallingIdentity(ident);
10207        }
10208    }
10209
10210    /**
10211     * This API should be called by SystemUI only when user perform certain action to dismiss
10212     * lock task mode. We should only dismiss pinned lock task mode in this case.
10213     */
10214    @Override
10215    public void stopSystemLockTaskMode() throws RemoteException {
10216        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10217            stopLockTaskMode();
10218        } else {
10219            mStackSupervisor.showLockTaskToast();
10220        }
10221    }
10222
10223    @Override
10224    public boolean isInLockTaskMode() {
10225        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10226    }
10227
10228    @Override
10229    public int getLockTaskModeState() {
10230        synchronized (this) {
10231            return mStackSupervisor.getLockTaskModeState();
10232        }
10233    }
10234
10235    @Override
10236    public void showLockTaskEscapeMessage(IBinder token) {
10237        synchronized (this) {
10238            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10239            if (r == null) {
10240                return;
10241            }
10242            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10243        }
10244    }
10245
10246    // =========================================================
10247    // CONTENT PROVIDERS
10248    // =========================================================
10249
10250    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10251        List<ProviderInfo> providers = null;
10252        try {
10253            providers = AppGlobals.getPackageManager()
10254                    .queryContentProviders(app.processName, app.uid,
10255                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10256                                    | MATCH_DEBUG_TRIAGED_MISSING)
10257                    .getList();
10258        } catch (RemoteException ex) {
10259        }
10260        if (DEBUG_MU) Slog.v(TAG_MU,
10261                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10262        int userId = app.userId;
10263        if (providers != null) {
10264            int N = providers.size();
10265            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10266            for (int i=0; i<N; i++) {
10267                // TODO: keep logic in sync with installEncryptionUnawareProviders
10268                ProviderInfo cpi =
10269                    (ProviderInfo)providers.get(i);
10270                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10271                        cpi.name, cpi.flags);
10272                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10273                    // This is a singleton provider, but a user besides the
10274                    // default user is asking to initialize a process it runs
10275                    // in...  well, no, it doesn't actually run in this process,
10276                    // it runs in the process of the default user.  Get rid of it.
10277                    providers.remove(i);
10278                    N--;
10279                    i--;
10280                    continue;
10281                }
10282
10283                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10284                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10285                if (cpr == null) {
10286                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10287                    mProviderMap.putProviderByClass(comp, cpr);
10288                }
10289                if (DEBUG_MU) Slog.v(TAG_MU,
10290                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10291                app.pubProviders.put(cpi.name, cpr);
10292                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10293                    // Don't add this if it is a platform component that is marked
10294                    // to run in multiple processes, because this is actually
10295                    // part of the framework so doesn't make sense to track as a
10296                    // separate apk in the process.
10297                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10298                            mProcessStats);
10299                }
10300                notifyPackageUse(cpi.applicationInfo.packageName,
10301                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10302            }
10303        }
10304        return providers;
10305    }
10306
10307    /**
10308     * Check if {@link ProcessRecord} has a possible chance at accessing the
10309     * given {@link ProviderInfo}. Final permission checking is always done
10310     * in {@link ContentProvider}.
10311     */
10312    private final String checkContentProviderPermissionLocked(
10313            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10314        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10315        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10316        boolean checkedGrants = false;
10317        if (checkUser) {
10318            // Looking for cross-user grants before enforcing the typical cross-users permissions
10319            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10320            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10321                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10322                    return null;
10323                }
10324                checkedGrants = true;
10325            }
10326            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10327                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10328            if (userId != tmpTargetUserId) {
10329                // When we actually went to determine the final targer user ID, this ended
10330                // up different than our initial check for the authority.  This is because
10331                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10332                // SELF.  So we need to re-check the grants again.
10333                checkedGrants = false;
10334            }
10335        }
10336        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10337                cpi.applicationInfo.uid, cpi.exported)
10338                == PackageManager.PERMISSION_GRANTED) {
10339            return null;
10340        }
10341        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10342                cpi.applicationInfo.uid, cpi.exported)
10343                == PackageManager.PERMISSION_GRANTED) {
10344            return null;
10345        }
10346
10347        PathPermission[] pps = cpi.pathPermissions;
10348        if (pps != null) {
10349            int i = pps.length;
10350            while (i > 0) {
10351                i--;
10352                PathPermission pp = pps[i];
10353                String pprperm = pp.getReadPermission();
10354                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10355                        cpi.applicationInfo.uid, cpi.exported)
10356                        == PackageManager.PERMISSION_GRANTED) {
10357                    return null;
10358                }
10359                String ppwperm = pp.getWritePermission();
10360                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10361                        cpi.applicationInfo.uid, cpi.exported)
10362                        == PackageManager.PERMISSION_GRANTED) {
10363                    return null;
10364                }
10365            }
10366        }
10367        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10368            return null;
10369        }
10370
10371        String msg;
10372        if (!cpi.exported) {
10373            msg = "Permission Denial: opening provider " + cpi.name
10374                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10375                    + ", uid=" + callingUid + ") that is not exported from uid "
10376                    + cpi.applicationInfo.uid;
10377        } else {
10378            msg = "Permission Denial: opening provider " + cpi.name
10379                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10380                    + ", uid=" + callingUid + ") requires "
10381                    + cpi.readPermission + " or " + cpi.writePermission;
10382        }
10383        Slog.w(TAG, msg);
10384        return msg;
10385    }
10386
10387    /**
10388     * Returns if the ContentProvider has granted a uri to callingUid
10389     */
10390    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10391        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10392        if (perms != null) {
10393            for (int i=perms.size()-1; i>=0; i--) {
10394                GrantUri grantUri = perms.keyAt(i);
10395                if (grantUri.sourceUserId == userId || !checkUser) {
10396                    if (matchesProvider(grantUri.uri, cpi)) {
10397                        return true;
10398                    }
10399                }
10400            }
10401        }
10402        return false;
10403    }
10404
10405    /**
10406     * Returns true if the uri authority is one of the authorities specified in the provider.
10407     */
10408    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10409        String uriAuth = uri.getAuthority();
10410        String cpiAuth = cpi.authority;
10411        if (cpiAuth.indexOf(';') == -1) {
10412            return cpiAuth.equals(uriAuth);
10413        }
10414        String[] cpiAuths = cpiAuth.split(";");
10415        int length = cpiAuths.length;
10416        for (int i = 0; i < length; i++) {
10417            if (cpiAuths[i].equals(uriAuth)) return true;
10418        }
10419        return false;
10420    }
10421
10422    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10423            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10424        if (r != null) {
10425            for (int i=0; i<r.conProviders.size(); i++) {
10426                ContentProviderConnection conn = r.conProviders.get(i);
10427                if (conn.provider == cpr) {
10428                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10429                            "Adding provider requested by "
10430                            + r.processName + " from process "
10431                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10432                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10433                    if (stable) {
10434                        conn.stableCount++;
10435                        conn.numStableIncs++;
10436                    } else {
10437                        conn.unstableCount++;
10438                        conn.numUnstableIncs++;
10439                    }
10440                    return conn;
10441                }
10442            }
10443            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10444            if (stable) {
10445                conn.stableCount = 1;
10446                conn.numStableIncs = 1;
10447            } else {
10448                conn.unstableCount = 1;
10449                conn.numUnstableIncs = 1;
10450            }
10451            cpr.connections.add(conn);
10452            r.conProviders.add(conn);
10453            startAssociationLocked(r.uid, r.processName, r.curProcState,
10454                    cpr.uid, cpr.name, cpr.info.processName);
10455            return conn;
10456        }
10457        cpr.addExternalProcessHandleLocked(externalProcessToken);
10458        return null;
10459    }
10460
10461    boolean decProviderCountLocked(ContentProviderConnection conn,
10462            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10463        if (conn != null) {
10464            cpr = conn.provider;
10465            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10466                    "Removing provider requested by "
10467                    + conn.client.processName + " from process "
10468                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10469                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10470            if (stable) {
10471                conn.stableCount--;
10472            } else {
10473                conn.unstableCount--;
10474            }
10475            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10476                cpr.connections.remove(conn);
10477                conn.client.conProviders.remove(conn);
10478                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10479                    // The client is more important than last activity -- note the time this
10480                    // is happening, so we keep the old provider process around a bit as last
10481                    // activity to avoid thrashing it.
10482                    if (cpr.proc != null) {
10483                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10484                    }
10485                }
10486                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10487                return true;
10488            }
10489            return false;
10490        }
10491        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10492        return false;
10493    }
10494
10495    private void checkTime(long startTime, String where) {
10496        long now = SystemClock.uptimeMillis();
10497        if ((now-startTime) > 50) {
10498            // If we are taking more than 50ms, log about it.
10499            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10500        }
10501    }
10502
10503    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10504            String name, IBinder token, boolean stable, int userId) {
10505        ContentProviderRecord cpr;
10506        ContentProviderConnection conn = null;
10507        ProviderInfo cpi = null;
10508
10509        synchronized(this) {
10510            long startTime = SystemClock.uptimeMillis();
10511
10512            ProcessRecord r = null;
10513            if (caller != null) {
10514                r = getRecordForAppLocked(caller);
10515                if (r == null) {
10516                    throw new SecurityException(
10517                            "Unable to find app for caller " + caller
10518                          + " (pid=" + Binder.getCallingPid()
10519                          + ") when getting content provider " + name);
10520                }
10521            }
10522
10523            boolean checkCrossUser = true;
10524
10525            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10526
10527            // First check if this content provider has been published...
10528            cpr = mProviderMap.getProviderByName(name, userId);
10529            // If that didn't work, check if it exists for user 0 and then
10530            // verify that it's a singleton provider before using it.
10531            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10532                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10533                if (cpr != null) {
10534                    cpi = cpr.info;
10535                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10536                            cpi.name, cpi.flags)
10537                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10538                        userId = UserHandle.USER_SYSTEM;
10539                        checkCrossUser = false;
10540                    } else {
10541                        cpr = null;
10542                        cpi = null;
10543                    }
10544                }
10545            }
10546
10547            boolean providerRunning = cpr != null;
10548            if (providerRunning) {
10549                cpi = cpr.info;
10550                String msg;
10551                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10552                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10553                        != null) {
10554                    throw new SecurityException(msg);
10555                }
10556                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10557
10558                if (r != null && cpr.canRunHere(r)) {
10559                    // This provider has been published or is in the process
10560                    // of being published...  but it is also allowed to run
10561                    // in the caller's process, so don't make a connection
10562                    // and just let the caller instantiate its own instance.
10563                    ContentProviderHolder holder = cpr.newHolder(null);
10564                    // don't give caller the provider object, it needs
10565                    // to make its own.
10566                    holder.provider = null;
10567                    return holder;
10568                }
10569
10570                final long origId = Binder.clearCallingIdentity();
10571
10572                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10573
10574                // In this case the provider instance already exists, so we can
10575                // return it right away.
10576                conn = incProviderCountLocked(r, cpr, token, stable);
10577                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10578                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10579                        // If this is a perceptible app accessing the provider,
10580                        // make sure to count it as being accessed and thus
10581                        // back up on the LRU list.  This is good because
10582                        // content providers are often expensive to start.
10583                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10584                        updateLruProcessLocked(cpr.proc, false, null);
10585                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10586                    }
10587                }
10588
10589                if (cpr.proc != null) {
10590                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10591                    boolean success = updateOomAdjLocked(cpr.proc);
10592                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10593                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10594                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10595                    // NOTE: there is still a race here where a signal could be
10596                    // pending on the process even though we managed to update its
10597                    // adj level.  Not sure what to do about this, but at least
10598                    // the race is now smaller.
10599                    if (!success) {
10600                        // Uh oh...  it looks like the provider's process
10601                        // has been killed on us.  We need to wait for a new
10602                        // process to be started, and make sure its death
10603                        // doesn't kill our process.
10604                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10605                                + " is crashing; detaching " + r);
10606                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10607                        checkTime(startTime, "getContentProviderImpl: before appDied");
10608                        appDiedLocked(cpr.proc);
10609                        checkTime(startTime, "getContentProviderImpl: after appDied");
10610                        if (!lastRef) {
10611                            // This wasn't the last ref our process had on
10612                            // the provider...  we have now been killed, bail.
10613                            return null;
10614                        }
10615                        providerRunning = false;
10616                        conn = null;
10617                    }
10618                }
10619
10620                Binder.restoreCallingIdentity(origId);
10621            }
10622
10623            if (!providerRunning) {
10624                try {
10625                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10626                    cpi = AppGlobals.getPackageManager().
10627                        resolveContentProvider(name,
10628                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10629                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10630                } catch (RemoteException ex) {
10631                }
10632                if (cpi == null) {
10633                    return null;
10634                }
10635                // If the provider is a singleton AND
10636                // (it's a call within the same user || the provider is a
10637                // privileged app)
10638                // Then allow connecting to the singleton provider
10639                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10640                        cpi.name, cpi.flags)
10641                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10642                if (singleton) {
10643                    userId = UserHandle.USER_SYSTEM;
10644                }
10645                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10646                checkTime(startTime, "getContentProviderImpl: got app info for user");
10647
10648                String msg;
10649                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10650                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10651                        != null) {
10652                    throw new SecurityException(msg);
10653                }
10654                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10655
10656                if (!mProcessesReady
10657                        && !cpi.processName.equals("system")) {
10658                    // If this content provider does not run in the system
10659                    // process, and the system is not yet ready to run other
10660                    // processes, then fail fast instead of hanging.
10661                    throw new IllegalArgumentException(
10662                            "Attempt to launch content provider before system ready");
10663                }
10664
10665                // Make sure that the user who owns this provider is running.  If not,
10666                // we don't want to allow it to run.
10667                if (!mUserController.isUserRunningLocked(userId, 0)) {
10668                    Slog.w(TAG, "Unable to launch app "
10669                            + cpi.applicationInfo.packageName + "/"
10670                            + cpi.applicationInfo.uid + " for provider "
10671                            + name + ": user " + userId + " is stopped");
10672                    return null;
10673                }
10674
10675                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10676                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10677                cpr = mProviderMap.getProviderByClass(comp, userId);
10678                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10679                final boolean firstClass = cpr == null;
10680                if (firstClass) {
10681                    final long ident = Binder.clearCallingIdentity();
10682
10683                    // If permissions need a review before any of the app components can run,
10684                    // we return no provider and launch a review activity if the calling app
10685                    // is in the foreground.
10686                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10687                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10688                            return null;
10689                        }
10690                    }
10691
10692                    try {
10693                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10694                        ApplicationInfo ai =
10695                            AppGlobals.getPackageManager().
10696                                getApplicationInfo(
10697                                        cpi.applicationInfo.packageName,
10698                                        STOCK_PM_FLAGS, userId);
10699                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10700                        if (ai == null) {
10701                            Slog.w(TAG, "No package info for content provider "
10702                                    + cpi.name);
10703                            return null;
10704                        }
10705                        ai = getAppInfoForUser(ai, userId);
10706                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10707                    } catch (RemoteException ex) {
10708                        // pm is in same process, this will never happen.
10709                    } finally {
10710                        Binder.restoreCallingIdentity(ident);
10711                    }
10712                }
10713
10714                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10715
10716                if (r != null && cpr.canRunHere(r)) {
10717                    // If this is a multiprocess provider, then just return its
10718                    // info and allow the caller to instantiate it.  Only do
10719                    // this if the provider is the same user as the caller's
10720                    // process, or can run as root (so can be in any process).
10721                    return cpr.newHolder(null);
10722                }
10723
10724                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10725                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10726                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10727
10728                // This is single process, and our app is now connecting to it.
10729                // See if we are already in the process of launching this
10730                // provider.
10731                final int N = mLaunchingProviders.size();
10732                int i;
10733                for (i = 0; i < N; i++) {
10734                    if (mLaunchingProviders.get(i) == cpr) {
10735                        break;
10736                    }
10737                }
10738
10739                // If the provider is not already being launched, then get it
10740                // started.
10741                if (i >= N) {
10742                    final long origId = Binder.clearCallingIdentity();
10743
10744                    try {
10745                        // Content provider is now in use, its package can't be stopped.
10746                        try {
10747                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10748                            AppGlobals.getPackageManager().setPackageStoppedState(
10749                                    cpr.appInfo.packageName, false, userId);
10750                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10751                        } catch (RemoteException e) {
10752                        } catch (IllegalArgumentException e) {
10753                            Slog.w(TAG, "Failed trying to unstop package "
10754                                    + cpr.appInfo.packageName + ": " + e);
10755                        }
10756
10757                        // Use existing process if already started
10758                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10759                        ProcessRecord proc = getProcessRecordLocked(
10760                                cpi.processName, cpr.appInfo.uid, false);
10761                        if (proc != null && proc.thread != null) {
10762                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10763                                    "Installing in existing process " + proc);
10764                            if (!proc.pubProviders.containsKey(cpi.name)) {
10765                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10766                                proc.pubProviders.put(cpi.name, cpr);
10767                                try {
10768                                    proc.thread.scheduleInstallProvider(cpi);
10769                                } catch (RemoteException e) {
10770                                }
10771                            }
10772                        } else {
10773                            checkTime(startTime, "getContentProviderImpl: before start process");
10774                            proc = startProcessLocked(cpi.processName,
10775                                    cpr.appInfo, false, 0, "content provider",
10776                                    new ComponentName(cpi.applicationInfo.packageName,
10777                                            cpi.name), false, false, false);
10778                            checkTime(startTime, "getContentProviderImpl: after start process");
10779                            if (proc == null) {
10780                                Slog.w(TAG, "Unable to launch app "
10781                                        + cpi.applicationInfo.packageName + "/"
10782                                        + cpi.applicationInfo.uid + " for provider "
10783                                        + name + ": process is bad");
10784                                return null;
10785                            }
10786                        }
10787                        cpr.launchingApp = proc;
10788                        mLaunchingProviders.add(cpr);
10789                    } finally {
10790                        Binder.restoreCallingIdentity(origId);
10791                    }
10792                }
10793
10794                checkTime(startTime, "getContentProviderImpl: updating data structures");
10795
10796                // Make sure the provider is published (the same provider class
10797                // may be published under multiple names).
10798                if (firstClass) {
10799                    mProviderMap.putProviderByClass(comp, cpr);
10800                }
10801
10802                mProviderMap.putProviderByName(name, cpr);
10803                conn = incProviderCountLocked(r, cpr, token, stable);
10804                if (conn != null) {
10805                    conn.waiting = true;
10806                }
10807            }
10808            checkTime(startTime, "getContentProviderImpl: done!");
10809        }
10810
10811        // Wait for the provider to be published...
10812        synchronized (cpr) {
10813            while (cpr.provider == null) {
10814                if (cpr.launchingApp == null) {
10815                    Slog.w(TAG, "Unable to launch app "
10816                            + cpi.applicationInfo.packageName + "/"
10817                            + cpi.applicationInfo.uid + " for provider "
10818                            + name + ": launching app became null");
10819                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10820                            UserHandle.getUserId(cpi.applicationInfo.uid),
10821                            cpi.applicationInfo.packageName,
10822                            cpi.applicationInfo.uid, name);
10823                    return null;
10824                }
10825                try {
10826                    if (DEBUG_MU) Slog.v(TAG_MU,
10827                            "Waiting to start provider " + cpr
10828                            + " launchingApp=" + cpr.launchingApp);
10829                    if (conn != null) {
10830                        conn.waiting = true;
10831                    }
10832                    cpr.wait();
10833                } catch (InterruptedException ex) {
10834                } finally {
10835                    if (conn != null) {
10836                        conn.waiting = false;
10837                    }
10838                }
10839            }
10840        }
10841        return cpr != null ? cpr.newHolder(conn) : null;
10842    }
10843
10844    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10845            ProcessRecord r, final int userId) {
10846        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10847                cpi.packageName, userId)) {
10848
10849            final boolean callerForeground = r == null || r.setSchedGroup
10850                    != ProcessList.SCHED_GROUP_BACKGROUND;
10851
10852            // Show a permission review UI only for starting from a foreground app
10853            if (!callerForeground) {
10854                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10855                        + cpi.packageName + " requires a permissions review");
10856                return false;
10857            }
10858
10859            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10860            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10861                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10862            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10863
10864            if (DEBUG_PERMISSIONS_REVIEW) {
10865                Slog.i(TAG, "u" + userId + " Launching permission review "
10866                        + "for package " + cpi.packageName);
10867            }
10868
10869            final UserHandle userHandle = new UserHandle(userId);
10870            mHandler.post(new Runnable() {
10871                @Override
10872                public void run() {
10873                    mContext.startActivityAsUser(intent, userHandle);
10874                }
10875            });
10876
10877            return false;
10878        }
10879
10880        return true;
10881    }
10882
10883    PackageManagerInternal getPackageManagerInternalLocked() {
10884        if (mPackageManagerInt == null) {
10885            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10886        }
10887        return mPackageManagerInt;
10888    }
10889
10890    @Override
10891    public final ContentProviderHolder getContentProvider(
10892            IApplicationThread caller, String name, int userId, boolean stable) {
10893        enforceNotIsolatedCaller("getContentProvider");
10894        if (caller == null) {
10895            String msg = "null IApplicationThread when getting content provider "
10896                    + name;
10897            Slog.w(TAG, msg);
10898            throw new SecurityException(msg);
10899        }
10900        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10901        // with cross-user grant.
10902        return getContentProviderImpl(caller, name, null, stable, userId);
10903    }
10904
10905    public ContentProviderHolder getContentProviderExternal(
10906            String name, int userId, IBinder token) {
10907        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10908            "Do not have permission in call getContentProviderExternal()");
10909        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10910                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10911        return getContentProviderExternalUnchecked(name, token, userId);
10912    }
10913
10914    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10915            IBinder token, int userId) {
10916        return getContentProviderImpl(null, name, token, true, userId);
10917    }
10918
10919    /**
10920     * Drop a content provider from a ProcessRecord's bookkeeping
10921     */
10922    public void removeContentProvider(IBinder connection, boolean stable) {
10923        enforceNotIsolatedCaller("removeContentProvider");
10924        long ident = Binder.clearCallingIdentity();
10925        try {
10926            synchronized (this) {
10927                ContentProviderConnection conn;
10928                try {
10929                    conn = (ContentProviderConnection)connection;
10930                } catch (ClassCastException e) {
10931                    String msg ="removeContentProvider: " + connection
10932                            + " not a ContentProviderConnection";
10933                    Slog.w(TAG, msg);
10934                    throw new IllegalArgumentException(msg);
10935                }
10936                if (conn == null) {
10937                    throw new NullPointerException("connection is null");
10938                }
10939                if (decProviderCountLocked(conn, null, null, stable)) {
10940                    updateOomAdjLocked();
10941                }
10942            }
10943        } finally {
10944            Binder.restoreCallingIdentity(ident);
10945        }
10946    }
10947
10948    public void removeContentProviderExternal(String name, IBinder token) {
10949        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10950            "Do not have permission in call removeContentProviderExternal()");
10951        int userId = UserHandle.getCallingUserId();
10952        long ident = Binder.clearCallingIdentity();
10953        try {
10954            removeContentProviderExternalUnchecked(name, token, userId);
10955        } finally {
10956            Binder.restoreCallingIdentity(ident);
10957        }
10958    }
10959
10960    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10961        synchronized (this) {
10962            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10963            if(cpr == null) {
10964                //remove from mProvidersByClass
10965                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10966                return;
10967            }
10968
10969            //update content provider record entry info
10970            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10971            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10972            if (localCpr.hasExternalProcessHandles()) {
10973                if (localCpr.removeExternalProcessHandleLocked(token)) {
10974                    updateOomAdjLocked();
10975                } else {
10976                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10977                            + " with no external reference for token: "
10978                            + token + ".");
10979                }
10980            } else {
10981                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10982                        + " with no external references.");
10983            }
10984        }
10985    }
10986
10987    public final void publishContentProviders(IApplicationThread caller,
10988            List<ContentProviderHolder> providers) {
10989        if (providers == null) {
10990            return;
10991        }
10992
10993        enforceNotIsolatedCaller("publishContentProviders");
10994        synchronized (this) {
10995            final ProcessRecord r = getRecordForAppLocked(caller);
10996            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10997            if (r == null) {
10998                throw new SecurityException(
10999                        "Unable to find app for caller " + caller
11000                      + " (pid=" + Binder.getCallingPid()
11001                      + ") when publishing content providers");
11002            }
11003
11004            final long origId = Binder.clearCallingIdentity();
11005
11006            final int N = providers.size();
11007            for (int i = 0; i < N; i++) {
11008                ContentProviderHolder src = providers.get(i);
11009                if (src == null || src.info == null || src.provider == null) {
11010                    continue;
11011                }
11012                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11013                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11014                if (dst != null) {
11015                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11016                    mProviderMap.putProviderByClass(comp, dst);
11017                    String names[] = dst.info.authority.split(";");
11018                    for (int j = 0; j < names.length; j++) {
11019                        mProviderMap.putProviderByName(names[j], dst);
11020                    }
11021
11022                    int launchingCount = mLaunchingProviders.size();
11023                    int j;
11024                    boolean wasInLaunchingProviders = false;
11025                    for (j = 0; j < launchingCount; j++) {
11026                        if (mLaunchingProviders.get(j) == dst) {
11027                            mLaunchingProviders.remove(j);
11028                            wasInLaunchingProviders = true;
11029                            j--;
11030                            launchingCount--;
11031                        }
11032                    }
11033                    if (wasInLaunchingProviders) {
11034                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11035                    }
11036                    synchronized (dst) {
11037                        dst.provider = src.provider;
11038                        dst.proc = r;
11039                        dst.notifyAll();
11040                    }
11041                    updateOomAdjLocked(r);
11042                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11043                            src.info.authority);
11044                }
11045            }
11046
11047            Binder.restoreCallingIdentity(origId);
11048        }
11049    }
11050
11051    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11052        ContentProviderConnection conn;
11053        try {
11054            conn = (ContentProviderConnection)connection;
11055        } catch (ClassCastException e) {
11056            String msg ="refContentProvider: " + connection
11057                    + " not a ContentProviderConnection";
11058            Slog.w(TAG, msg);
11059            throw new IllegalArgumentException(msg);
11060        }
11061        if (conn == null) {
11062            throw new NullPointerException("connection is null");
11063        }
11064
11065        synchronized (this) {
11066            if (stable > 0) {
11067                conn.numStableIncs += stable;
11068            }
11069            stable = conn.stableCount + stable;
11070            if (stable < 0) {
11071                throw new IllegalStateException("stableCount < 0: " + stable);
11072            }
11073
11074            if (unstable > 0) {
11075                conn.numUnstableIncs += unstable;
11076            }
11077            unstable = conn.unstableCount + unstable;
11078            if (unstable < 0) {
11079                throw new IllegalStateException("unstableCount < 0: " + unstable);
11080            }
11081
11082            if ((stable+unstable) <= 0) {
11083                throw new IllegalStateException("ref counts can't go to zero here: stable="
11084                        + stable + " unstable=" + unstable);
11085            }
11086            conn.stableCount = stable;
11087            conn.unstableCount = unstable;
11088            return !conn.dead;
11089        }
11090    }
11091
11092    public void unstableProviderDied(IBinder connection) {
11093        ContentProviderConnection conn;
11094        try {
11095            conn = (ContentProviderConnection)connection;
11096        } catch (ClassCastException e) {
11097            String msg ="refContentProvider: " + connection
11098                    + " not a ContentProviderConnection";
11099            Slog.w(TAG, msg);
11100            throw new IllegalArgumentException(msg);
11101        }
11102        if (conn == null) {
11103            throw new NullPointerException("connection is null");
11104        }
11105
11106        // Safely retrieve the content provider associated with the connection.
11107        IContentProvider provider;
11108        synchronized (this) {
11109            provider = conn.provider.provider;
11110        }
11111
11112        if (provider == null) {
11113            // Um, yeah, we're way ahead of you.
11114            return;
11115        }
11116
11117        // Make sure the caller is being honest with us.
11118        if (provider.asBinder().pingBinder()) {
11119            // Er, no, still looks good to us.
11120            synchronized (this) {
11121                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11122                        + " says " + conn + " died, but we don't agree");
11123                return;
11124            }
11125        }
11126
11127        // Well look at that!  It's dead!
11128        synchronized (this) {
11129            if (conn.provider.provider != provider) {
11130                // But something changed...  good enough.
11131                return;
11132            }
11133
11134            ProcessRecord proc = conn.provider.proc;
11135            if (proc == null || proc.thread == null) {
11136                // Seems like the process is already cleaned up.
11137                return;
11138            }
11139
11140            // As far as we're concerned, this is just like receiving a
11141            // death notification...  just a bit prematurely.
11142            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11143                    + ") early provider death");
11144            final long ident = Binder.clearCallingIdentity();
11145            try {
11146                appDiedLocked(proc);
11147            } finally {
11148                Binder.restoreCallingIdentity(ident);
11149            }
11150        }
11151    }
11152
11153    @Override
11154    public void appNotRespondingViaProvider(IBinder connection) {
11155        enforceCallingPermission(
11156                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11157
11158        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11159        if (conn == null) {
11160            Slog.w(TAG, "ContentProviderConnection is null");
11161            return;
11162        }
11163
11164        final ProcessRecord host = conn.provider.proc;
11165        if (host == null) {
11166            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11167            return;
11168        }
11169
11170        mHandler.post(new Runnable() {
11171            @Override
11172            public void run() {
11173                mAppErrors.appNotResponding(host, null, null, false,
11174                        "ContentProvider not responding");
11175            }
11176        });
11177    }
11178
11179    public final void installSystemProviders() {
11180        List<ProviderInfo> providers;
11181        synchronized (this) {
11182            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11183            providers = generateApplicationProvidersLocked(app);
11184            if (providers != null) {
11185                for (int i=providers.size()-1; i>=0; i--) {
11186                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11187                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11188                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11189                                + ": not system .apk");
11190                        providers.remove(i);
11191                    }
11192                }
11193            }
11194        }
11195        if (providers != null) {
11196            mSystemThread.installSystemProviders(providers);
11197        }
11198
11199        mCoreSettingsObserver = new CoreSettingsObserver(this);
11200        mFontScaleSettingObserver = new FontScaleSettingObserver();
11201
11202        //mUsageStatsService.monitorPackages();
11203    }
11204
11205    private void startPersistentApps(int matchFlags) {
11206        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11207
11208        synchronized (this) {
11209            try {
11210                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11211                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11212                for (ApplicationInfo app : apps) {
11213                    if (!"android".equals(app.packageName)) {
11214                        addAppLocked(app, false, null /* ABI override */);
11215                    }
11216                }
11217            } catch (RemoteException ex) {
11218            }
11219        }
11220    }
11221
11222    /**
11223     * When a user is unlocked, we need to install encryption-unaware providers
11224     * belonging to any running apps.
11225     */
11226    private void installEncryptionUnawareProviders(int userId) {
11227        // We're only interested in providers that are encryption unaware, and
11228        // we don't care about uninstalled apps, since there's no way they're
11229        // running at this point.
11230        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11231
11232        synchronized (this) {
11233            final int NP = mProcessNames.getMap().size();
11234            for (int ip = 0; ip < NP; ip++) {
11235                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11236                final int NA = apps.size();
11237                for (int ia = 0; ia < NA; ia++) {
11238                    final ProcessRecord app = apps.valueAt(ia);
11239                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11240
11241                    final int NG = app.pkgList.size();
11242                    for (int ig = 0; ig < NG; ig++) {
11243                        try {
11244                            final String pkgName = app.pkgList.keyAt(ig);
11245                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11246                                    .getPackageInfo(pkgName, matchFlags, userId);
11247                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11248                                for (ProviderInfo pi : pkgInfo.providers) {
11249                                    // TODO: keep in sync with generateApplicationProvidersLocked
11250                                    final boolean processMatch = Objects.equals(pi.processName,
11251                                            app.processName) || pi.multiprocess;
11252                                    final boolean userMatch = isSingleton(pi.processName,
11253                                            pi.applicationInfo, pi.name, pi.flags)
11254                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11255                                    if (processMatch && userMatch) {
11256                                        Log.v(TAG, "Installing " + pi);
11257                                        app.thread.scheduleInstallProvider(pi);
11258                                    } else {
11259                                        Log.v(TAG, "Skipping " + pi);
11260                                    }
11261                                }
11262                            }
11263                        } catch (RemoteException ignored) {
11264                        }
11265                    }
11266                }
11267            }
11268        }
11269    }
11270
11271    /**
11272     * Allows apps to retrieve the MIME type of a URI.
11273     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11274     * users, then it does not need permission to access the ContentProvider.
11275     * Either, it needs cross-user uri grants.
11276     *
11277     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11278     *
11279     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11280     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11281     */
11282    public String getProviderMimeType(Uri uri, int userId) {
11283        enforceNotIsolatedCaller("getProviderMimeType");
11284        final String name = uri.getAuthority();
11285        int callingUid = Binder.getCallingUid();
11286        int callingPid = Binder.getCallingPid();
11287        long ident = 0;
11288        boolean clearedIdentity = false;
11289        synchronized (this) {
11290            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11291        }
11292        if (canClearIdentity(callingPid, callingUid, userId)) {
11293            clearedIdentity = true;
11294            ident = Binder.clearCallingIdentity();
11295        }
11296        ContentProviderHolder holder = null;
11297        try {
11298            holder = getContentProviderExternalUnchecked(name, null, userId);
11299            if (holder != null) {
11300                return holder.provider.getType(uri);
11301            }
11302        } catch (RemoteException e) {
11303            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11304            return null;
11305        } catch (Exception e) {
11306            Log.w(TAG, "Exception while determining type of " + uri, e);
11307            return null;
11308        } finally {
11309            // We need to clear the identity to call removeContentProviderExternalUnchecked
11310            if (!clearedIdentity) {
11311                ident = Binder.clearCallingIdentity();
11312            }
11313            try {
11314                if (holder != null) {
11315                    removeContentProviderExternalUnchecked(name, null, userId);
11316                }
11317            } finally {
11318                Binder.restoreCallingIdentity(ident);
11319            }
11320        }
11321
11322        return null;
11323    }
11324
11325    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11326        if (UserHandle.getUserId(callingUid) == userId) {
11327            return true;
11328        }
11329        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11330                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11331                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11332                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11333                return true;
11334        }
11335        return false;
11336    }
11337
11338    // =========================================================
11339    // GLOBAL MANAGEMENT
11340    // =========================================================
11341
11342    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11343            boolean isolated, int isolatedUid) {
11344        String proc = customProcess != null ? customProcess : info.processName;
11345        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11346        final int userId = UserHandle.getUserId(info.uid);
11347        int uid = info.uid;
11348        if (isolated) {
11349            if (isolatedUid == 0) {
11350                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11351                while (true) {
11352                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11353                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11354                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11355                    }
11356                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11357                    mNextIsolatedProcessUid++;
11358                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11359                        // No process for this uid, use it.
11360                        break;
11361                    }
11362                    stepsLeft--;
11363                    if (stepsLeft <= 0) {
11364                        return null;
11365                    }
11366                }
11367            } else {
11368                // Special case for startIsolatedProcess (internal only), where
11369                // the uid of the isolated process is specified by the caller.
11370                uid = isolatedUid;
11371            }
11372        }
11373        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11374        if (!mBooted && !mBooting
11375                && userId == UserHandle.USER_SYSTEM
11376                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11377            r.persistent = true;
11378        }
11379        addProcessNameLocked(r);
11380        return r;
11381    }
11382
11383    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11384            String abiOverride) {
11385        ProcessRecord app;
11386        if (!isolated) {
11387            app = getProcessRecordLocked(info.processName, info.uid, true);
11388        } else {
11389            app = null;
11390        }
11391
11392        if (app == null) {
11393            app = newProcessRecordLocked(info, null, isolated, 0);
11394            updateLruProcessLocked(app, false, null);
11395            updateOomAdjLocked();
11396        }
11397
11398        // This package really, really can not be stopped.
11399        try {
11400            AppGlobals.getPackageManager().setPackageStoppedState(
11401                    info.packageName, false, UserHandle.getUserId(app.uid));
11402        } catch (RemoteException e) {
11403        } catch (IllegalArgumentException e) {
11404            Slog.w(TAG, "Failed trying to unstop package "
11405                    + info.packageName + ": " + e);
11406        }
11407
11408        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11409            app.persistent = true;
11410            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11411        }
11412        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11413            mPersistentStartingProcesses.add(app);
11414            startProcessLocked(app, "added application", app.processName, abiOverride,
11415                    null /* entryPoint */, null /* entryPointArgs */);
11416        }
11417
11418        return app;
11419    }
11420
11421    public void unhandledBack() {
11422        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11423                "unhandledBack()");
11424
11425        synchronized(this) {
11426            final long origId = Binder.clearCallingIdentity();
11427            try {
11428                getFocusedStack().unhandledBackLocked();
11429            } finally {
11430                Binder.restoreCallingIdentity(origId);
11431            }
11432        }
11433    }
11434
11435    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11436        enforceNotIsolatedCaller("openContentUri");
11437        final int userId = UserHandle.getCallingUserId();
11438        String name = uri.getAuthority();
11439        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11440        ParcelFileDescriptor pfd = null;
11441        if (cph != null) {
11442            // We record the binder invoker's uid in thread-local storage before
11443            // going to the content provider to open the file.  Later, in the code
11444            // that handles all permissions checks, we look for this uid and use
11445            // that rather than the Activity Manager's own uid.  The effect is that
11446            // we do the check against the caller's permissions even though it looks
11447            // to the content provider like the Activity Manager itself is making
11448            // the request.
11449            Binder token = new Binder();
11450            sCallerIdentity.set(new Identity(
11451                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11452            try {
11453                pfd = cph.provider.openFile(null, uri, "r", null, token);
11454            } catch (FileNotFoundException e) {
11455                // do nothing; pfd will be returned null
11456            } finally {
11457                // Ensure that whatever happens, we clean up the identity state
11458                sCallerIdentity.remove();
11459                // Ensure we're done with the provider.
11460                removeContentProviderExternalUnchecked(name, null, userId);
11461            }
11462        } else {
11463            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11464        }
11465        return pfd;
11466    }
11467
11468    // Actually is sleeping or shutting down or whatever else in the future
11469    // is an inactive state.
11470    public boolean isSleepingOrShuttingDown() {
11471        return isSleeping() || mShuttingDown;
11472    }
11473
11474    public boolean isSleeping() {
11475        return mSleeping;
11476    }
11477
11478    void onWakefulnessChanged(int wakefulness) {
11479        synchronized(this) {
11480            mWakefulness = wakefulness;
11481            updateSleepIfNeededLocked();
11482        }
11483    }
11484
11485    void finishRunningVoiceLocked() {
11486        if (mRunningVoice != null) {
11487            mRunningVoice = null;
11488            mVoiceWakeLock.release();
11489            updateSleepIfNeededLocked();
11490        }
11491    }
11492
11493    void startTimeTrackingFocusedActivityLocked() {
11494        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11495            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11496        }
11497    }
11498
11499    void updateSleepIfNeededLocked() {
11500        if (mSleeping && !shouldSleepLocked()) {
11501            mSleeping = false;
11502            startTimeTrackingFocusedActivityLocked();
11503            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11504            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11505            updateOomAdjLocked();
11506        } else if (!mSleeping && shouldSleepLocked()) {
11507            mSleeping = true;
11508            if (mCurAppTimeTracker != null) {
11509                mCurAppTimeTracker.stop();
11510            }
11511            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11512            mStackSupervisor.goingToSleepLocked();
11513            updateOomAdjLocked();
11514
11515            // Initialize the wake times of all processes.
11516            checkExcessivePowerUsageLocked(false);
11517            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11518            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11519            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11520        }
11521    }
11522
11523    private boolean shouldSleepLocked() {
11524        // Resume applications while running a voice interactor.
11525        if (mRunningVoice != null) {
11526            return false;
11527        }
11528
11529        // TODO: Transform the lock screen state into a sleep token instead.
11530        switch (mWakefulness) {
11531            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11532            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11533            case PowerManagerInternal.WAKEFULNESS_DOZING:
11534                // Pause applications whenever the lock screen is shown or any sleep
11535                // tokens have been acquired.
11536                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11537            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11538            default:
11539                // If we're asleep then pause applications unconditionally.
11540                return true;
11541        }
11542    }
11543
11544    /** Pokes the task persister. */
11545    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11546        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11547    }
11548
11549    /** Notifies all listeners when the task stack has changed. */
11550    void notifyTaskStackChangedLocked() {
11551        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11552        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11553        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11554        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11555    }
11556
11557    /** Notifies all listeners when an Activity is pinned. */
11558    void notifyActivityPinnedLocked() {
11559        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11560        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11561    }
11562
11563    /**
11564     * Notifies all listeners when an attempt was made to start an an activity that is already
11565     * running in the pinned stack and the activity was not actually started, but the task is
11566     * either brought to the front or a new Intent is delivered to it.
11567     */
11568    void notifyPinnedActivityRestartAttemptLocked() {
11569        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11570        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11571    }
11572
11573    /** Notifies all listeners when the pinned stack animation ends. */
11574    @Override
11575    public void notifyPinnedStackAnimationEnded() {
11576        synchronized (this) {
11577            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11578            mHandler.obtainMessage(
11579                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11580        }
11581    }
11582
11583    @Override
11584    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11585        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11586    }
11587
11588    @Override
11589    public boolean shutdown(int timeout) {
11590        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11591                != PackageManager.PERMISSION_GRANTED) {
11592            throw new SecurityException("Requires permission "
11593                    + android.Manifest.permission.SHUTDOWN);
11594        }
11595
11596        boolean timedout = false;
11597
11598        synchronized(this) {
11599            mShuttingDown = true;
11600            updateEventDispatchingLocked();
11601            timedout = mStackSupervisor.shutdownLocked(timeout);
11602        }
11603
11604        mAppOpsService.shutdown();
11605        if (mUsageStatsService != null) {
11606            mUsageStatsService.prepareShutdown();
11607        }
11608        mBatteryStatsService.shutdown();
11609        synchronized (this) {
11610            mProcessStats.shutdownLocked();
11611            notifyTaskPersisterLocked(null, true);
11612        }
11613
11614        return timedout;
11615    }
11616
11617    public final void activitySlept(IBinder token) {
11618        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11619
11620        final long origId = Binder.clearCallingIdentity();
11621
11622        synchronized (this) {
11623            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11624            if (r != null) {
11625                mStackSupervisor.activitySleptLocked(r);
11626            }
11627        }
11628
11629        Binder.restoreCallingIdentity(origId);
11630    }
11631
11632    private String lockScreenShownToString() {
11633        switch (mLockScreenShown) {
11634            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11635            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11636            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11637            default: return "Unknown=" + mLockScreenShown;
11638        }
11639    }
11640
11641    void logLockScreen(String msg) {
11642        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11643                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11644                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11645                + " mSleeping=" + mSleeping);
11646    }
11647
11648    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11649        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11650        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11651        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11652            boolean wasRunningVoice = mRunningVoice != null;
11653            mRunningVoice = session;
11654            if (!wasRunningVoice) {
11655                mVoiceWakeLock.acquire();
11656                updateSleepIfNeededLocked();
11657            }
11658        }
11659    }
11660
11661    private void updateEventDispatchingLocked() {
11662        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11663    }
11664
11665    public void setLockScreenShown(boolean showing, boolean occluded) {
11666        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11667                != PackageManager.PERMISSION_GRANTED) {
11668            throw new SecurityException("Requires permission "
11669                    + android.Manifest.permission.DEVICE_POWER);
11670        }
11671
11672        synchronized(this) {
11673            long ident = Binder.clearCallingIdentity();
11674            try {
11675                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11676                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11677                if (showing && occluded) {
11678                    // The lock screen is currently showing, but is occluded by a window that can
11679                    // show on top of the lock screen. In this can we want to dismiss the docked
11680                    // stack since it will be complicated/risky to try to put the activity on top
11681                    // of the lock screen in the right fullscreen configuration.
11682                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11683                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11684                }
11685
11686                updateSleepIfNeededLocked();
11687            } finally {
11688                Binder.restoreCallingIdentity(ident);
11689            }
11690        }
11691    }
11692
11693    @Override
11694    public void notifyLockedProfile(@UserIdInt int userId) {
11695        try {
11696            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11697                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11698            }
11699        } catch (RemoteException ex) {
11700            throw new SecurityException("Fail to check is caller a privileged app", ex);
11701        }
11702
11703        synchronized (this) {
11704            if (mStackSupervisor.isUserLockedProfile(userId)) {
11705                final long ident = Binder.clearCallingIdentity();
11706                try {
11707                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11708                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11709                        // If there is no device lock, we will show the profile's credential page.
11710                        mActivityStarter.showConfirmDeviceCredential(userId);
11711                    } else {
11712                        // Showing launcher to avoid user entering credential twice.
11713                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11714                    }
11715                } finally {
11716                    Binder.restoreCallingIdentity(ident);
11717                }
11718            }
11719        }
11720    }
11721
11722    @Override
11723    public void startConfirmDeviceCredentialIntent(Intent intent) {
11724        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11725        synchronized (this) {
11726            final long ident = Binder.clearCallingIdentity();
11727            try {
11728                mActivityStarter.startConfirmCredentialIntent(intent);
11729            } finally {
11730                Binder.restoreCallingIdentity(ident);
11731            }
11732        }
11733    }
11734
11735    @Override
11736    public void stopAppSwitches() {
11737        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11738                != PackageManager.PERMISSION_GRANTED) {
11739            throw new SecurityException("viewquires permission "
11740                    + android.Manifest.permission.STOP_APP_SWITCHES);
11741        }
11742
11743        synchronized(this) {
11744            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11745                    + APP_SWITCH_DELAY_TIME;
11746            mDidAppSwitch = false;
11747            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11748            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11749            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11750        }
11751    }
11752
11753    public void resumeAppSwitches() {
11754        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11755                != PackageManager.PERMISSION_GRANTED) {
11756            throw new SecurityException("Requires permission "
11757                    + android.Manifest.permission.STOP_APP_SWITCHES);
11758        }
11759
11760        synchronized(this) {
11761            // Note that we don't execute any pending app switches... we will
11762            // let those wait until either the timeout, or the next start
11763            // activity request.
11764            mAppSwitchesAllowedTime = 0;
11765        }
11766    }
11767
11768    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11769            int callingPid, int callingUid, String name) {
11770        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11771            return true;
11772        }
11773
11774        int perm = checkComponentPermission(
11775                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11776                sourceUid, -1, true);
11777        if (perm == PackageManager.PERMISSION_GRANTED) {
11778            return true;
11779        }
11780
11781        // If the actual IPC caller is different from the logical source, then
11782        // also see if they are allowed to control app switches.
11783        if (callingUid != -1 && callingUid != sourceUid) {
11784            perm = checkComponentPermission(
11785                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11786                    callingUid, -1, true);
11787            if (perm == PackageManager.PERMISSION_GRANTED) {
11788                return true;
11789            }
11790        }
11791
11792        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11793        return false;
11794    }
11795
11796    public void setDebugApp(String packageName, boolean waitForDebugger,
11797            boolean persistent) {
11798        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11799                "setDebugApp()");
11800
11801        long ident = Binder.clearCallingIdentity();
11802        try {
11803            // Note that this is not really thread safe if there are multiple
11804            // callers into it at the same time, but that's not a situation we
11805            // care about.
11806            if (persistent) {
11807                final ContentResolver resolver = mContext.getContentResolver();
11808                Settings.Global.putString(
11809                    resolver, Settings.Global.DEBUG_APP,
11810                    packageName);
11811                Settings.Global.putInt(
11812                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11813                    waitForDebugger ? 1 : 0);
11814            }
11815
11816            synchronized (this) {
11817                if (!persistent) {
11818                    mOrigDebugApp = mDebugApp;
11819                    mOrigWaitForDebugger = mWaitForDebugger;
11820                }
11821                mDebugApp = packageName;
11822                mWaitForDebugger = waitForDebugger;
11823                mDebugTransient = !persistent;
11824                if (packageName != null) {
11825                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11826                            false, UserHandle.USER_ALL, "set debug app");
11827                }
11828            }
11829        } finally {
11830            Binder.restoreCallingIdentity(ident);
11831        }
11832    }
11833
11834    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11835        synchronized (this) {
11836            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11837            if (!isDebuggable) {
11838                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11839                    throw new SecurityException("Process not debuggable: " + app.packageName);
11840                }
11841            }
11842
11843            mTrackAllocationApp = processName;
11844        }
11845    }
11846
11847    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11848        synchronized (this) {
11849            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11850            if (!isDebuggable) {
11851                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11852                    throw new SecurityException("Process not debuggable: " + app.packageName);
11853                }
11854            }
11855            mProfileApp = processName;
11856            mProfileFile = profilerInfo.profileFile;
11857            if (mProfileFd != null) {
11858                try {
11859                    mProfileFd.close();
11860                } catch (IOException e) {
11861                }
11862                mProfileFd = null;
11863            }
11864            mProfileFd = profilerInfo.profileFd;
11865            mSamplingInterval = profilerInfo.samplingInterval;
11866            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11867            mProfileType = 0;
11868        }
11869    }
11870
11871    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11872        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11873        if (!isDebuggable) {
11874            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11875                throw new SecurityException("Process not debuggable: " + app.packageName);
11876            }
11877        }
11878        mNativeDebuggingApp = processName;
11879    }
11880
11881    @Override
11882    public void setAlwaysFinish(boolean enabled) {
11883        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11884                "setAlwaysFinish()");
11885
11886        long ident = Binder.clearCallingIdentity();
11887        try {
11888            Settings.Global.putInt(
11889                    mContext.getContentResolver(),
11890                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11891
11892            synchronized (this) {
11893                mAlwaysFinishActivities = enabled;
11894            }
11895        } finally {
11896            Binder.restoreCallingIdentity(ident);
11897        }
11898    }
11899
11900    @Override
11901    public void setLenientBackgroundCheck(boolean enabled) {
11902        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11903                "setLenientBackgroundCheck()");
11904
11905        long ident = Binder.clearCallingIdentity();
11906        try {
11907            Settings.Global.putInt(
11908                    mContext.getContentResolver(),
11909                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11910
11911            synchronized (this) {
11912                mLenientBackgroundCheck = enabled;
11913            }
11914        } finally {
11915            Binder.restoreCallingIdentity(ident);
11916        }
11917    }
11918
11919    @Override
11920    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11921        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11922                "setActivityController()");
11923        synchronized (this) {
11924            mController = controller;
11925            mControllerIsAMonkey = imAMonkey;
11926            Watchdog.getInstance().setActivityController(controller);
11927        }
11928    }
11929
11930    @Override
11931    public void setUserIsMonkey(boolean userIsMonkey) {
11932        synchronized (this) {
11933            synchronized (mPidsSelfLocked) {
11934                final int callingPid = Binder.getCallingPid();
11935                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11936                if (precessRecord == null) {
11937                    throw new SecurityException("Unknown process: " + callingPid);
11938                }
11939                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11940                    throw new SecurityException("Only an instrumentation process "
11941                            + "with a UiAutomation can call setUserIsMonkey");
11942                }
11943            }
11944            mUserIsMonkey = userIsMonkey;
11945        }
11946    }
11947
11948    @Override
11949    public boolean isUserAMonkey() {
11950        synchronized (this) {
11951            // If there is a controller also implies the user is a monkey.
11952            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11953        }
11954    }
11955
11956    public void requestBugReport(int bugreportType) {
11957        String service = null;
11958        switch (bugreportType) {
11959            case ActivityManager.BUGREPORT_OPTION_FULL:
11960                service = "bugreport";
11961                break;
11962            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11963                service = "bugreportplus";
11964                break;
11965            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11966                service = "bugreportremote";
11967                break;
11968        }
11969        if (service == null) {
11970            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11971                    + bugreportType);
11972        }
11973        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11974        SystemProperties.set("ctl.start", service);
11975    }
11976
11977    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11978        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11979    }
11980
11981    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11982        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11983            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11984        }
11985        return KEY_DISPATCHING_TIMEOUT;
11986    }
11987
11988    @Override
11989    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11990        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11991                != PackageManager.PERMISSION_GRANTED) {
11992            throw new SecurityException("Requires permission "
11993                    + android.Manifest.permission.FILTER_EVENTS);
11994        }
11995        ProcessRecord proc;
11996        long timeout;
11997        synchronized (this) {
11998            synchronized (mPidsSelfLocked) {
11999                proc = mPidsSelfLocked.get(pid);
12000            }
12001            timeout = getInputDispatchingTimeoutLocked(proc);
12002        }
12003
12004        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12005            return -1;
12006        }
12007
12008        return timeout;
12009    }
12010
12011    /**
12012     * Handle input dispatching timeouts.
12013     * Returns whether input dispatching should be aborted or not.
12014     */
12015    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12016            final ActivityRecord activity, final ActivityRecord parent,
12017            final boolean aboveSystem, String reason) {
12018        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12019                != PackageManager.PERMISSION_GRANTED) {
12020            throw new SecurityException("Requires permission "
12021                    + android.Manifest.permission.FILTER_EVENTS);
12022        }
12023
12024        final String annotation;
12025        if (reason == null) {
12026            annotation = "Input dispatching timed out";
12027        } else {
12028            annotation = "Input dispatching timed out (" + reason + ")";
12029        }
12030
12031        if (proc != null) {
12032            synchronized (this) {
12033                if (proc.debugging) {
12034                    return false;
12035                }
12036
12037                if (mDidDexOpt) {
12038                    // Give more time since we were dexopting.
12039                    mDidDexOpt = false;
12040                    return false;
12041                }
12042
12043                if (proc.instrumentationClass != null) {
12044                    Bundle info = new Bundle();
12045                    info.putString("shortMsg", "keyDispatchingTimedOut");
12046                    info.putString("longMsg", annotation);
12047                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12048                    return true;
12049                }
12050            }
12051            mHandler.post(new Runnable() {
12052                @Override
12053                public void run() {
12054                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12055                }
12056            });
12057        }
12058
12059        return true;
12060    }
12061
12062    @Override
12063    public Bundle getAssistContextExtras(int requestType) {
12064        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12065                null, null, true /* focused */, true /* newSessionId */,
12066                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12067        if (pae == null) {
12068            return null;
12069        }
12070        synchronized (pae) {
12071            while (!pae.haveResult) {
12072                try {
12073                    pae.wait();
12074                } catch (InterruptedException e) {
12075                }
12076            }
12077        }
12078        synchronized (this) {
12079            buildAssistBundleLocked(pae, pae.result);
12080            mPendingAssistExtras.remove(pae);
12081            mUiHandler.removeCallbacks(pae);
12082        }
12083        return pae.extras;
12084    }
12085
12086    @Override
12087    public boolean isAssistDataAllowedOnCurrentActivity() {
12088        int userId;
12089        synchronized (this) {
12090            userId = mUserController.getCurrentUserIdLocked();
12091            ActivityRecord activity = getFocusedStack().topActivity();
12092            if (activity == null) {
12093                return false;
12094            }
12095            userId = activity.userId;
12096        }
12097        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12098                Context.DEVICE_POLICY_SERVICE);
12099        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12100    }
12101
12102    @Override
12103    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12104        long ident = Binder.clearCallingIdentity();
12105        try {
12106            synchronized (this) {
12107                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12108                ActivityRecord top = getFocusedStack().topActivity();
12109                if (top != caller) {
12110                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12111                            + " is not current top " + top);
12112                    return false;
12113                }
12114                if (!top.nowVisible) {
12115                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12116                            + " is not visible");
12117                    return false;
12118                }
12119            }
12120            AssistUtils utils = new AssistUtils(mContext);
12121            return utils.showSessionForActiveService(args,
12122                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12123        } finally {
12124            Binder.restoreCallingIdentity(ident);
12125        }
12126    }
12127
12128    @Override
12129    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12130            Bundle receiverExtras,
12131            IBinder activityToken, boolean focused, boolean newSessionId) {
12132        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12133                activityToken, focused, newSessionId,
12134                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12135                != null;
12136    }
12137
12138    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12139            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12140            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12141        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12142                "enqueueAssistContext()");
12143        synchronized (this) {
12144            ActivityRecord activity = getFocusedStack().topActivity();
12145            if (activity == null) {
12146                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12147                return null;
12148            }
12149            if (activity.app == null || activity.app.thread == null) {
12150                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12151                return null;
12152            }
12153            if (focused) {
12154                if (activityToken != null) {
12155                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12156                    if (activity != caller) {
12157                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12158                                + " is not current top " + activity);
12159                        return null;
12160                    }
12161                }
12162            } else {
12163                activity = ActivityRecord.forTokenLocked(activityToken);
12164                if (activity == null) {
12165                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12166                            + " couldn't be found");
12167                    return null;
12168                }
12169            }
12170
12171            PendingAssistExtras pae;
12172            Bundle extras = new Bundle();
12173            if (args != null) {
12174                extras.putAll(args);
12175            }
12176            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12177            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12178            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12179                    userHandle);
12180            // Increment the sessionId if necessary
12181            if (newSessionId) {
12182                mViSessionId++;
12183            }
12184            try {
12185                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12186                        requestType, mViSessionId);
12187                mPendingAssistExtras.add(pae);
12188                mUiHandler.postDelayed(pae, timeout);
12189            } catch (RemoteException e) {
12190                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12191                return null;
12192            }
12193            return pae;
12194        }
12195    }
12196
12197    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12198        IResultReceiver receiver;
12199        synchronized (this) {
12200            mPendingAssistExtras.remove(pae);
12201            receiver = pae.receiver;
12202        }
12203        if (receiver != null) {
12204            // Caller wants result sent back to them.
12205            Bundle sendBundle = new Bundle();
12206            // At least return the receiver extras
12207            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12208                    pae.receiverExtras);
12209            try {
12210                pae.receiver.send(0, sendBundle);
12211            } catch (RemoteException e) {
12212            }
12213        }
12214    }
12215
12216    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12217        if (result != null) {
12218            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12219        }
12220        if (pae.hint != null) {
12221            pae.extras.putBoolean(pae.hint, true);
12222        }
12223    }
12224
12225    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12226            AssistContent content, Uri referrer) {
12227        PendingAssistExtras pae = (PendingAssistExtras)token;
12228        synchronized (pae) {
12229            pae.result = extras;
12230            pae.structure = structure;
12231            pae.content = content;
12232            if (referrer != null) {
12233                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12234            }
12235            pae.haveResult = true;
12236            pae.notifyAll();
12237            if (pae.intent == null && pae.receiver == null) {
12238                // Caller is just waiting for the result.
12239                return;
12240            }
12241        }
12242
12243        // We are now ready to launch the assist activity.
12244        IResultReceiver sendReceiver = null;
12245        Bundle sendBundle = null;
12246        synchronized (this) {
12247            buildAssistBundleLocked(pae, extras);
12248            boolean exists = mPendingAssistExtras.remove(pae);
12249            mUiHandler.removeCallbacks(pae);
12250            if (!exists) {
12251                // Timed out.
12252                return;
12253            }
12254            if ((sendReceiver=pae.receiver) != null) {
12255                // Caller wants result sent back to them.
12256                sendBundle = new Bundle();
12257                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12258                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12259                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12260                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12261                        pae.receiverExtras);
12262            }
12263        }
12264        if (sendReceiver != null) {
12265            try {
12266                sendReceiver.send(0, sendBundle);
12267            } catch (RemoteException e) {
12268            }
12269            return;
12270        }
12271
12272        long ident = Binder.clearCallingIdentity();
12273        try {
12274            pae.intent.replaceExtras(pae.extras);
12275            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12276                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12277                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12278            closeSystemDialogs("assist");
12279            try {
12280                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12281            } catch (ActivityNotFoundException e) {
12282                Slog.w(TAG, "No activity to handle assist action.", e);
12283            }
12284        } finally {
12285            Binder.restoreCallingIdentity(ident);
12286        }
12287    }
12288
12289    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12290            Bundle args) {
12291        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12292                true /* focused */, true /* newSessionId */,
12293                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12294    }
12295
12296    public void registerProcessObserver(IProcessObserver observer) {
12297        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12298                "registerProcessObserver()");
12299        synchronized (this) {
12300            mProcessObservers.register(observer);
12301        }
12302    }
12303
12304    @Override
12305    public void unregisterProcessObserver(IProcessObserver observer) {
12306        synchronized (this) {
12307            mProcessObservers.unregister(observer);
12308        }
12309    }
12310
12311    @Override
12312    public void registerUidObserver(IUidObserver observer, int which) {
12313        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12314                "registerUidObserver()");
12315        synchronized (this) {
12316            mUidObservers.register(observer, which);
12317        }
12318    }
12319
12320    @Override
12321    public void unregisterUidObserver(IUidObserver observer) {
12322        synchronized (this) {
12323            mUidObservers.unregister(observer);
12324        }
12325    }
12326
12327    @Override
12328    public boolean convertFromTranslucent(IBinder token) {
12329        final long origId = Binder.clearCallingIdentity();
12330        try {
12331            synchronized (this) {
12332                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12333                if (r == null) {
12334                    return false;
12335                }
12336                final boolean translucentChanged = r.changeWindowTranslucency(true);
12337                if (translucentChanged) {
12338                    r.task.stack.releaseBackgroundResources(r);
12339                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12340                }
12341                mWindowManager.setAppFullscreen(token, true);
12342                return translucentChanged;
12343            }
12344        } finally {
12345            Binder.restoreCallingIdentity(origId);
12346        }
12347    }
12348
12349    @Override
12350    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12351        final long origId = Binder.clearCallingIdentity();
12352        try {
12353            synchronized (this) {
12354                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12355                if (r == null) {
12356                    return false;
12357                }
12358                int index = r.task.mActivities.lastIndexOf(r);
12359                if (index > 0) {
12360                    ActivityRecord under = r.task.mActivities.get(index - 1);
12361                    under.returningOptions = options;
12362                }
12363                final boolean translucentChanged = r.changeWindowTranslucency(false);
12364                if (translucentChanged) {
12365                    r.task.stack.convertActivityToTranslucent(r);
12366                }
12367                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12368                mWindowManager.setAppFullscreen(token, false);
12369                return translucentChanged;
12370            }
12371        } finally {
12372            Binder.restoreCallingIdentity(origId);
12373        }
12374    }
12375
12376    @Override
12377    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12378        final long origId = Binder.clearCallingIdentity();
12379        try {
12380            synchronized (this) {
12381                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12382                if (r != null) {
12383                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12384                }
12385            }
12386            return false;
12387        } finally {
12388            Binder.restoreCallingIdentity(origId);
12389        }
12390    }
12391
12392    @Override
12393    public boolean isBackgroundVisibleBehind(IBinder token) {
12394        final long origId = Binder.clearCallingIdentity();
12395        try {
12396            synchronized (this) {
12397                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12398                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12399                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12400                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12401                return visible;
12402            }
12403        } finally {
12404            Binder.restoreCallingIdentity(origId);
12405        }
12406    }
12407
12408    @Override
12409    public ActivityOptions getActivityOptions(IBinder token) {
12410        final long origId = Binder.clearCallingIdentity();
12411        try {
12412            synchronized (this) {
12413                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12414                if (r != null) {
12415                    final ActivityOptions activityOptions = r.pendingOptions;
12416                    r.pendingOptions = null;
12417                    return activityOptions;
12418                }
12419                return null;
12420            }
12421        } finally {
12422            Binder.restoreCallingIdentity(origId);
12423        }
12424    }
12425
12426    @Override
12427    public void setImmersive(IBinder token, boolean immersive) {
12428        synchronized(this) {
12429            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12430            if (r == null) {
12431                throw new IllegalArgumentException();
12432            }
12433            r.immersive = immersive;
12434
12435            // update associated state if we're frontmost
12436            if (r == mFocusedActivity) {
12437                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12438                applyUpdateLockStateLocked(r);
12439            }
12440        }
12441    }
12442
12443    @Override
12444    public boolean isImmersive(IBinder token) {
12445        synchronized (this) {
12446            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12447            if (r == null) {
12448                throw new IllegalArgumentException();
12449            }
12450            return r.immersive;
12451        }
12452    }
12453
12454    @Override
12455    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12456        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12457            throw new UnsupportedOperationException("VR mode not supported on this device!");
12458        }
12459
12460        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12461
12462        ActivityRecord r;
12463        synchronized (this) {
12464            r = ActivityRecord.isInStackLocked(token);
12465        }
12466
12467        if (r == null) {
12468            throw new IllegalArgumentException();
12469        }
12470
12471        int err;
12472        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12473                VrManagerInternal.NO_ERROR) {
12474            return err;
12475        }
12476
12477        synchronized(this) {
12478            r.requestedVrComponent = (enabled) ? packageName : null;
12479
12480            // Update associated state if this activity is currently focused
12481            if (r == mFocusedActivity) {
12482                applyUpdateVrModeLocked(r);
12483            }
12484            return 0;
12485        }
12486    }
12487
12488    @Override
12489    public boolean isVrModePackageEnabled(ComponentName packageName) {
12490        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12491            throw new UnsupportedOperationException("VR mode not supported on this device!");
12492        }
12493
12494        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12495
12496        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12497                VrManagerInternal.NO_ERROR;
12498    }
12499
12500    public boolean isTopActivityImmersive() {
12501        enforceNotIsolatedCaller("startActivity");
12502        synchronized (this) {
12503            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12504            return (r != null) ? r.immersive : false;
12505        }
12506    }
12507
12508    @Override
12509    public boolean isTopOfTask(IBinder token) {
12510        synchronized (this) {
12511            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12512            if (r == null) {
12513                throw new IllegalArgumentException();
12514            }
12515            return r.task.getTopActivity() == r;
12516        }
12517    }
12518
12519    public final void enterSafeMode() {
12520        synchronized(this) {
12521            // It only makes sense to do this before the system is ready
12522            // and started launching other packages.
12523            if (!mSystemReady) {
12524                try {
12525                    AppGlobals.getPackageManager().enterSafeMode();
12526                } catch (RemoteException e) {
12527                }
12528            }
12529
12530            mSafeMode = true;
12531        }
12532    }
12533
12534    public final void showSafeModeOverlay() {
12535        View v = LayoutInflater.from(mContext).inflate(
12536                com.android.internal.R.layout.safe_mode, null);
12537        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12538        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12539        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12540        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12541        lp.gravity = Gravity.BOTTOM | Gravity.START;
12542        lp.format = v.getBackground().getOpacity();
12543        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12544                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12545        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12546        ((WindowManager)mContext.getSystemService(
12547                Context.WINDOW_SERVICE)).addView(v, lp);
12548    }
12549
12550    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12551        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12552            return;
12553        }
12554        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12555        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12556        synchronized (stats) {
12557            if (mBatteryStatsService.isOnBattery()) {
12558                mBatteryStatsService.enforceCallingPermission();
12559                int MY_UID = Binder.getCallingUid();
12560                final int uid;
12561                if (sender == null) {
12562                    uid = sourceUid;
12563                } else {
12564                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12565                }
12566                BatteryStatsImpl.Uid.Pkg pkg =
12567                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12568                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12569                pkg.noteWakeupAlarmLocked(tag);
12570            }
12571        }
12572    }
12573
12574    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12575        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12576            return;
12577        }
12578        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12579        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12580        synchronized (stats) {
12581            mBatteryStatsService.enforceCallingPermission();
12582            int MY_UID = Binder.getCallingUid();
12583            final int uid;
12584            if (sender == null) {
12585                uid = sourceUid;
12586            } else {
12587                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12588            }
12589            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12590        }
12591    }
12592
12593    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12594        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12595            return;
12596        }
12597        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12598        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12599        synchronized (stats) {
12600            mBatteryStatsService.enforceCallingPermission();
12601            int MY_UID = Binder.getCallingUid();
12602            final int uid;
12603            if (sender == null) {
12604                uid = sourceUid;
12605            } else {
12606                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12607            }
12608            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12609        }
12610    }
12611
12612    public boolean killPids(int[] pids, String pReason, boolean secure) {
12613        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12614            throw new SecurityException("killPids only available to the system");
12615        }
12616        String reason = (pReason == null) ? "Unknown" : pReason;
12617        // XXX Note: don't acquire main activity lock here, because the window
12618        // manager calls in with its locks held.
12619
12620        boolean killed = false;
12621        synchronized (mPidsSelfLocked) {
12622            int worstType = 0;
12623            for (int i=0; i<pids.length; i++) {
12624                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12625                if (proc != null) {
12626                    int type = proc.setAdj;
12627                    if (type > worstType) {
12628                        worstType = type;
12629                    }
12630                }
12631            }
12632
12633            // If the worst oom_adj is somewhere in the cached proc LRU range,
12634            // then constrain it so we will kill all cached procs.
12635            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12636                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12637                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12638            }
12639
12640            // If this is not a secure call, don't let it kill processes that
12641            // are important.
12642            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12643                worstType = ProcessList.SERVICE_ADJ;
12644            }
12645
12646            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12647            for (int i=0; i<pids.length; i++) {
12648                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12649                if (proc == null) {
12650                    continue;
12651                }
12652                int adj = proc.setAdj;
12653                if (adj >= worstType && !proc.killedByAm) {
12654                    proc.kill(reason, true);
12655                    killed = true;
12656                }
12657            }
12658        }
12659        return killed;
12660    }
12661
12662    @Override
12663    public void killUid(int appId, int userId, String reason) {
12664        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12665        synchronized (this) {
12666            final long identity = Binder.clearCallingIdentity();
12667            try {
12668                killPackageProcessesLocked(null, appId, userId,
12669                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12670                        reason != null ? reason : "kill uid");
12671            } finally {
12672                Binder.restoreCallingIdentity(identity);
12673            }
12674        }
12675    }
12676
12677    @Override
12678    public boolean killProcessesBelowForeground(String reason) {
12679        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12680            throw new SecurityException("killProcessesBelowForeground() only available to system");
12681        }
12682
12683        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12684    }
12685
12686    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12687        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12688            throw new SecurityException("killProcessesBelowAdj() only available to system");
12689        }
12690
12691        boolean killed = false;
12692        synchronized (mPidsSelfLocked) {
12693            final int size = mPidsSelfLocked.size();
12694            for (int i = 0; i < size; i++) {
12695                final int pid = mPidsSelfLocked.keyAt(i);
12696                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12697                if (proc == null) continue;
12698
12699                final int adj = proc.setAdj;
12700                if (adj > belowAdj && !proc.killedByAm) {
12701                    proc.kill(reason, true);
12702                    killed = true;
12703                }
12704            }
12705        }
12706        return killed;
12707    }
12708
12709    @Override
12710    public void hang(final IBinder who, boolean allowRestart) {
12711        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12712                != PackageManager.PERMISSION_GRANTED) {
12713            throw new SecurityException("Requires permission "
12714                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12715        }
12716
12717        final IBinder.DeathRecipient death = new DeathRecipient() {
12718            @Override
12719            public void binderDied() {
12720                synchronized (this) {
12721                    notifyAll();
12722                }
12723            }
12724        };
12725
12726        try {
12727            who.linkToDeath(death, 0);
12728        } catch (RemoteException e) {
12729            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12730            return;
12731        }
12732
12733        synchronized (this) {
12734            Watchdog.getInstance().setAllowRestart(allowRestart);
12735            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12736            synchronized (death) {
12737                while (who.isBinderAlive()) {
12738                    try {
12739                        death.wait();
12740                    } catch (InterruptedException e) {
12741                    }
12742                }
12743            }
12744            Watchdog.getInstance().setAllowRestart(true);
12745        }
12746    }
12747
12748    @Override
12749    public void restart() {
12750        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12751                != PackageManager.PERMISSION_GRANTED) {
12752            throw new SecurityException("Requires permission "
12753                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12754        }
12755
12756        Log.i(TAG, "Sending shutdown broadcast...");
12757
12758        BroadcastReceiver br = new BroadcastReceiver() {
12759            @Override public void onReceive(Context context, Intent intent) {
12760                // Now the broadcast is done, finish up the low-level shutdown.
12761                Log.i(TAG, "Shutting down activity manager...");
12762                shutdown(10000);
12763                Log.i(TAG, "Shutdown complete, restarting!");
12764                Process.killProcess(Process.myPid());
12765                System.exit(10);
12766            }
12767        };
12768
12769        // First send the high-level shut down broadcast.
12770        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12771        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12772        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12773        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12774        mContext.sendOrderedBroadcastAsUser(intent,
12775                UserHandle.ALL, null, br, mHandler, 0, null, null);
12776        */
12777        br.onReceive(mContext, intent);
12778    }
12779
12780    private long getLowRamTimeSinceIdle(long now) {
12781        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12782    }
12783
12784    @Override
12785    public void performIdleMaintenance() {
12786        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12787                != PackageManager.PERMISSION_GRANTED) {
12788            throw new SecurityException("Requires permission "
12789                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12790        }
12791
12792        synchronized (this) {
12793            final long now = SystemClock.uptimeMillis();
12794            final long timeSinceLastIdle = now - mLastIdleTime;
12795            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12796            mLastIdleTime = now;
12797            mLowRamTimeSinceLastIdle = 0;
12798            if (mLowRamStartTime != 0) {
12799                mLowRamStartTime = now;
12800            }
12801
12802            StringBuilder sb = new StringBuilder(128);
12803            sb.append("Idle maintenance over ");
12804            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12805            sb.append(" low RAM for ");
12806            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12807            Slog.i(TAG, sb.toString());
12808
12809            // If at least 1/3 of our time since the last idle period has been spent
12810            // with RAM low, then we want to kill processes.
12811            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12812
12813            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12814                ProcessRecord proc = mLruProcesses.get(i);
12815                if (proc.notCachedSinceIdle) {
12816                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12817                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12818                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12819                        if (doKilling && proc.initialIdlePss != 0
12820                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12821                            sb = new StringBuilder(128);
12822                            sb.append("Kill");
12823                            sb.append(proc.processName);
12824                            sb.append(" in idle maint: pss=");
12825                            sb.append(proc.lastPss);
12826                            sb.append(", swapPss=");
12827                            sb.append(proc.lastSwapPss);
12828                            sb.append(", initialPss=");
12829                            sb.append(proc.initialIdlePss);
12830                            sb.append(", period=");
12831                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12832                            sb.append(", lowRamPeriod=");
12833                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12834                            Slog.wtfQuiet(TAG, sb.toString());
12835                            proc.kill("idle maint (pss " + proc.lastPss
12836                                    + " from " + proc.initialIdlePss + ")", true);
12837                        }
12838                    }
12839                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12840                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12841                    proc.notCachedSinceIdle = true;
12842                    proc.initialIdlePss = 0;
12843                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12844                            mTestPssMode, isSleeping(), now);
12845                }
12846            }
12847
12848            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12849            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12850        }
12851    }
12852
12853    @Override
12854    public void sendIdleJobTrigger() {
12855        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12856                != PackageManager.PERMISSION_GRANTED) {
12857            throw new SecurityException("Requires permission "
12858                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12859        }
12860
12861        final long ident = Binder.clearCallingIdentity();
12862        try {
12863            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12864                    .setPackage("android")
12865                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12866            broadcastIntent(null, intent, null, null, 0, null, null, null,
12867                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12868        } finally {
12869            Binder.restoreCallingIdentity(ident);
12870        }
12871    }
12872
12873    private void retrieveSettings() {
12874        final ContentResolver resolver = mContext.getContentResolver();
12875        final boolean freeformWindowManagement =
12876                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12877                        || Settings.Global.getInt(
12878                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12879        final boolean supportsPictureInPicture =
12880                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12881
12882        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12883        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12884        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12885        final boolean alwaysFinishActivities =
12886                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12887        final boolean lenientBackgroundCheck =
12888                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12889        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12890        final boolean forceResizable = Settings.Global.getInt(
12891                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12892        final boolean supportsLeanbackOnly =
12893                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12894
12895        // Transfer any global setting for forcing RTL layout, into a System Property
12896        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12897
12898        final Configuration configuration = new Configuration();
12899        Settings.System.getConfiguration(resolver, configuration);
12900        if (forceRtl) {
12901            // This will take care of setting the correct layout direction flags
12902            configuration.setLayoutDirection(configuration.locale);
12903        }
12904
12905        synchronized (this) {
12906            mDebugApp = mOrigDebugApp = debugApp;
12907            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12908            mAlwaysFinishActivities = alwaysFinishActivities;
12909            mLenientBackgroundCheck = lenientBackgroundCheck;
12910            mSupportsLeanbackOnly = supportsLeanbackOnly;
12911            mForceResizableActivities = forceResizable;
12912            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12913            if (supportsMultiWindow || forceResizable) {
12914                mSupportsMultiWindow = true;
12915                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12916                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12917            } else {
12918                mSupportsMultiWindow = false;
12919                mSupportsFreeformWindowManagement = false;
12920                mSupportsPictureInPicture = false;
12921            }
12922            // This happens before any activities are started, so we can
12923            // change mConfiguration in-place.
12924            updateConfigurationLocked(configuration, null, true);
12925            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12926                    "Initial config: " + mConfiguration);
12927
12928            // Load resources only after the current configuration has been set.
12929            final Resources res = mContext.getResources();
12930            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12931            mThumbnailWidth = res.getDimensionPixelSize(
12932                    com.android.internal.R.dimen.thumbnail_width);
12933            mThumbnailHeight = res.getDimensionPixelSize(
12934                    com.android.internal.R.dimen.thumbnail_height);
12935            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12936                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12937            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12938                    com.android.internal.R.string.config_appsNotReportingCrashes));
12939            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12940                mFullscreenThumbnailScale = (float) res
12941                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12942                    (float) mConfiguration.screenWidthDp;
12943            } else {
12944                mFullscreenThumbnailScale = res.getFraction(
12945                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12946            }
12947        }
12948    }
12949
12950    public boolean testIsSystemReady() {
12951        // no need to synchronize(this) just to read & return the value
12952        return mSystemReady;
12953    }
12954
12955    public void systemReady(final Runnable goingCallback) {
12956        synchronized(this) {
12957            if (mSystemReady) {
12958                // If we're done calling all the receivers, run the next "boot phase" passed in
12959                // by the SystemServer
12960                if (goingCallback != null) {
12961                    goingCallback.run();
12962                }
12963                return;
12964            }
12965
12966            mLocalDeviceIdleController
12967                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12968
12969            // Make sure we have the current profile info, since it is needed for security checks.
12970            mUserController.onSystemReady();
12971            mRecentTasks.onSystemReadyLocked();
12972            mAppOpsService.systemReady();
12973            mSystemReady = true;
12974        }
12975
12976        ArrayList<ProcessRecord> procsToKill = null;
12977        synchronized(mPidsSelfLocked) {
12978            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12979                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12980                if (!isAllowedWhileBooting(proc.info)){
12981                    if (procsToKill == null) {
12982                        procsToKill = new ArrayList<ProcessRecord>();
12983                    }
12984                    procsToKill.add(proc);
12985                }
12986            }
12987        }
12988
12989        synchronized(this) {
12990            if (procsToKill != null) {
12991                for (int i=procsToKill.size()-1; i>=0; i--) {
12992                    ProcessRecord proc = procsToKill.get(i);
12993                    Slog.i(TAG, "Removing system update proc: " + proc);
12994                    removeProcessLocked(proc, true, false, "system update done");
12995                }
12996            }
12997
12998            // Now that we have cleaned up any update processes, we
12999            // are ready to start launching real processes and know that
13000            // we won't trample on them any more.
13001            mProcessesReady = true;
13002        }
13003
13004        Slog.i(TAG, "System now ready");
13005        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13006            SystemClock.uptimeMillis());
13007
13008        synchronized(this) {
13009            // Make sure we have no pre-ready processes sitting around.
13010
13011            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13012                ResolveInfo ri = mContext.getPackageManager()
13013                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13014                                STOCK_PM_FLAGS);
13015                CharSequence errorMsg = null;
13016                if (ri != null) {
13017                    ActivityInfo ai = ri.activityInfo;
13018                    ApplicationInfo app = ai.applicationInfo;
13019                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13020                        mTopAction = Intent.ACTION_FACTORY_TEST;
13021                        mTopData = null;
13022                        mTopComponent = new ComponentName(app.packageName,
13023                                ai.name);
13024                    } else {
13025                        errorMsg = mContext.getResources().getText(
13026                                com.android.internal.R.string.factorytest_not_system);
13027                    }
13028                } else {
13029                    errorMsg = mContext.getResources().getText(
13030                            com.android.internal.R.string.factorytest_no_action);
13031                }
13032                if (errorMsg != null) {
13033                    mTopAction = null;
13034                    mTopData = null;
13035                    mTopComponent = null;
13036                    Message msg = Message.obtain();
13037                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13038                    msg.getData().putCharSequence("msg", errorMsg);
13039                    mUiHandler.sendMessage(msg);
13040                }
13041            }
13042        }
13043
13044        retrieveSettings();
13045        final int currentUserId;
13046        synchronized (this) {
13047            currentUserId = mUserController.getCurrentUserIdLocked();
13048            readGrantedUriPermissionsLocked();
13049        }
13050
13051        if (goingCallback != null) goingCallback.run();
13052
13053        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13054                Integer.toString(currentUserId), currentUserId);
13055        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13056                Integer.toString(currentUserId), currentUserId);
13057        mSystemServiceManager.startUser(currentUserId);
13058
13059        synchronized (this) {
13060            // Only start up encryption-aware persistent apps; once user is
13061            // unlocked we'll come back around and start unaware apps
13062            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13063
13064            // Start up initial activity.
13065            mBooting = true;
13066            // Enable home activity for system user, so that the system can always boot
13067            if (UserManager.isSplitSystemUser()) {
13068                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13069                try {
13070                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13071                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13072                            UserHandle.USER_SYSTEM);
13073                } catch (RemoteException e) {
13074                    throw e.rethrowAsRuntimeException();
13075                }
13076            }
13077            startHomeActivityLocked(currentUserId, "systemReady");
13078
13079            try {
13080                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13081                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13082                            + " data partition or your device will be unstable.");
13083                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13084                }
13085            } catch (RemoteException e) {
13086            }
13087
13088            if (!Build.isBuildConsistent()) {
13089                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13090                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13091            }
13092
13093            long ident = Binder.clearCallingIdentity();
13094            try {
13095                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13096                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13097                        | Intent.FLAG_RECEIVER_FOREGROUND);
13098                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13099                broadcastIntentLocked(null, null, intent,
13100                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13101                        null, false, false, MY_PID, Process.SYSTEM_UID,
13102                        currentUserId);
13103                intent = new Intent(Intent.ACTION_USER_STARTING);
13104                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13105                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13106                broadcastIntentLocked(null, null, intent,
13107                        null, new IIntentReceiver.Stub() {
13108                            @Override
13109                            public void performReceive(Intent intent, int resultCode, String data,
13110                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13111                                    throws RemoteException {
13112                            }
13113                        }, 0, null, null,
13114                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13115                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13116            } catch (Throwable t) {
13117                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13118            } finally {
13119                Binder.restoreCallingIdentity(ident);
13120            }
13121            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13122            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13123        }
13124    }
13125
13126    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13127        synchronized (this) {
13128            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13129        }
13130    }
13131
13132    void skipCurrentReceiverLocked(ProcessRecord app) {
13133        for (BroadcastQueue queue : mBroadcastQueues) {
13134            queue.skipCurrentReceiverLocked(app);
13135        }
13136    }
13137
13138    /**
13139     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13140     * The application process will exit immediately after this call returns.
13141     * @param app object of the crashing app, null for the system server
13142     * @param crashInfo describing the exception
13143     */
13144    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13145        ProcessRecord r = findAppProcess(app, "Crash");
13146        final String processName = app == null ? "system_server"
13147                : (r == null ? "unknown" : r.processName);
13148
13149        handleApplicationCrashInner("crash", r, processName, crashInfo);
13150    }
13151
13152    /* Native crash reporting uses this inner version because it needs to be somewhat
13153     * decoupled from the AM-managed cleanup lifecycle
13154     */
13155    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13156            ApplicationErrorReport.CrashInfo crashInfo) {
13157        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13158                UserHandle.getUserId(Binder.getCallingUid()), processName,
13159                r == null ? -1 : r.info.flags,
13160                crashInfo.exceptionClassName,
13161                crashInfo.exceptionMessage,
13162                crashInfo.throwFileName,
13163                crashInfo.throwLineNumber);
13164
13165        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13166
13167        mAppErrors.crashApplication(r, crashInfo);
13168    }
13169
13170    public void handleApplicationStrictModeViolation(
13171            IBinder app,
13172            int violationMask,
13173            StrictMode.ViolationInfo info) {
13174        ProcessRecord r = findAppProcess(app, "StrictMode");
13175        if (r == null) {
13176            return;
13177        }
13178
13179        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13180            Integer stackFingerprint = info.hashCode();
13181            boolean logIt = true;
13182            synchronized (mAlreadyLoggedViolatedStacks) {
13183                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13184                    logIt = false;
13185                    // TODO: sub-sample into EventLog for these, with
13186                    // the info.durationMillis?  Then we'd get
13187                    // the relative pain numbers, without logging all
13188                    // the stack traces repeatedly.  We'd want to do
13189                    // likewise in the client code, which also does
13190                    // dup suppression, before the Binder call.
13191                } else {
13192                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13193                        mAlreadyLoggedViolatedStacks.clear();
13194                    }
13195                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13196                }
13197            }
13198            if (logIt) {
13199                logStrictModeViolationToDropBox(r, info);
13200            }
13201        }
13202
13203        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13204            AppErrorResult result = new AppErrorResult();
13205            synchronized (this) {
13206                final long origId = Binder.clearCallingIdentity();
13207
13208                Message msg = Message.obtain();
13209                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13210                HashMap<String, Object> data = new HashMap<String, Object>();
13211                data.put("result", result);
13212                data.put("app", r);
13213                data.put("violationMask", violationMask);
13214                data.put("info", info);
13215                msg.obj = data;
13216                mUiHandler.sendMessage(msg);
13217
13218                Binder.restoreCallingIdentity(origId);
13219            }
13220            int res = result.get();
13221            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13222        }
13223    }
13224
13225    // Depending on the policy in effect, there could be a bunch of
13226    // these in quick succession so we try to batch these together to
13227    // minimize disk writes, number of dropbox entries, and maximize
13228    // compression, by having more fewer, larger records.
13229    private void logStrictModeViolationToDropBox(
13230            ProcessRecord process,
13231            StrictMode.ViolationInfo info) {
13232        if (info == null) {
13233            return;
13234        }
13235        final boolean isSystemApp = process == null ||
13236                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13237                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13238        final String processName = process == null ? "unknown" : process.processName;
13239        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13240        final DropBoxManager dbox = (DropBoxManager)
13241                mContext.getSystemService(Context.DROPBOX_SERVICE);
13242
13243        // Exit early if the dropbox isn't configured to accept this report type.
13244        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13245
13246        boolean bufferWasEmpty;
13247        boolean needsFlush;
13248        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13249        synchronized (sb) {
13250            bufferWasEmpty = sb.length() == 0;
13251            appendDropBoxProcessHeaders(process, processName, sb);
13252            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13253            sb.append("System-App: ").append(isSystemApp).append("\n");
13254            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13255            if (info.violationNumThisLoop != 0) {
13256                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13257            }
13258            if (info.numAnimationsRunning != 0) {
13259                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13260            }
13261            if (info.broadcastIntentAction != null) {
13262                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13263            }
13264            if (info.durationMillis != -1) {
13265                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13266            }
13267            if (info.numInstances != -1) {
13268                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13269            }
13270            if (info.tags != null) {
13271                for (String tag : info.tags) {
13272                    sb.append("Span-Tag: ").append(tag).append("\n");
13273                }
13274            }
13275            sb.append("\n");
13276            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13277                sb.append(info.crashInfo.stackTrace);
13278                sb.append("\n");
13279            }
13280            if (info.message != null) {
13281                sb.append(info.message);
13282                sb.append("\n");
13283            }
13284
13285            // Only buffer up to ~64k.  Various logging bits truncate
13286            // things at 128k.
13287            needsFlush = (sb.length() > 64 * 1024);
13288        }
13289
13290        // Flush immediately if the buffer's grown too large, or this
13291        // is a non-system app.  Non-system apps are isolated with a
13292        // different tag & policy and not batched.
13293        //
13294        // Batching is useful during internal testing with
13295        // StrictMode settings turned up high.  Without batching,
13296        // thousands of separate files could be created on boot.
13297        if (!isSystemApp || needsFlush) {
13298            new Thread("Error dump: " + dropboxTag) {
13299                @Override
13300                public void run() {
13301                    String report;
13302                    synchronized (sb) {
13303                        report = sb.toString();
13304                        sb.delete(0, sb.length());
13305                        sb.trimToSize();
13306                    }
13307                    if (report.length() != 0) {
13308                        dbox.addText(dropboxTag, report);
13309                    }
13310                }
13311            }.start();
13312            return;
13313        }
13314
13315        // System app batching:
13316        if (!bufferWasEmpty) {
13317            // An existing dropbox-writing thread is outstanding, so
13318            // we don't need to start it up.  The existing thread will
13319            // catch the buffer appends we just did.
13320            return;
13321        }
13322
13323        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13324        // (After this point, we shouldn't access AMS internal data structures.)
13325        new Thread("Error dump: " + dropboxTag) {
13326            @Override
13327            public void run() {
13328                // 5 second sleep to let stacks arrive and be batched together
13329                try {
13330                    Thread.sleep(5000);  // 5 seconds
13331                } catch (InterruptedException e) {}
13332
13333                String errorReport;
13334                synchronized (mStrictModeBuffer) {
13335                    errorReport = mStrictModeBuffer.toString();
13336                    if (errorReport.length() == 0) {
13337                        return;
13338                    }
13339                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13340                    mStrictModeBuffer.trimToSize();
13341                }
13342                dbox.addText(dropboxTag, errorReport);
13343            }
13344        }.start();
13345    }
13346
13347    /**
13348     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13349     * @param app object of the crashing app, null for the system server
13350     * @param tag reported by the caller
13351     * @param system whether this wtf is coming from the system
13352     * @param crashInfo describing the context of the error
13353     * @return true if the process should exit immediately (WTF is fatal)
13354     */
13355    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13356            final ApplicationErrorReport.CrashInfo crashInfo) {
13357        final int callingUid = Binder.getCallingUid();
13358        final int callingPid = Binder.getCallingPid();
13359
13360        if (system) {
13361            // If this is coming from the system, we could very well have low-level
13362            // system locks held, so we want to do this all asynchronously.  And we
13363            // never want this to become fatal, so there is that too.
13364            mHandler.post(new Runnable() {
13365                @Override public void run() {
13366                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13367                }
13368            });
13369            return false;
13370        }
13371
13372        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13373                crashInfo);
13374
13375        if (r != null && r.pid != Process.myPid() &&
13376                Settings.Global.getInt(mContext.getContentResolver(),
13377                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13378            mAppErrors.crashApplication(r, crashInfo);
13379            return true;
13380        } else {
13381            return false;
13382        }
13383    }
13384
13385    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13386            final ApplicationErrorReport.CrashInfo crashInfo) {
13387        final ProcessRecord r = findAppProcess(app, "WTF");
13388        final String processName = app == null ? "system_server"
13389                : (r == null ? "unknown" : r.processName);
13390
13391        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13392                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13393
13394        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13395
13396        return r;
13397    }
13398
13399    /**
13400     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13401     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13402     */
13403    private ProcessRecord findAppProcess(IBinder app, String reason) {
13404        if (app == null) {
13405            return null;
13406        }
13407
13408        synchronized (this) {
13409            final int NP = mProcessNames.getMap().size();
13410            for (int ip=0; ip<NP; ip++) {
13411                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13412                final int NA = apps.size();
13413                for (int ia=0; ia<NA; ia++) {
13414                    ProcessRecord p = apps.valueAt(ia);
13415                    if (p.thread != null && p.thread.asBinder() == app) {
13416                        return p;
13417                    }
13418                }
13419            }
13420
13421            Slog.w(TAG, "Can't find mystery application for " + reason
13422                    + " from pid=" + Binder.getCallingPid()
13423                    + " uid=" + Binder.getCallingUid() + ": " + app);
13424            return null;
13425        }
13426    }
13427
13428    /**
13429     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13430     * to append various headers to the dropbox log text.
13431     */
13432    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13433            StringBuilder sb) {
13434        // Watchdog thread ends up invoking this function (with
13435        // a null ProcessRecord) to add the stack file to dropbox.
13436        // Do not acquire a lock on this (am) in such cases, as it
13437        // could cause a potential deadlock, if and when watchdog
13438        // is invoked due to unavailability of lock on am and it
13439        // would prevent watchdog from killing system_server.
13440        if (process == null) {
13441            sb.append("Process: ").append(processName).append("\n");
13442            return;
13443        }
13444        // Note: ProcessRecord 'process' is guarded by the service
13445        // instance.  (notably process.pkgList, which could otherwise change
13446        // concurrently during execution of this method)
13447        synchronized (this) {
13448            sb.append("Process: ").append(processName).append("\n");
13449            int flags = process.info.flags;
13450            IPackageManager pm = AppGlobals.getPackageManager();
13451            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13452            for (int ip=0; ip<process.pkgList.size(); ip++) {
13453                String pkg = process.pkgList.keyAt(ip);
13454                sb.append("Package: ").append(pkg);
13455                try {
13456                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13457                    if (pi != null) {
13458                        sb.append(" v").append(pi.versionCode);
13459                        if (pi.versionName != null) {
13460                            sb.append(" (").append(pi.versionName).append(")");
13461                        }
13462                    }
13463                } catch (RemoteException e) {
13464                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13465                }
13466                sb.append("\n");
13467            }
13468        }
13469    }
13470
13471    private static String processClass(ProcessRecord process) {
13472        if (process == null || process.pid == MY_PID) {
13473            return "system_server";
13474        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13475            return "system_app";
13476        } else {
13477            return "data_app";
13478        }
13479    }
13480
13481    private volatile long mWtfClusterStart;
13482    private volatile int mWtfClusterCount;
13483
13484    /**
13485     * Write a description of an error (crash, WTF, ANR) to the drop box.
13486     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13487     * @param process which caused the error, null means the system server
13488     * @param activity which triggered the error, null if unknown
13489     * @param parent activity related to the error, null if unknown
13490     * @param subject line related to the error, null if absent
13491     * @param report in long form describing the error, null if absent
13492     * @param logFile to include in the report, null if none
13493     * @param crashInfo giving an application stack trace, null if absent
13494     */
13495    public void addErrorToDropBox(String eventType,
13496            ProcessRecord process, String processName, ActivityRecord activity,
13497            ActivityRecord parent, String subject,
13498            final String report, final File logFile,
13499            final ApplicationErrorReport.CrashInfo crashInfo) {
13500        // NOTE -- this must never acquire the ActivityManagerService lock,
13501        // otherwise the watchdog may be prevented from resetting the system.
13502
13503        final String dropboxTag = processClass(process) + "_" + eventType;
13504        final DropBoxManager dbox = (DropBoxManager)
13505                mContext.getSystemService(Context.DROPBOX_SERVICE);
13506
13507        // Exit early if the dropbox isn't configured to accept this report type.
13508        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13509
13510        // Rate-limit how often we're willing to do the heavy lifting below to
13511        // collect and record logs; currently 5 logs per 10 second period.
13512        final long now = SystemClock.elapsedRealtime();
13513        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13514            mWtfClusterStart = now;
13515            mWtfClusterCount = 1;
13516        } else {
13517            if (mWtfClusterCount++ >= 5) return;
13518        }
13519
13520        final StringBuilder sb = new StringBuilder(1024);
13521        appendDropBoxProcessHeaders(process, processName, sb);
13522        if (process != null) {
13523            sb.append("Foreground: ")
13524                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13525                    .append("\n");
13526        }
13527        if (activity != null) {
13528            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13529        }
13530        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13531            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13532        }
13533        if (parent != null && parent != activity) {
13534            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13535        }
13536        if (subject != null) {
13537            sb.append("Subject: ").append(subject).append("\n");
13538        }
13539        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13540        if (Debug.isDebuggerConnected()) {
13541            sb.append("Debugger: Connected\n");
13542        }
13543        sb.append("\n");
13544
13545        // Do the rest in a worker thread to avoid blocking the caller on I/O
13546        // (After this point, we shouldn't access AMS internal data structures.)
13547        Thread worker = new Thread("Error dump: " + dropboxTag) {
13548            @Override
13549            public void run() {
13550                if (report != null) {
13551                    sb.append(report);
13552                }
13553                if (logFile != null) {
13554                    try {
13555                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13556                                    "\n\n[[TRUNCATED]]"));
13557                    } catch (IOException e) {
13558                        Slog.e(TAG, "Error reading " + logFile, e);
13559                    }
13560                }
13561                if (crashInfo != null && crashInfo.stackTrace != null) {
13562                    sb.append(crashInfo.stackTrace);
13563                }
13564
13565                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13566                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13567                if (lines > 0) {
13568                    sb.append("\n");
13569
13570                    // Merge several logcat streams, and take the last N lines
13571                    InputStreamReader input = null;
13572                    try {
13573                        java.lang.Process logcat = new ProcessBuilder(
13574                                "/system/bin/timeout", "-k", "15s", "10s",
13575                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13576                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13577                                        .redirectErrorStream(true).start();
13578
13579                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13580                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13581                        input = new InputStreamReader(logcat.getInputStream());
13582
13583                        int num;
13584                        char[] buf = new char[8192];
13585                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13586                    } catch (IOException e) {
13587                        Slog.e(TAG, "Error running logcat", e);
13588                    } finally {
13589                        if (input != null) try { input.close(); } catch (IOException e) {}
13590                    }
13591                }
13592
13593                dbox.addText(dropboxTag, sb.toString());
13594            }
13595        };
13596
13597        if (process == null) {
13598            // If process is null, we are being called from some internal code
13599            // and may be about to die -- run this synchronously.
13600            worker.run();
13601        } else {
13602            worker.start();
13603        }
13604    }
13605
13606    @Override
13607    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13608        enforceNotIsolatedCaller("getProcessesInErrorState");
13609        // assume our apps are happy - lazy create the list
13610        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13611
13612        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13613                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13614        int userId = UserHandle.getUserId(Binder.getCallingUid());
13615
13616        synchronized (this) {
13617
13618            // iterate across all processes
13619            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13620                ProcessRecord app = mLruProcesses.get(i);
13621                if (!allUsers && app.userId != userId) {
13622                    continue;
13623                }
13624                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13625                    // This one's in trouble, so we'll generate a report for it
13626                    // crashes are higher priority (in case there's a crash *and* an anr)
13627                    ActivityManager.ProcessErrorStateInfo report = null;
13628                    if (app.crashing) {
13629                        report = app.crashingReport;
13630                    } else if (app.notResponding) {
13631                        report = app.notRespondingReport;
13632                    }
13633
13634                    if (report != null) {
13635                        if (errList == null) {
13636                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13637                        }
13638                        errList.add(report);
13639                    } else {
13640                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13641                                " crashing = " + app.crashing +
13642                                " notResponding = " + app.notResponding);
13643                    }
13644                }
13645            }
13646        }
13647
13648        return errList;
13649    }
13650
13651    static int procStateToImportance(int procState, int memAdj,
13652            ActivityManager.RunningAppProcessInfo currApp) {
13653        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13654        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13655            currApp.lru = memAdj;
13656        } else {
13657            currApp.lru = 0;
13658        }
13659        return imp;
13660    }
13661
13662    private void fillInProcMemInfo(ProcessRecord app,
13663            ActivityManager.RunningAppProcessInfo outInfo) {
13664        outInfo.pid = app.pid;
13665        outInfo.uid = app.info.uid;
13666        if (mHeavyWeightProcess == app) {
13667            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13668        }
13669        if (app.persistent) {
13670            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13671        }
13672        if (app.activities.size() > 0) {
13673            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13674        }
13675        outInfo.lastTrimLevel = app.trimMemoryLevel;
13676        int adj = app.curAdj;
13677        int procState = app.curProcState;
13678        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13679        outInfo.importanceReasonCode = app.adjTypeCode;
13680        outInfo.processState = app.curProcState;
13681    }
13682
13683    @Override
13684    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13685        enforceNotIsolatedCaller("getRunningAppProcesses");
13686
13687        final int callingUid = Binder.getCallingUid();
13688
13689        // Lazy instantiation of list
13690        List<ActivityManager.RunningAppProcessInfo> runList = null;
13691        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13692                callingUid) == PackageManager.PERMISSION_GRANTED;
13693        final int userId = UserHandle.getUserId(callingUid);
13694        final boolean allUids = isGetTasksAllowed(
13695                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13696
13697        synchronized (this) {
13698            // Iterate across all processes
13699            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13700                ProcessRecord app = mLruProcesses.get(i);
13701                if ((!allUsers && app.userId != userId)
13702                        || (!allUids && app.uid != callingUid)) {
13703                    continue;
13704                }
13705                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13706                    // Generate process state info for running application
13707                    ActivityManager.RunningAppProcessInfo currApp =
13708                        new ActivityManager.RunningAppProcessInfo(app.processName,
13709                                app.pid, app.getPackageList());
13710                    fillInProcMemInfo(app, currApp);
13711                    if (app.adjSource instanceof ProcessRecord) {
13712                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13713                        currApp.importanceReasonImportance =
13714                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13715                                        app.adjSourceProcState);
13716                    } else if (app.adjSource instanceof ActivityRecord) {
13717                        ActivityRecord r = (ActivityRecord)app.adjSource;
13718                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13719                    }
13720                    if (app.adjTarget instanceof ComponentName) {
13721                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13722                    }
13723                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13724                    //        + " lru=" + currApp.lru);
13725                    if (runList == null) {
13726                        runList = new ArrayList<>();
13727                    }
13728                    runList.add(currApp);
13729                }
13730            }
13731        }
13732        return runList;
13733    }
13734
13735    @Override
13736    public List<ApplicationInfo> getRunningExternalApplications() {
13737        enforceNotIsolatedCaller("getRunningExternalApplications");
13738        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13739        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13740        if (runningApps != null && runningApps.size() > 0) {
13741            Set<String> extList = new HashSet<String>();
13742            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13743                if (app.pkgList != null) {
13744                    for (String pkg : app.pkgList) {
13745                        extList.add(pkg);
13746                    }
13747                }
13748            }
13749            IPackageManager pm = AppGlobals.getPackageManager();
13750            for (String pkg : extList) {
13751                try {
13752                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13753                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13754                        retList.add(info);
13755                    }
13756                } catch (RemoteException e) {
13757                }
13758            }
13759        }
13760        return retList;
13761    }
13762
13763    @Override
13764    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13765        enforceNotIsolatedCaller("getMyMemoryState");
13766        synchronized (this) {
13767            ProcessRecord proc;
13768            synchronized (mPidsSelfLocked) {
13769                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13770            }
13771            fillInProcMemInfo(proc, outInfo);
13772        }
13773    }
13774
13775    @Override
13776    public int getMemoryTrimLevel() {
13777        enforceNotIsolatedCaller("getMyMemoryState");
13778        synchronized (this) {
13779            return mLastMemoryLevel;
13780        }
13781    }
13782
13783    @Override
13784    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13785            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13786        (new ActivityManagerShellCommand(this, false)).exec(
13787                this, in, out, err, args, resultReceiver);
13788    }
13789
13790    @Override
13791    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13792        if (checkCallingPermission(android.Manifest.permission.DUMP)
13793                != PackageManager.PERMISSION_GRANTED) {
13794            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13795                    + Binder.getCallingPid()
13796                    + ", uid=" + Binder.getCallingUid()
13797                    + " without permission "
13798                    + android.Manifest.permission.DUMP);
13799            return;
13800        }
13801
13802        boolean dumpAll = false;
13803        boolean dumpClient = false;
13804        boolean dumpCheckin = false;
13805        boolean dumpCheckinFormat = false;
13806        String dumpPackage = null;
13807
13808        int opti = 0;
13809        while (opti < args.length) {
13810            String opt = args[opti];
13811            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13812                break;
13813            }
13814            opti++;
13815            if ("-a".equals(opt)) {
13816                dumpAll = true;
13817            } else if ("-c".equals(opt)) {
13818                dumpClient = true;
13819            } else if ("-p".equals(opt)) {
13820                if (opti < args.length) {
13821                    dumpPackage = args[opti];
13822                    opti++;
13823                } else {
13824                    pw.println("Error: -p option requires package argument");
13825                    return;
13826                }
13827                dumpClient = true;
13828            } else if ("--checkin".equals(opt)) {
13829                dumpCheckin = dumpCheckinFormat = true;
13830            } else if ("-C".equals(opt)) {
13831                dumpCheckinFormat = true;
13832            } else if ("-h".equals(opt)) {
13833                ActivityManagerShellCommand.dumpHelp(pw, true);
13834                return;
13835            } else {
13836                pw.println("Unknown argument: " + opt + "; use -h for help");
13837            }
13838        }
13839
13840        long origId = Binder.clearCallingIdentity();
13841        boolean more = false;
13842        // Is the caller requesting to dump a particular piece of data?
13843        if (opti < args.length) {
13844            String cmd = args[opti];
13845            opti++;
13846            if ("activities".equals(cmd) || "a".equals(cmd)) {
13847                synchronized (this) {
13848                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13849                }
13850            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13851                synchronized (this) {
13852                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13853                }
13854            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13855                String[] newArgs;
13856                String name;
13857                if (opti >= args.length) {
13858                    name = null;
13859                    newArgs = EMPTY_STRING_ARRAY;
13860                } else {
13861                    dumpPackage = args[opti];
13862                    opti++;
13863                    newArgs = new String[args.length - opti];
13864                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13865                            args.length - opti);
13866                }
13867                synchronized (this) {
13868                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13869                }
13870            } else if ("broadcast-stats".equals(cmd)) {
13871                String[] newArgs;
13872                String name;
13873                if (opti >= args.length) {
13874                    name = null;
13875                    newArgs = EMPTY_STRING_ARRAY;
13876                } else {
13877                    dumpPackage = args[opti];
13878                    opti++;
13879                    newArgs = new String[args.length - opti];
13880                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13881                            args.length - opti);
13882                }
13883                synchronized (this) {
13884                    dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13885                }
13886            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13887                String[] newArgs;
13888                String name;
13889                if (opti >= args.length) {
13890                    name = null;
13891                    newArgs = EMPTY_STRING_ARRAY;
13892                } else {
13893                    dumpPackage = args[opti];
13894                    opti++;
13895                    newArgs = new String[args.length - opti];
13896                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13897                            args.length - opti);
13898                }
13899                synchronized (this) {
13900                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13901                }
13902            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13903                String[] newArgs;
13904                String name;
13905                if (opti >= args.length) {
13906                    name = null;
13907                    newArgs = EMPTY_STRING_ARRAY;
13908                } else {
13909                    dumpPackage = args[opti];
13910                    opti++;
13911                    newArgs = new String[args.length - opti];
13912                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13913                            args.length - opti);
13914                }
13915                synchronized (this) {
13916                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13917                }
13918            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13919                synchronized (this) {
13920                    dumpOomLocked(fd, pw, args, opti, true);
13921                }
13922            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13923                synchronized (this) {
13924                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13925                }
13926            } else if ("provider".equals(cmd)) {
13927                String[] newArgs;
13928                String name;
13929                if (opti >= args.length) {
13930                    name = null;
13931                    newArgs = EMPTY_STRING_ARRAY;
13932                } else {
13933                    name = args[opti];
13934                    opti++;
13935                    newArgs = new String[args.length - opti];
13936                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13937                }
13938                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13939                    pw.println("No providers match: " + name);
13940                    pw.println("Use -h for help.");
13941                }
13942            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13943                synchronized (this) {
13944                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13945                }
13946            } else if ("service".equals(cmd)) {
13947                String[] newArgs;
13948                String name;
13949                if (opti >= args.length) {
13950                    name = null;
13951                    newArgs = EMPTY_STRING_ARRAY;
13952                } else {
13953                    name = args[opti];
13954                    opti++;
13955                    newArgs = new String[args.length - opti];
13956                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13957                            args.length - opti);
13958                }
13959                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13960                    pw.println("No services match: " + name);
13961                    pw.println("Use -h for help.");
13962                }
13963            } else if ("package".equals(cmd)) {
13964                String[] newArgs;
13965                if (opti >= args.length) {
13966                    pw.println("package: no package name specified");
13967                    pw.println("Use -h for help.");
13968                } else {
13969                    dumpPackage = args[opti];
13970                    opti++;
13971                    newArgs = new String[args.length - opti];
13972                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13973                            args.length - opti);
13974                    args = newArgs;
13975                    opti = 0;
13976                    more = true;
13977                }
13978            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13979                synchronized (this) {
13980                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13981                }
13982            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13983                if (dumpClient) {
13984                    ActiveServices.ServiceDumper dumper;
13985                    synchronized (this) {
13986                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13987                                dumpPackage);
13988                    }
13989                    dumper.dumpWithClient();
13990                } else {
13991                    synchronized (this) {
13992                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13993                                dumpPackage).dumpLocked();
13994                    }
13995                }
13996            } else if ("locks".equals(cmd)) {
13997                LockGuard.dump(fd, pw, args);
13998            } else {
13999                // Dumping a single activity?
14000                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14001                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14002                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14003                    if (res < 0) {
14004                        pw.println("Bad activity command, or no activities match: " + cmd);
14005                        pw.println("Use -h for help.");
14006                    }
14007                }
14008            }
14009            if (!more) {
14010                Binder.restoreCallingIdentity(origId);
14011                return;
14012            }
14013        }
14014
14015        // No piece of data specified, dump everything.
14016        if (dumpCheckinFormat) {
14017            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14018        } else if (dumpClient) {
14019            ActiveServices.ServiceDumper sdumper;
14020            synchronized (this) {
14021                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14022                pw.println();
14023                if (dumpAll) {
14024                    pw.println("-------------------------------------------------------------------------------");
14025                }
14026                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14027                pw.println();
14028                if (dumpAll) {
14029                    pw.println("-------------------------------------------------------------------------------");
14030                }
14031                if (dumpAll || dumpPackage != null) {
14032                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14033                    pw.println();
14034                    if (dumpAll) {
14035                        pw.println("-------------------------------------------------------------------------------");
14036                    }
14037                }
14038                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14039                pw.println();
14040                if (dumpAll) {
14041                    pw.println("-------------------------------------------------------------------------------");
14042                }
14043                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14044                pw.println();
14045                if (dumpAll) {
14046                    pw.println("-------------------------------------------------------------------------------");
14047                }
14048                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14049                        dumpPackage);
14050            }
14051            sdumper.dumpWithClient();
14052            pw.println();
14053            synchronized (this) {
14054                if (dumpAll) {
14055                    pw.println("-------------------------------------------------------------------------------");
14056                }
14057                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14058                pw.println();
14059                if (dumpAll) {
14060                    pw.println("-------------------------------------------------------------------------------");
14061                }
14062                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14063                if (mAssociations.size() > 0) {
14064                    pw.println();
14065                    if (dumpAll) {
14066                        pw.println("-------------------------------------------------------------------------------");
14067                    }
14068                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14069                }
14070                pw.println();
14071                if (dumpAll) {
14072                    pw.println("-------------------------------------------------------------------------------");
14073                }
14074                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14075            }
14076
14077        } else {
14078            synchronized (this) {
14079                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14080                pw.println();
14081                if (dumpAll) {
14082                    pw.println("-------------------------------------------------------------------------------");
14083                }
14084                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14085                pw.println();
14086                if (dumpAll) {
14087                    pw.println("-------------------------------------------------------------------------------");
14088                }
14089                if (dumpAll || dumpPackage != null) {
14090                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14091                    pw.println();
14092                    if (dumpAll) {
14093                        pw.println("-------------------------------------------------------------------------------");
14094                    }
14095                }
14096                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14097                pw.println();
14098                if (dumpAll) {
14099                    pw.println("-------------------------------------------------------------------------------");
14100                }
14101                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14102                pw.println();
14103                if (dumpAll) {
14104                    pw.println("-------------------------------------------------------------------------------");
14105                }
14106                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14107                        .dumpLocked();
14108                pw.println();
14109                if (dumpAll) {
14110                    pw.println("-------------------------------------------------------------------------------");
14111                }
14112                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14113                pw.println();
14114                if (dumpAll) {
14115                    pw.println("-------------------------------------------------------------------------------");
14116                }
14117                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14118                if (mAssociations.size() > 0) {
14119                    pw.println();
14120                    if (dumpAll) {
14121                        pw.println("-------------------------------------------------------------------------------");
14122                    }
14123                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14124                }
14125                pw.println();
14126                if (dumpAll) {
14127                    pw.println("-------------------------------------------------------------------------------");
14128                }
14129                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14130            }
14131        }
14132        Binder.restoreCallingIdentity(origId);
14133    }
14134
14135    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14136            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14137        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14138
14139        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14140                dumpPackage);
14141        boolean needSep = printedAnything;
14142
14143        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14144                dumpPackage, needSep, "  mFocusedActivity: ");
14145        if (printed) {
14146            printedAnything = true;
14147            needSep = false;
14148        }
14149
14150        if (dumpPackage == null) {
14151            if (needSep) {
14152                pw.println();
14153            }
14154            needSep = true;
14155            printedAnything = true;
14156            mStackSupervisor.dump(pw, "  ");
14157        }
14158
14159        if (!printedAnything) {
14160            pw.println("  (nothing)");
14161        }
14162    }
14163
14164    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14165            int opti, boolean dumpAll, String dumpPackage) {
14166        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14167
14168        boolean printedAnything = false;
14169
14170        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14171            boolean printedHeader = false;
14172
14173            final int N = mRecentTasks.size();
14174            for (int i=0; i<N; i++) {
14175                TaskRecord tr = mRecentTasks.get(i);
14176                if (dumpPackage != null) {
14177                    if (tr.realActivity == null ||
14178                            !dumpPackage.equals(tr.realActivity)) {
14179                        continue;
14180                    }
14181                }
14182                if (!printedHeader) {
14183                    pw.println("  Recent tasks:");
14184                    printedHeader = true;
14185                    printedAnything = true;
14186                }
14187                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14188                        pw.println(tr);
14189                if (dumpAll) {
14190                    mRecentTasks.get(i).dump(pw, "    ");
14191                }
14192            }
14193        }
14194
14195        if (!printedAnything) {
14196            pw.println("  (nothing)");
14197        }
14198    }
14199
14200    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14201            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14202        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14203
14204        int dumpUid = 0;
14205        if (dumpPackage != null) {
14206            IPackageManager pm = AppGlobals.getPackageManager();
14207            try {
14208                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14209            } catch (RemoteException e) {
14210            }
14211        }
14212
14213        boolean printedAnything = false;
14214
14215        final long now = SystemClock.uptimeMillis();
14216
14217        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14218            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14219                    = mAssociations.valueAt(i1);
14220            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14221                SparseArray<ArrayMap<String, Association>> sourceUids
14222                        = targetComponents.valueAt(i2);
14223                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14224                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14225                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14226                        Association ass = sourceProcesses.valueAt(i4);
14227                        if (dumpPackage != null) {
14228                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14229                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14230                                continue;
14231                            }
14232                        }
14233                        printedAnything = true;
14234                        pw.print("  ");
14235                        pw.print(ass.mTargetProcess);
14236                        pw.print("/");
14237                        UserHandle.formatUid(pw, ass.mTargetUid);
14238                        pw.print(" <- ");
14239                        pw.print(ass.mSourceProcess);
14240                        pw.print("/");
14241                        UserHandle.formatUid(pw, ass.mSourceUid);
14242                        pw.println();
14243                        pw.print("    via ");
14244                        pw.print(ass.mTargetComponent.flattenToShortString());
14245                        pw.println();
14246                        pw.print("    ");
14247                        long dur = ass.mTime;
14248                        if (ass.mNesting > 0) {
14249                            dur += now - ass.mStartTime;
14250                        }
14251                        TimeUtils.formatDuration(dur, pw);
14252                        pw.print(" (");
14253                        pw.print(ass.mCount);
14254                        pw.print(" times)");
14255                        pw.print("  ");
14256                        for (int i=0; i<ass.mStateTimes.length; i++) {
14257                            long amt = ass.mStateTimes[i];
14258                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14259                                amt += now - ass.mLastStateUptime;
14260                            }
14261                            if (amt != 0) {
14262                                pw.print(" ");
14263                                pw.print(ProcessList.makeProcStateString(
14264                                            i + ActivityManager.MIN_PROCESS_STATE));
14265                                pw.print("=");
14266                                TimeUtils.formatDuration(amt, pw);
14267                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14268                                    pw.print("*");
14269                                }
14270                            }
14271                        }
14272                        pw.println();
14273                        if (ass.mNesting > 0) {
14274                            pw.print("    Currently active: ");
14275                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14276                            pw.println();
14277                        }
14278                    }
14279                }
14280            }
14281
14282        }
14283
14284        if (!printedAnything) {
14285            pw.println("  (nothing)");
14286        }
14287    }
14288
14289    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14290            String header, boolean needSep) {
14291        boolean printed = false;
14292        int whichAppId = -1;
14293        if (dumpPackage != null) {
14294            try {
14295                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14296                        dumpPackage, 0);
14297                whichAppId = UserHandle.getAppId(info.uid);
14298            } catch (NameNotFoundException e) {
14299                e.printStackTrace();
14300            }
14301        }
14302        for (int i=0; i<uids.size(); i++) {
14303            UidRecord uidRec = uids.valueAt(i);
14304            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14305                continue;
14306            }
14307            if (!printed) {
14308                printed = true;
14309                if (needSep) {
14310                    pw.println();
14311                }
14312                pw.print("  ");
14313                pw.println(header);
14314                needSep = true;
14315            }
14316            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14317            pw.print(": "); pw.println(uidRec);
14318        }
14319        return printed;
14320    }
14321
14322    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14323            int opti, boolean dumpAll, String dumpPackage) {
14324        boolean needSep = false;
14325        boolean printedAnything = false;
14326        int numPers = 0;
14327
14328        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14329
14330        if (dumpAll) {
14331            final int NP = mProcessNames.getMap().size();
14332            for (int ip=0; ip<NP; ip++) {
14333                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14334                final int NA = procs.size();
14335                for (int ia=0; ia<NA; ia++) {
14336                    ProcessRecord r = procs.valueAt(ia);
14337                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14338                        continue;
14339                    }
14340                    if (!needSep) {
14341                        pw.println("  All known processes:");
14342                        needSep = true;
14343                        printedAnything = true;
14344                    }
14345                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14346                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14347                        pw.print(" "); pw.println(r);
14348                    r.dump(pw, "    ");
14349                    if (r.persistent) {
14350                        numPers++;
14351                    }
14352                }
14353            }
14354        }
14355
14356        if (mIsolatedProcesses.size() > 0) {
14357            boolean printed = false;
14358            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14359                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14360                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14361                    continue;
14362                }
14363                if (!printed) {
14364                    if (needSep) {
14365                        pw.println();
14366                    }
14367                    pw.println("  Isolated process list (sorted by uid):");
14368                    printedAnything = true;
14369                    printed = true;
14370                    needSep = true;
14371                }
14372                pw.println(String.format("%sIsolated #%2d: %s",
14373                        "    ", i, r.toString()));
14374            }
14375        }
14376
14377        if (mActiveUids.size() > 0) {
14378            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14379                printedAnything = needSep = true;
14380            }
14381        }
14382        if (mValidateUids.size() > 0) {
14383            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14384                printedAnything = needSep = true;
14385            }
14386        }
14387
14388        if (mLruProcesses.size() > 0) {
14389            if (needSep) {
14390                pw.println();
14391            }
14392            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14393                    pw.print(" total, non-act at ");
14394                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14395                    pw.print(", non-svc at ");
14396                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14397                    pw.println("):");
14398            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14399            needSep = true;
14400            printedAnything = true;
14401        }
14402
14403        if (dumpAll || dumpPackage != null) {
14404            synchronized (mPidsSelfLocked) {
14405                boolean printed = false;
14406                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14407                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14408                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14409                        continue;
14410                    }
14411                    if (!printed) {
14412                        if (needSep) pw.println();
14413                        needSep = true;
14414                        pw.println("  PID mappings:");
14415                        printed = true;
14416                        printedAnything = true;
14417                    }
14418                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14419                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14420                }
14421            }
14422        }
14423
14424        if (mForegroundProcesses.size() > 0) {
14425            synchronized (mPidsSelfLocked) {
14426                boolean printed = false;
14427                for (int i=0; i<mForegroundProcesses.size(); i++) {
14428                    ProcessRecord r = mPidsSelfLocked.get(
14429                            mForegroundProcesses.valueAt(i).pid);
14430                    if (dumpPackage != null && (r == null
14431                            || !r.pkgList.containsKey(dumpPackage))) {
14432                        continue;
14433                    }
14434                    if (!printed) {
14435                        if (needSep) pw.println();
14436                        needSep = true;
14437                        pw.println("  Foreground Processes:");
14438                        printed = true;
14439                        printedAnything = true;
14440                    }
14441                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14442                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14443                }
14444            }
14445        }
14446
14447        if (mPersistentStartingProcesses.size() > 0) {
14448            if (needSep) pw.println();
14449            needSep = true;
14450            printedAnything = true;
14451            pw.println("  Persisent processes that are starting:");
14452            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14453                    "Starting Norm", "Restarting PERS", dumpPackage);
14454        }
14455
14456        if (mRemovedProcesses.size() > 0) {
14457            if (needSep) pw.println();
14458            needSep = true;
14459            printedAnything = true;
14460            pw.println("  Processes that are being removed:");
14461            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14462                    "Removed Norm", "Removed PERS", dumpPackage);
14463        }
14464
14465        if (mProcessesOnHold.size() > 0) {
14466            if (needSep) pw.println();
14467            needSep = true;
14468            printedAnything = true;
14469            pw.println("  Processes that are on old until the system is ready:");
14470            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14471                    "OnHold Norm", "OnHold PERS", dumpPackage);
14472        }
14473
14474        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14475
14476        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14477        if (needSep) {
14478            printedAnything = true;
14479        }
14480
14481        if (dumpPackage == null) {
14482            pw.println();
14483            needSep = false;
14484            mUserController.dump(pw, dumpAll);
14485        }
14486        if (mHomeProcess != null && (dumpPackage == null
14487                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14488            if (needSep) {
14489                pw.println();
14490                needSep = false;
14491            }
14492            pw.println("  mHomeProcess: " + mHomeProcess);
14493        }
14494        if (mPreviousProcess != null && (dumpPackage == null
14495                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14496            if (needSep) {
14497                pw.println();
14498                needSep = false;
14499            }
14500            pw.println("  mPreviousProcess: " + mPreviousProcess);
14501        }
14502        if (dumpAll) {
14503            StringBuilder sb = new StringBuilder(128);
14504            sb.append("  mPreviousProcessVisibleTime: ");
14505            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14506            pw.println(sb);
14507        }
14508        if (mHeavyWeightProcess != null && (dumpPackage == null
14509                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14510            if (needSep) {
14511                pw.println();
14512                needSep = false;
14513            }
14514            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14515        }
14516        if (dumpPackage == null) {
14517            pw.println("  mConfiguration: " + mConfiguration);
14518        }
14519        if (dumpAll) {
14520            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14521            if (mCompatModePackages.getPackages().size() > 0) {
14522                boolean printed = false;
14523                for (Map.Entry<String, Integer> entry
14524                        : mCompatModePackages.getPackages().entrySet()) {
14525                    String pkg = entry.getKey();
14526                    int mode = entry.getValue();
14527                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14528                        continue;
14529                    }
14530                    if (!printed) {
14531                        pw.println("  mScreenCompatPackages:");
14532                        printed = true;
14533                    }
14534                    pw.print("    "); pw.print(pkg); pw.print(": ");
14535                            pw.print(mode); pw.println();
14536                }
14537            }
14538        }
14539        if (dumpPackage == null) {
14540            pw.println("  mWakefulness="
14541                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14542            pw.println("  mSleepTokens=" + mSleepTokens);
14543            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14544                    + lockScreenShownToString());
14545            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14546            if (mRunningVoice != null) {
14547                pw.println("  mRunningVoice=" + mRunningVoice);
14548                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14549            }
14550        }
14551        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14552                || mOrigWaitForDebugger) {
14553            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14554                    || dumpPackage.equals(mOrigDebugApp)) {
14555                if (needSep) {
14556                    pw.println();
14557                    needSep = false;
14558                }
14559                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14560                        + " mDebugTransient=" + mDebugTransient
14561                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14562            }
14563        }
14564        if (mCurAppTimeTracker != null) {
14565            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14566        }
14567        if (mMemWatchProcesses.getMap().size() > 0) {
14568            pw.println("  Mem watch processes:");
14569            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14570                    = mMemWatchProcesses.getMap();
14571            for (int i=0; i<procs.size(); i++) {
14572                final String proc = procs.keyAt(i);
14573                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14574                for (int j=0; j<uids.size(); j++) {
14575                    if (needSep) {
14576                        pw.println();
14577                        needSep = false;
14578                    }
14579                    StringBuilder sb = new StringBuilder();
14580                    sb.append("    ").append(proc).append('/');
14581                    UserHandle.formatUid(sb, uids.keyAt(j));
14582                    Pair<Long, String> val = uids.valueAt(j);
14583                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14584                    if (val.second != null) {
14585                        sb.append(", report to ").append(val.second);
14586                    }
14587                    pw.println(sb.toString());
14588                }
14589            }
14590            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14591            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14592            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14593                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14594        }
14595        if (mTrackAllocationApp != null) {
14596            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14597                if (needSep) {
14598                    pw.println();
14599                    needSep = false;
14600                }
14601                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14602            }
14603        }
14604        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14605                || mProfileFd != null) {
14606            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14607                if (needSep) {
14608                    pw.println();
14609                    needSep = false;
14610                }
14611                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14612                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14613                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14614                        + mAutoStopProfiler);
14615                pw.println("  mProfileType=" + mProfileType);
14616            }
14617        }
14618        if (mNativeDebuggingApp != null) {
14619            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14620                if (needSep) {
14621                    pw.println();
14622                    needSep = false;
14623                }
14624                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14625            }
14626        }
14627        if (dumpPackage == null) {
14628            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14629                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14630                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14631            }
14632            if (mController != null) {
14633                pw.println("  mController=" + mController
14634                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14635            }
14636            if (dumpAll) {
14637                pw.println("  Total persistent processes: " + numPers);
14638                pw.println("  mProcessesReady=" + mProcessesReady
14639                        + " mSystemReady=" + mSystemReady
14640                        + " mBooted=" + mBooted
14641                        + " mFactoryTest=" + mFactoryTest);
14642                pw.println("  mBooting=" + mBooting
14643                        + " mCallFinishBooting=" + mCallFinishBooting
14644                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14645                pw.print("  mLastPowerCheckRealtime=");
14646                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14647                        pw.println("");
14648                pw.print("  mLastPowerCheckUptime=");
14649                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14650                        pw.println("");
14651                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14652                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14653                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14654                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14655                        + " (" + mLruProcesses.size() + " total)"
14656                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14657                        + " mNumServiceProcs=" + mNumServiceProcs
14658                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14659                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14660                        + " mLastMemoryLevel=" + mLastMemoryLevel
14661                        + " mLastNumProcesses=" + mLastNumProcesses);
14662                long now = SystemClock.uptimeMillis();
14663                pw.print("  mLastIdleTime=");
14664                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14665                        pw.print(" mLowRamSinceLastIdle=");
14666                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14667                        pw.println();
14668            }
14669        }
14670
14671        if (!printedAnything) {
14672            pw.println("  (nothing)");
14673        }
14674    }
14675
14676    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14677            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14678        if (mProcessesToGc.size() > 0) {
14679            boolean printed = false;
14680            long now = SystemClock.uptimeMillis();
14681            for (int i=0; i<mProcessesToGc.size(); i++) {
14682                ProcessRecord proc = mProcessesToGc.get(i);
14683                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14684                    continue;
14685                }
14686                if (!printed) {
14687                    if (needSep) pw.println();
14688                    needSep = true;
14689                    pw.println("  Processes that are waiting to GC:");
14690                    printed = true;
14691                }
14692                pw.print("    Process "); pw.println(proc);
14693                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14694                        pw.print(", last gced=");
14695                        pw.print(now-proc.lastRequestedGc);
14696                        pw.print(" ms ago, last lowMem=");
14697                        pw.print(now-proc.lastLowMemory);
14698                        pw.println(" ms ago");
14699
14700            }
14701        }
14702        return needSep;
14703    }
14704
14705    void printOomLevel(PrintWriter pw, String name, int adj) {
14706        pw.print("    ");
14707        if (adj >= 0) {
14708            pw.print(' ');
14709            if (adj < 10) pw.print(' ');
14710        } else {
14711            if (adj > -10) pw.print(' ');
14712        }
14713        pw.print(adj);
14714        pw.print(": ");
14715        pw.print(name);
14716        pw.print(" (");
14717        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14718        pw.println(")");
14719    }
14720
14721    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14722            int opti, boolean dumpAll) {
14723        boolean needSep = false;
14724
14725        if (mLruProcesses.size() > 0) {
14726            if (needSep) pw.println();
14727            needSep = true;
14728            pw.println("  OOM levels:");
14729            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14730            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14731            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14732            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14733            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14734            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14735            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14736            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14737            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14738            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14739            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14740            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14741            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14742            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14743
14744            if (needSep) pw.println();
14745            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14746                    pw.print(" total, non-act at ");
14747                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14748                    pw.print(", non-svc at ");
14749                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14750                    pw.println("):");
14751            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14752            needSep = true;
14753        }
14754
14755        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14756
14757        pw.println();
14758        pw.println("  mHomeProcess: " + mHomeProcess);
14759        pw.println("  mPreviousProcess: " + mPreviousProcess);
14760        if (mHeavyWeightProcess != null) {
14761            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14762        }
14763
14764        return true;
14765    }
14766
14767    /**
14768     * There are three ways to call this:
14769     *  - no provider specified: dump all the providers
14770     *  - a flattened component name that matched an existing provider was specified as the
14771     *    first arg: dump that one provider
14772     *  - the first arg isn't the flattened component name of an existing provider:
14773     *    dump all providers whose component contains the first arg as a substring
14774     */
14775    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14776            int opti, boolean dumpAll) {
14777        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14778    }
14779
14780    static class ItemMatcher {
14781        ArrayList<ComponentName> components;
14782        ArrayList<String> strings;
14783        ArrayList<Integer> objects;
14784        boolean all;
14785
14786        ItemMatcher() {
14787            all = true;
14788        }
14789
14790        void build(String name) {
14791            ComponentName componentName = ComponentName.unflattenFromString(name);
14792            if (componentName != null) {
14793                if (components == null) {
14794                    components = new ArrayList<ComponentName>();
14795                }
14796                components.add(componentName);
14797                all = false;
14798            } else {
14799                int objectId = 0;
14800                // Not a '/' separated full component name; maybe an object ID?
14801                try {
14802                    objectId = Integer.parseInt(name, 16);
14803                    if (objects == null) {
14804                        objects = new ArrayList<Integer>();
14805                    }
14806                    objects.add(objectId);
14807                    all = false;
14808                } catch (RuntimeException e) {
14809                    // Not an integer; just do string match.
14810                    if (strings == null) {
14811                        strings = new ArrayList<String>();
14812                    }
14813                    strings.add(name);
14814                    all = false;
14815                }
14816            }
14817        }
14818
14819        int build(String[] args, int opti) {
14820            for (; opti<args.length; opti++) {
14821                String name = args[opti];
14822                if ("--".equals(name)) {
14823                    return opti+1;
14824                }
14825                build(name);
14826            }
14827            return opti;
14828        }
14829
14830        boolean match(Object object, ComponentName comp) {
14831            if (all) {
14832                return true;
14833            }
14834            if (components != null) {
14835                for (int i=0; i<components.size(); i++) {
14836                    if (components.get(i).equals(comp)) {
14837                        return true;
14838                    }
14839                }
14840            }
14841            if (objects != null) {
14842                for (int i=0; i<objects.size(); i++) {
14843                    if (System.identityHashCode(object) == objects.get(i)) {
14844                        return true;
14845                    }
14846                }
14847            }
14848            if (strings != null) {
14849                String flat = comp.flattenToString();
14850                for (int i=0; i<strings.size(); i++) {
14851                    if (flat.contains(strings.get(i))) {
14852                        return true;
14853                    }
14854                }
14855            }
14856            return false;
14857        }
14858    }
14859
14860    /**
14861     * There are three things that cmd can be:
14862     *  - a flattened component name that matches an existing activity
14863     *  - the cmd arg isn't the flattened component name of an existing activity:
14864     *    dump all activity whose component contains the cmd as a substring
14865     *  - A hex number of the ActivityRecord object instance.
14866     */
14867    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14868            int opti, boolean dumpAll) {
14869        ArrayList<ActivityRecord> activities;
14870
14871        synchronized (this) {
14872            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14873        }
14874
14875        if (activities.size() <= 0) {
14876            return false;
14877        }
14878
14879        String[] newArgs = new String[args.length - opti];
14880        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14881
14882        TaskRecord lastTask = null;
14883        boolean needSep = false;
14884        for (int i=activities.size()-1; i>=0; i--) {
14885            ActivityRecord r = activities.get(i);
14886            if (needSep) {
14887                pw.println();
14888            }
14889            needSep = true;
14890            synchronized (this) {
14891                if (lastTask != r.task) {
14892                    lastTask = r.task;
14893                    pw.print("TASK "); pw.print(lastTask.affinity);
14894                            pw.print(" id="); pw.println(lastTask.taskId);
14895                    if (dumpAll) {
14896                        lastTask.dump(pw, "  ");
14897                    }
14898                }
14899            }
14900            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14901        }
14902        return true;
14903    }
14904
14905    /**
14906     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14907     * there is a thread associated with the activity.
14908     */
14909    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14910            final ActivityRecord r, String[] args, boolean dumpAll) {
14911        String innerPrefix = prefix + "  ";
14912        synchronized (this) {
14913            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14914                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14915                    pw.print(" pid=");
14916                    if (r.app != null) pw.println(r.app.pid);
14917                    else pw.println("(not running)");
14918            if (dumpAll) {
14919                r.dump(pw, innerPrefix);
14920            }
14921        }
14922        if (r.app != null && r.app.thread != null) {
14923            // flush anything that is already in the PrintWriter since the thread is going
14924            // to write to the file descriptor directly
14925            pw.flush();
14926            try {
14927                TransferPipe tp = new TransferPipe();
14928                try {
14929                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14930                            r.appToken, innerPrefix, args);
14931                    tp.go(fd);
14932                } finally {
14933                    tp.kill();
14934                }
14935            } catch (IOException e) {
14936                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14937            } catch (RemoteException e) {
14938                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14939            }
14940        }
14941    }
14942
14943    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14944            int opti, boolean dumpAll, String dumpPackage) {
14945        boolean needSep = false;
14946        boolean onlyHistory = false;
14947        boolean printedAnything = false;
14948
14949        if ("history".equals(dumpPackage)) {
14950            if (opti < args.length && "-s".equals(args[opti])) {
14951                dumpAll = false;
14952            }
14953            onlyHistory = true;
14954            dumpPackage = null;
14955        }
14956
14957        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14958        if (!onlyHistory && dumpAll) {
14959            if (mRegisteredReceivers.size() > 0) {
14960                boolean printed = false;
14961                Iterator it = mRegisteredReceivers.values().iterator();
14962                while (it.hasNext()) {
14963                    ReceiverList r = (ReceiverList)it.next();
14964                    if (dumpPackage != null && (r.app == null ||
14965                            !dumpPackage.equals(r.app.info.packageName))) {
14966                        continue;
14967                    }
14968                    if (!printed) {
14969                        pw.println("  Registered Receivers:");
14970                        needSep = true;
14971                        printed = true;
14972                        printedAnything = true;
14973                    }
14974                    pw.print("  * "); pw.println(r);
14975                    r.dump(pw, "    ");
14976                }
14977            }
14978
14979            if (mReceiverResolver.dump(pw, needSep ?
14980                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14981                    "    ", dumpPackage, false, false)) {
14982                needSep = true;
14983                printedAnything = true;
14984            }
14985        }
14986
14987        for (BroadcastQueue q : mBroadcastQueues) {
14988            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14989            printedAnything |= needSep;
14990        }
14991
14992        needSep = true;
14993
14994        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14995            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14996                if (needSep) {
14997                    pw.println();
14998                }
14999                needSep = true;
15000                printedAnything = true;
15001                pw.print("  Sticky broadcasts for user ");
15002                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15003                StringBuilder sb = new StringBuilder(128);
15004                for (Map.Entry<String, ArrayList<Intent>> ent
15005                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15006                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15007                    if (dumpAll) {
15008                        pw.println(":");
15009                        ArrayList<Intent> intents = ent.getValue();
15010                        final int N = intents.size();
15011                        for (int i=0; i<N; i++) {
15012                            sb.setLength(0);
15013                            sb.append("    Intent: ");
15014                            intents.get(i).toShortString(sb, false, true, false, false);
15015                            pw.println(sb.toString());
15016                            Bundle bundle = intents.get(i).getExtras();
15017                            if (bundle != null) {
15018                                pw.print("      ");
15019                                pw.println(bundle.toString());
15020                            }
15021                        }
15022                    } else {
15023                        pw.println("");
15024                    }
15025                }
15026            }
15027        }
15028
15029        if (!onlyHistory && dumpAll) {
15030            pw.println();
15031            for (BroadcastQueue queue : mBroadcastQueues) {
15032                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15033                        + queue.mBroadcastsScheduled);
15034            }
15035            pw.println("  mHandler:");
15036            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15037            needSep = true;
15038            printedAnything = true;
15039        }
15040
15041        if (!printedAnything) {
15042            pw.println("  (nothing)");
15043        }
15044    }
15045
15046    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15047            int opti, boolean dumpAll, String dumpPackage) {
15048        if (mCurBroadcastStats == null) {
15049            return;
15050        }
15051
15052        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15053        final long now = SystemClock.elapsedRealtime();
15054        if (mLastBroadcastStats != null) {
15055            pw.print("  Last stats (from ");
15056            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15057            pw.print(" to ");
15058            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15059            pw.print(", ");
15060            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15061                    - mLastBroadcastStats.mStartUptime, pw);
15062            pw.println(" uptime):");
15063            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15064                pw.println("    (nothing)");
15065            }
15066            pw.println();
15067        }
15068        pw.print("  Current stats (from ");
15069        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15070        pw.print(" to now, ");
15071        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15072                - mCurBroadcastStats.mStartUptime, pw);
15073        pw.println(" uptime):");
15074        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15075            pw.println("    (nothing)");
15076        }
15077    }
15078
15079    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15080            int opti, boolean fullCheckin, String dumpPackage) {
15081        if (mCurBroadcastStats == null) {
15082            return;
15083        }
15084
15085        if (mLastBroadcastStats != null) {
15086            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15087            if (fullCheckin) {
15088                mLastBroadcastStats = null;
15089                return;
15090            }
15091        }
15092        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15093        if (fullCheckin) {
15094            mCurBroadcastStats = null;
15095        }
15096    }
15097
15098    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15099            int opti, boolean dumpAll, String dumpPackage) {
15100        boolean needSep;
15101        boolean printedAnything = false;
15102
15103        ItemMatcher matcher = new ItemMatcher();
15104        matcher.build(args, opti);
15105
15106        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15107
15108        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15109        printedAnything |= needSep;
15110
15111        if (mLaunchingProviders.size() > 0) {
15112            boolean printed = false;
15113            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15114                ContentProviderRecord r = mLaunchingProviders.get(i);
15115                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15116                    continue;
15117                }
15118                if (!printed) {
15119                    if (needSep) pw.println();
15120                    needSep = true;
15121                    pw.println("  Launching content providers:");
15122                    printed = true;
15123                    printedAnything = true;
15124                }
15125                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15126                        pw.println(r);
15127            }
15128        }
15129
15130        if (!printedAnything) {
15131            pw.println("  (nothing)");
15132        }
15133    }
15134
15135    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15136            int opti, boolean dumpAll, String dumpPackage) {
15137        boolean needSep = false;
15138        boolean printedAnything = false;
15139
15140        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15141
15142        if (mGrantedUriPermissions.size() > 0) {
15143            boolean printed = false;
15144            int dumpUid = -2;
15145            if (dumpPackage != null) {
15146                try {
15147                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15148                            MATCH_UNINSTALLED_PACKAGES, 0);
15149                } catch (NameNotFoundException e) {
15150                    dumpUid = -1;
15151                }
15152            }
15153            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15154                int uid = mGrantedUriPermissions.keyAt(i);
15155                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15156                    continue;
15157                }
15158                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15159                if (!printed) {
15160                    if (needSep) pw.println();
15161                    needSep = true;
15162                    pw.println("  Granted Uri Permissions:");
15163                    printed = true;
15164                    printedAnything = true;
15165                }
15166                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15167                for (UriPermission perm : perms.values()) {
15168                    pw.print("    "); pw.println(perm);
15169                    if (dumpAll) {
15170                        perm.dump(pw, "      ");
15171                    }
15172                }
15173            }
15174        }
15175
15176        if (!printedAnything) {
15177            pw.println("  (nothing)");
15178        }
15179    }
15180
15181    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15182            int opti, boolean dumpAll, String dumpPackage) {
15183        boolean printed = false;
15184
15185        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15186
15187        if (mIntentSenderRecords.size() > 0) {
15188            Iterator<WeakReference<PendingIntentRecord>> it
15189                    = mIntentSenderRecords.values().iterator();
15190            while (it.hasNext()) {
15191                WeakReference<PendingIntentRecord> ref = it.next();
15192                PendingIntentRecord rec = ref != null ? ref.get(): null;
15193                if (dumpPackage != null && (rec == null
15194                        || !dumpPackage.equals(rec.key.packageName))) {
15195                    continue;
15196                }
15197                printed = true;
15198                if (rec != null) {
15199                    pw.print("  * "); pw.println(rec);
15200                    if (dumpAll) {
15201                        rec.dump(pw, "    ");
15202                    }
15203                } else {
15204                    pw.print("  * "); pw.println(ref);
15205                }
15206            }
15207        }
15208
15209        if (!printed) {
15210            pw.println("  (nothing)");
15211        }
15212    }
15213
15214    private static final int dumpProcessList(PrintWriter pw,
15215            ActivityManagerService service, List list,
15216            String prefix, String normalLabel, String persistentLabel,
15217            String dumpPackage) {
15218        int numPers = 0;
15219        final int N = list.size()-1;
15220        for (int i=N; i>=0; i--) {
15221            ProcessRecord r = (ProcessRecord)list.get(i);
15222            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15223                continue;
15224            }
15225            pw.println(String.format("%s%s #%2d: %s",
15226                    prefix, (r.persistent ? persistentLabel : normalLabel),
15227                    i, r.toString()));
15228            if (r.persistent) {
15229                numPers++;
15230            }
15231        }
15232        return numPers;
15233    }
15234
15235    private static final boolean dumpProcessOomList(PrintWriter pw,
15236            ActivityManagerService service, List<ProcessRecord> origList,
15237            String prefix, String normalLabel, String persistentLabel,
15238            boolean inclDetails, String dumpPackage) {
15239
15240        ArrayList<Pair<ProcessRecord, Integer>> list
15241                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15242        for (int i=0; i<origList.size(); i++) {
15243            ProcessRecord r = origList.get(i);
15244            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15245                continue;
15246            }
15247            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15248        }
15249
15250        if (list.size() <= 0) {
15251            return false;
15252        }
15253
15254        Comparator<Pair<ProcessRecord, Integer>> comparator
15255                = new Comparator<Pair<ProcessRecord, Integer>>() {
15256            @Override
15257            public int compare(Pair<ProcessRecord, Integer> object1,
15258                    Pair<ProcessRecord, Integer> object2) {
15259                if (object1.first.setAdj != object2.first.setAdj) {
15260                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15261                }
15262                if (object1.first.setProcState != object2.first.setProcState) {
15263                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15264                }
15265                if (object1.second.intValue() != object2.second.intValue()) {
15266                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15267                }
15268                return 0;
15269            }
15270        };
15271
15272        Collections.sort(list, comparator);
15273
15274        final long curRealtime = SystemClock.elapsedRealtime();
15275        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15276        final long curUptime = SystemClock.uptimeMillis();
15277        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15278
15279        for (int i=list.size()-1; i>=0; i--) {
15280            ProcessRecord r = list.get(i).first;
15281            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15282            char schedGroup;
15283            switch (r.setSchedGroup) {
15284                case ProcessList.SCHED_GROUP_BACKGROUND:
15285                    schedGroup = 'B';
15286                    break;
15287                case ProcessList.SCHED_GROUP_DEFAULT:
15288                    schedGroup = 'F';
15289                    break;
15290                case ProcessList.SCHED_GROUP_TOP_APP:
15291                    schedGroup = 'T';
15292                    break;
15293                default:
15294                    schedGroup = '?';
15295                    break;
15296            }
15297            char foreground;
15298            if (r.foregroundActivities) {
15299                foreground = 'A';
15300            } else if (r.foregroundServices) {
15301                foreground = 'S';
15302            } else {
15303                foreground = ' ';
15304            }
15305            String procState = ProcessList.makeProcStateString(r.curProcState);
15306            pw.print(prefix);
15307            pw.print(r.persistent ? persistentLabel : normalLabel);
15308            pw.print(" #");
15309            int num = (origList.size()-1)-list.get(i).second;
15310            if (num < 10) pw.print(' ');
15311            pw.print(num);
15312            pw.print(": ");
15313            pw.print(oomAdj);
15314            pw.print(' ');
15315            pw.print(schedGroup);
15316            pw.print('/');
15317            pw.print(foreground);
15318            pw.print('/');
15319            pw.print(procState);
15320            pw.print(" trm:");
15321            if (r.trimMemoryLevel < 10) pw.print(' ');
15322            pw.print(r.trimMemoryLevel);
15323            pw.print(' ');
15324            pw.print(r.toShortString());
15325            pw.print(" (");
15326            pw.print(r.adjType);
15327            pw.println(')');
15328            if (r.adjSource != null || r.adjTarget != null) {
15329                pw.print(prefix);
15330                pw.print("    ");
15331                if (r.adjTarget instanceof ComponentName) {
15332                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15333                } else if (r.adjTarget != null) {
15334                    pw.print(r.adjTarget.toString());
15335                } else {
15336                    pw.print("{null}");
15337                }
15338                pw.print("<=");
15339                if (r.adjSource instanceof ProcessRecord) {
15340                    pw.print("Proc{");
15341                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15342                    pw.println("}");
15343                } else if (r.adjSource != null) {
15344                    pw.println(r.adjSource.toString());
15345                } else {
15346                    pw.println("{null}");
15347                }
15348            }
15349            if (inclDetails) {
15350                pw.print(prefix);
15351                pw.print("    ");
15352                pw.print("oom: max="); pw.print(r.maxAdj);
15353                pw.print(" curRaw="); pw.print(r.curRawAdj);
15354                pw.print(" setRaw="); pw.print(r.setRawAdj);
15355                pw.print(" cur="); pw.print(r.curAdj);
15356                pw.print(" set="); pw.println(r.setAdj);
15357                pw.print(prefix);
15358                pw.print("    ");
15359                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15360                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15361                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15362                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15363                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15364                pw.println();
15365                pw.print(prefix);
15366                pw.print("    ");
15367                pw.print("cached="); pw.print(r.cached);
15368                pw.print(" empty="); pw.print(r.empty);
15369                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15370
15371                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15372                    if (r.lastWakeTime != 0) {
15373                        long wtime;
15374                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15375                        synchronized (stats) {
15376                            wtime = stats.getProcessWakeTime(r.info.uid,
15377                                    r.pid, curRealtime);
15378                        }
15379                        long timeUsed = wtime - r.lastWakeTime;
15380                        pw.print(prefix);
15381                        pw.print("    ");
15382                        pw.print("keep awake over ");
15383                        TimeUtils.formatDuration(realtimeSince, pw);
15384                        pw.print(" used ");
15385                        TimeUtils.formatDuration(timeUsed, pw);
15386                        pw.print(" (");
15387                        pw.print((timeUsed*100)/realtimeSince);
15388                        pw.println("%)");
15389                    }
15390                    if (r.lastCpuTime != 0) {
15391                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15392                        pw.print(prefix);
15393                        pw.print("    ");
15394                        pw.print("run cpu over ");
15395                        TimeUtils.formatDuration(uptimeSince, pw);
15396                        pw.print(" used ");
15397                        TimeUtils.formatDuration(timeUsed, pw);
15398                        pw.print(" (");
15399                        pw.print((timeUsed*100)/uptimeSince);
15400                        pw.println("%)");
15401                    }
15402                }
15403            }
15404        }
15405        return true;
15406    }
15407
15408    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15409            String[] args) {
15410        ArrayList<ProcessRecord> procs;
15411        synchronized (this) {
15412            if (args != null && args.length > start
15413                    && args[start].charAt(0) != '-') {
15414                procs = new ArrayList<ProcessRecord>();
15415                int pid = -1;
15416                try {
15417                    pid = Integer.parseInt(args[start]);
15418                } catch (NumberFormatException e) {
15419                }
15420                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15421                    ProcessRecord proc = mLruProcesses.get(i);
15422                    if (proc.pid == pid) {
15423                        procs.add(proc);
15424                    } else if (allPkgs && proc.pkgList != null
15425                            && proc.pkgList.containsKey(args[start])) {
15426                        procs.add(proc);
15427                    } else if (proc.processName.equals(args[start])) {
15428                        procs.add(proc);
15429                    }
15430                }
15431                if (procs.size() <= 0) {
15432                    return null;
15433                }
15434            } else {
15435                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15436            }
15437        }
15438        return procs;
15439    }
15440
15441    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15442            PrintWriter pw, String[] args) {
15443        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15444        if (procs == null) {
15445            pw.println("No process found for: " + args[0]);
15446            return;
15447        }
15448
15449        long uptime = SystemClock.uptimeMillis();
15450        long realtime = SystemClock.elapsedRealtime();
15451        pw.println("Applications Graphics Acceleration Info:");
15452        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15453
15454        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15455            ProcessRecord r = procs.get(i);
15456            if (r.thread != null) {
15457                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15458                pw.flush();
15459                try {
15460                    TransferPipe tp = new TransferPipe();
15461                    try {
15462                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15463                        tp.go(fd);
15464                    } finally {
15465                        tp.kill();
15466                    }
15467                } catch (IOException e) {
15468                    pw.println("Failure while dumping the app: " + r);
15469                    pw.flush();
15470                } catch (RemoteException e) {
15471                    pw.println("Got a RemoteException while dumping the app " + r);
15472                    pw.flush();
15473                }
15474            }
15475        }
15476    }
15477
15478    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15479        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15480        if (procs == null) {
15481            pw.println("No process found for: " + args[0]);
15482            return;
15483        }
15484
15485        pw.println("Applications Database Info:");
15486
15487        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15488            ProcessRecord r = procs.get(i);
15489            if (r.thread != null) {
15490                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15491                pw.flush();
15492                try {
15493                    TransferPipe tp = new TransferPipe();
15494                    try {
15495                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15496                        tp.go(fd);
15497                    } finally {
15498                        tp.kill();
15499                    }
15500                } catch (IOException e) {
15501                    pw.println("Failure while dumping the app: " + r);
15502                    pw.flush();
15503                } catch (RemoteException e) {
15504                    pw.println("Got a RemoteException while dumping the app " + r);
15505                    pw.flush();
15506                }
15507            }
15508        }
15509    }
15510
15511    final static class MemItem {
15512        final boolean isProc;
15513        final String label;
15514        final String shortLabel;
15515        final long pss;
15516        final long swapPss;
15517        final int id;
15518        final boolean hasActivities;
15519        ArrayList<MemItem> subitems;
15520
15521        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15522                boolean _hasActivities) {
15523            isProc = true;
15524            label = _label;
15525            shortLabel = _shortLabel;
15526            pss = _pss;
15527            swapPss = _swapPss;
15528            id = _id;
15529            hasActivities = _hasActivities;
15530        }
15531
15532        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15533            isProc = false;
15534            label = _label;
15535            shortLabel = _shortLabel;
15536            pss = _pss;
15537            swapPss = _swapPss;
15538            id = _id;
15539            hasActivities = false;
15540        }
15541    }
15542
15543    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15544            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15545        if (sort && !isCompact) {
15546            Collections.sort(items, new Comparator<MemItem>() {
15547                @Override
15548                public int compare(MemItem lhs, MemItem rhs) {
15549                    if (lhs.pss < rhs.pss) {
15550                        return 1;
15551                    } else if (lhs.pss > rhs.pss) {
15552                        return -1;
15553                    }
15554                    return 0;
15555                }
15556            });
15557        }
15558
15559        for (int i=0; i<items.size(); i++) {
15560            MemItem mi = items.get(i);
15561            if (!isCompact) {
15562                if (dumpSwapPss) {
15563                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15564                            mi.label, stringifyKBSize(mi.swapPss));
15565                } else {
15566                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15567                }
15568            } else if (mi.isProc) {
15569                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15570                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15571                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15572                pw.println(mi.hasActivities ? ",a" : ",e");
15573            } else {
15574                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15575                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15576            }
15577            if (mi.subitems != null) {
15578                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15579                        true, isCompact, dumpSwapPss);
15580            }
15581        }
15582    }
15583
15584    // These are in KB.
15585    static final long[] DUMP_MEM_BUCKETS = new long[] {
15586        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15587        120*1024, 160*1024, 200*1024,
15588        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15589        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15590    };
15591
15592    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15593            boolean stackLike) {
15594        int start = label.lastIndexOf('.');
15595        if (start >= 0) start++;
15596        else start = 0;
15597        int end = label.length();
15598        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15599            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15600                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15601                out.append(bucket);
15602                out.append(stackLike ? "MB." : "MB ");
15603                out.append(label, start, end);
15604                return;
15605            }
15606        }
15607        out.append(memKB/1024);
15608        out.append(stackLike ? "MB." : "MB ");
15609        out.append(label, start, end);
15610    }
15611
15612    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15613            ProcessList.NATIVE_ADJ,
15614            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15615            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15616            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15617            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15618            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15619            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15620    };
15621    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15622            "Native",
15623            "System", "Persistent", "Persistent Service", "Foreground",
15624            "Visible", "Perceptible",
15625            "Heavy Weight", "Backup",
15626            "A Services", "Home",
15627            "Previous", "B Services", "Cached"
15628    };
15629    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15630            "native",
15631            "sys", "pers", "persvc", "fore",
15632            "vis", "percept",
15633            "heavy", "backup",
15634            "servicea", "home",
15635            "prev", "serviceb", "cached"
15636    };
15637
15638    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15639            long realtime, boolean isCheckinRequest, boolean isCompact) {
15640        if (isCompact) {
15641            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15642        }
15643        if (isCheckinRequest || isCompact) {
15644            // short checkin version
15645            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15646        } else {
15647            pw.println("Applications Memory Usage (in Kilobytes):");
15648            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15649        }
15650    }
15651
15652    private static final int KSM_SHARED = 0;
15653    private static final int KSM_SHARING = 1;
15654    private static final int KSM_UNSHARED = 2;
15655    private static final int KSM_VOLATILE = 3;
15656
15657    private final long[] getKsmInfo() {
15658        long[] longOut = new long[4];
15659        final int[] SINGLE_LONG_FORMAT = new int[] {
15660            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15661        };
15662        long[] longTmp = new long[1];
15663        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15664                SINGLE_LONG_FORMAT, null, longTmp, null);
15665        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15666        longTmp[0] = 0;
15667        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15668                SINGLE_LONG_FORMAT, null, longTmp, null);
15669        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15670        longTmp[0] = 0;
15671        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15672                SINGLE_LONG_FORMAT, null, longTmp, null);
15673        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15674        longTmp[0] = 0;
15675        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15676                SINGLE_LONG_FORMAT, null, longTmp, null);
15677        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15678        return longOut;
15679    }
15680
15681    private static String stringifySize(long size, int order) {
15682        Locale locale = Locale.US;
15683        switch (order) {
15684            case 1:
15685                return String.format(locale, "%,13d", size);
15686            case 1024:
15687                return String.format(locale, "%,9dK", size / 1024);
15688            case 1024 * 1024:
15689                return String.format(locale, "%,5dM", size / 1024 / 1024);
15690            case 1024 * 1024 * 1024:
15691                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15692            default:
15693                throw new IllegalArgumentException("Invalid size order");
15694        }
15695    }
15696
15697    private static String stringifyKBSize(long size) {
15698        return stringifySize(size * 1024, 1024);
15699    }
15700
15701    // Update this version number in case you change the 'compact' format
15702    private static final int MEMINFO_COMPACT_VERSION = 1;
15703
15704    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15705            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15706        boolean dumpDetails = false;
15707        boolean dumpFullDetails = false;
15708        boolean dumpDalvik = false;
15709        boolean dumpSummaryOnly = false;
15710        boolean dumpUnreachable = false;
15711        boolean oomOnly = false;
15712        boolean isCompact = false;
15713        boolean localOnly = false;
15714        boolean packages = false;
15715        boolean isCheckinRequest = false;
15716        boolean dumpSwapPss = false;
15717
15718        int opti = 0;
15719        while (opti < args.length) {
15720            String opt = args[opti];
15721            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15722                break;
15723            }
15724            opti++;
15725            if ("-a".equals(opt)) {
15726                dumpDetails = true;
15727                dumpFullDetails = true;
15728                dumpDalvik = true;
15729                dumpSwapPss = true;
15730            } else if ("-d".equals(opt)) {
15731                dumpDalvik = true;
15732            } else if ("-c".equals(opt)) {
15733                isCompact = true;
15734            } else if ("-s".equals(opt)) {
15735                dumpDetails = true;
15736                dumpSummaryOnly = true;
15737            } else if ("-S".equals(opt)) {
15738                dumpSwapPss = true;
15739            } else if ("--unreachable".equals(opt)) {
15740                dumpUnreachable = true;
15741            } else if ("--oom".equals(opt)) {
15742                oomOnly = true;
15743            } else if ("--local".equals(opt)) {
15744                localOnly = true;
15745            } else if ("--package".equals(opt)) {
15746                packages = true;
15747            } else if ("--checkin".equals(opt)) {
15748                isCheckinRequest = true;
15749
15750            } else if ("-h".equals(opt)) {
15751                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15752                pw.println("  -a: include all available information for each process.");
15753                pw.println("  -d: include dalvik details.");
15754                pw.println("  -c: dump in a compact machine-parseable representation.");
15755                pw.println("  -s: dump only summary of application memory usage.");
15756                pw.println("  -S: dump also SwapPss.");
15757                pw.println("  --oom: only show processes organized by oom adj.");
15758                pw.println("  --local: only collect details locally, don't call process.");
15759                pw.println("  --package: interpret process arg as package, dumping all");
15760                pw.println("             processes that have loaded that package.");
15761                pw.println("  --checkin: dump data for a checkin");
15762                pw.println("If [process] is specified it can be the name or ");
15763                pw.println("pid of a specific process to dump.");
15764                return;
15765            } else {
15766                pw.println("Unknown argument: " + opt + "; use -h for help");
15767            }
15768        }
15769
15770        long uptime = SystemClock.uptimeMillis();
15771        long realtime = SystemClock.elapsedRealtime();
15772        final long[] tmpLong = new long[1];
15773
15774        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15775        if (procs == null) {
15776            // No Java processes.  Maybe they want to print a native process.
15777            if (args != null && args.length > opti
15778                    && args[opti].charAt(0) != '-') {
15779                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15780                        = new ArrayList<ProcessCpuTracker.Stats>();
15781                updateCpuStatsNow();
15782                int findPid = -1;
15783                try {
15784                    findPid = Integer.parseInt(args[opti]);
15785                } catch (NumberFormatException e) {
15786                }
15787                synchronized (mProcessCpuTracker) {
15788                    final int N = mProcessCpuTracker.countStats();
15789                    for (int i=0; i<N; i++) {
15790                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15791                        if (st.pid == findPid || (st.baseName != null
15792                                && st.baseName.equals(args[opti]))) {
15793                            nativeProcs.add(st);
15794                        }
15795                    }
15796                }
15797                if (nativeProcs.size() > 0) {
15798                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15799                            isCompact);
15800                    Debug.MemoryInfo mi = null;
15801                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15802                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15803                        final int pid = r.pid;
15804                        if (!isCheckinRequest && dumpDetails) {
15805                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15806                        }
15807                        if (mi == null) {
15808                            mi = new Debug.MemoryInfo();
15809                        }
15810                        if (dumpDetails || (!brief && !oomOnly)) {
15811                            Debug.getMemoryInfo(pid, mi);
15812                        } else {
15813                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15814                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15815                        }
15816                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15817                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15818                        if (isCheckinRequest) {
15819                            pw.println();
15820                        }
15821                    }
15822                    return;
15823                }
15824            }
15825            pw.println("No process found for: " + args[opti]);
15826            return;
15827        }
15828
15829        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15830            dumpDetails = true;
15831        }
15832
15833        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15834
15835        String[] innerArgs = new String[args.length-opti];
15836        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15837
15838        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15839        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15840        long nativePss = 0;
15841        long nativeSwapPss = 0;
15842        long dalvikPss = 0;
15843        long dalvikSwapPss = 0;
15844        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15845                EmptyArray.LONG;
15846        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15847                EmptyArray.LONG;
15848        long otherPss = 0;
15849        long otherSwapPss = 0;
15850        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15851        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15852
15853        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15854        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15855        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15856                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15857
15858        long totalPss = 0;
15859        long totalSwapPss = 0;
15860        long cachedPss = 0;
15861        long cachedSwapPss = 0;
15862        boolean hasSwapPss = false;
15863
15864        Debug.MemoryInfo mi = null;
15865        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15866            final ProcessRecord r = procs.get(i);
15867            final IApplicationThread thread;
15868            final int pid;
15869            final int oomAdj;
15870            final boolean hasActivities;
15871            synchronized (this) {
15872                thread = r.thread;
15873                pid = r.pid;
15874                oomAdj = r.getSetAdjWithServices();
15875                hasActivities = r.activities.size() > 0;
15876            }
15877            if (thread != null) {
15878                if (!isCheckinRequest && dumpDetails) {
15879                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15880                }
15881                if (mi == null) {
15882                    mi = new Debug.MemoryInfo();
15883                }
15884                if (dumpDetails || (!brief && !oomOnly)) {
15885                    Debug.getMemoryInfo(pid, mi);
15886                    hasSwapPss = mi.hasSwappedOutPss;
15887                } else {
15888                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15889                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15890                }
15891                if (dumpDetails) {
15892                    if (localOnly) {
15893                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15894                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15895                        if (isCheckinRequest) {
15896                            pw.println();
15897                        }
15898                    } else {
15899                        try {
15900                            pw.flush();
15901                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15902                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15903                        } catch (RemoteException e) {
15904                            if (!isCheckinRequest) {
15905                                pw.println("Got RemoteException!");
15906                                pw.flush();
15907                            }
15908                        }
15909                    }
15910                }
15911
15912                final long myTotalPss = mi.getTotalPss();
15913                final long myTotalUss = mi.getTotalUss();
15914                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15915
15916                synchronized (this) {
15917                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15918                        // Record this for posterity if the process has been stable.
15919                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15920                    }
15921                }
15922
15923                if (!isCheckinRequest && mi != null) {
15924                    totalPss += myTotalPss;
15925                    totalSwapPss += myTotalSwapPss;
15926                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15927                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15928                            myTotalSwapPss, pid, hasActivities);
15929                    procMems.add(pssItem);
15930                    procMemsMap.put(pid, pssItem);
15931
15932                    nativePss += mi.nativePss;
15933                    nativeSwapPss += mi.nativeSwappedOutPss;
15934                    dalvikPss += mi.dalvikPss;
15935                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15936                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15937                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15938                        dalvikSubitemSwapPss[j] +=
15939                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15940                    }
15941                    otherPss += mi.otherPss;
15942                    otherSwapPss += mi.otherSwappedOutPss;
15943                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15944                        long mem = mi.getOtherPss(j);
15945                        miscPss[j] += mem;
15946                        otherPss -= mem;
15947                        mem = mi.getOtherSwappedOutPss(j);
15948                        miscSwapPss[j] += mem;
15949                        otherSwapPss -= mem;
15950                    }
15951
15952                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15953                        cachedPss += myTotalPss;
15954                        cachedSwapPss += myTotalSwapPss;
15955                    }
15956
15957                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15958                        if (oomIndex == (oomPss.length - 1)
15959                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15960                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15961                            oomPss[oomIndex] += myTotalPss;
15962                            oomSwapPss[oomIndex] += myTotalSwapPss;
15963                            if (oomProcs[oomIndex] == null) {
15964                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15965                            }
15966                            oomProcs[oomIndex].add(pssItem);
15967                            break;
15968                        }
15969                    }
15970                }
15971            }
15972        }
15973
15974        long nativeProcTotalPss = 0;
15975
15976        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15977            // If we are showing aggregations, also look for native processes to
15978            // include so that our aggregations are more accurate.
15979            updateCpuStatsNow();
15980            mi = null;
15981            synchronized (mProcessCpuTracker) {
15982                final int N = mProcessCpuTracker.countStats();
15983                for (int i=0; i<N; i++) {
15984                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15985                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15986                        if (mi == null) {
15987                            mi = new Debug.MemoryInfo();
15988                        }
15989                        if (!brief && !oomOnly) {
15990                            Debug.getMemoryInfo(st.pid, mi);
15991                        } else {
15992                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15993                            mi.nativePrivateDirty = (int)tmpLong[0];
15994                        }
15995
15996                        final long myTotalPss = mi.getTotalPss();
15997                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15998                        totalPss += myTotalPss;
15999                        nativeProcTotalPss += myTotalPss;
16000
16001                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16002                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16003                        procMems.add(pssItem);
16004
16005                        nativePss += mi.nativePss;
16006                        nativeSwapPss += mi.nativeSwappedOutPss;
16007                        dalvikPss += mi.dalvikPss;
16008                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16009                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16010                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16011                            dalvikSubitemSwapPss[j] +=
16012                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16013                        }
16014                        otherPss += mi.otherPss;
16015                        otherSwapPss += mi.otherSwappedOutPss;
16016                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16017                            long mem = mi.getOtherPss(j);
16018                            miscPss[j] += mem;
16019                            otherPss -= mem;
16020                            mem = mi.getOtherSwappedOutPss(j);
16021                            miscSwapPss[j] += mem;
16022                            otherSwapPss -= mem;
16023                        }
16024                        oomPss[0] += myTotalPss;
16025                        oomSwapPss[0] += myTotalSwapPss;
16026                        if (oomProcs[0] == null) {
16027                            oomProcs[0] = new ArrayList<MemItem>();
16028                        }
16029                        oomProcs[0].add(pssItem);
16030                    }
16031                }
16032            }
16033
16034            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16035
16036            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16037            final MemItem dalvikItem =
16038                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16039            if (dalvikSubitemPss.length > 0) {
16040                dalvikItem.subitems = new ArrayList<MemItem>();
16041                for (int j=0; j<dalvikSubitemPss.length; j++) {
16042                    final String name = Debug.MemoryInfo.getOtherLabel(
16043                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16044                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16045                                    dalvikSubitemSwapPss[j], j));
16046                }
16047            }
16048            catMems.add(dalvikItem);
16049            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16050            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16051                String label = Debug.MemoryInfo.getOtherLabel(j);
16052                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16053            }
16054
16055            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16056            for (int j=0; j<oomPss.length; j++) {
16057                if (oomPss[j] != 0) {
16058                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16059                            : DUMP_MEM_OOM_LABEL[j];
16060                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16061                            DUMP_MEM_OOM_ADJ[j]);
16062                    item.subitems = oomProcs[j];
16063                    oomMems.add(item);
16064                }
16065            }
16066
16067            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16068            if (!brief && !oomOnly && !isCompact) {
16069                pw.println();
16070                pw.println("Total PSS by process:");
16071                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16072                pw.println();
16073            }
16074            if (!isCompact) {
16075                pw.println("Total PSS by OOM adjustment:");
16076            }
16077            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16078            if (!brief && !oomOnly) {
16079                PrintWriter out = categoryPw != null ? categoryPw : pw;
16080                if (!isCompact) {
16081                    out.println();
16082                    out.println("Total PSS by category:");
16083                }
16084                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16085            }
16086            if (!isCompact) {
16087                pw.println();
16088            }
16089            MemInfoReader memInfo = new MemInfoReader();
16090            memInfo.readMemInfo();
16091            if (nativeProcTotalPss > 0) {
16092                synchronized (this) {
16093                    final long cachedKb = memInfo.getCachedSizeKb();
16094                    final long freeKb = memInfo.getFreeSizeKb();
16095                    final long zramKb = memInfo.getZramTotalSizeKb();
16096                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16097                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16098                            kernelKb*1024, nativeProcTotalPss*1024);
16099                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16100                            nativeProcTotalPss);
16101                }
16102            }
16103            if (!brief) {
16104                if (!isCompact) {
16105                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16106                    pw.print(" (status ");
16107                    switch (mLastMemoryLevel) {
16108                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16109                            pw.println("normal)");
16110                            break;
16111                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16112                            pw.println("moderate)");
16113                            break;
16114                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16115                            pw.println("low)");
16116                            break;
16117                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16118                            pw.println("critical)");
16119                            break;
16120                        default:
16121                            pw.print(mLastMemoryLevel);
16122                            pw.println(")");
16123                            break;
16124                    }
16125                    pw.print(" Free RAM: ");
16126                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16127                            + memInfo.getFreeSizeKb()));
16128                    pw.print(" (");
16129                    pw.print(stringifyKBSize(cachedPss));
16130                    pw.print(" cached pss + ");
16131                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16132                    pw.print(" cached kernel + ");
16133                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16134                    pw.println(" free)");
16135                } else {
16136                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16137                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16138                            + memInfo.getFreeSizeKb()); pw.print(",");
16139                    pw.println(totalPss - cachedPss);
16140                }
16141            }
16142            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16143                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16144                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16145            if (!isCompact) {
16146                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16147                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16148                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16149                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16150                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16151            } else {
16152                pw.print("lostram,"); pw.println(lostRAM);
16153            }
16154            if (!brief) {
16155                if (memInfo.getZramTotalSizeKb() != 0) {
16156                    if (!isCompact) {
16157                        pw.print("     ZRAM: ");
16158                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16159                                pw.print(" physical used for ");
16160                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16161                                        - memInfo.getSwapFreeSizeKb()));
16162                                pw.print(" in swap (");
16163                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16164                                pw.println(" total swap)");
16165                    } else {
16166                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16167                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16168                                pw.println(memInfo.getSwapFreeSizeKb());
16169                    }
16170                }
16171                final long[] ksm = getKsmInfo();
16172                if (!isCompact) {
16173                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16174                            || ksm[KSM_VOLATILE] != 0) {
16175                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16176                                pw.print(" saved from shared ");
16177                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16178                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16179                                pw.print(" unshared; ");
16180                                pw.print(stringifyKBSize(
16181                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16182                    }
16183                    pw.print("   Tuning: ");
16184                    pw.print(ActivityManager.staticGetMemoryClass());
16185                    pw.print(" (large ");
16186                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16187                    pw.print("), oom ");
16188                    pw.print(stringifySize(
16189                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16190                    pw.print(", restore limit ");
16191                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16192                    if (ActivityManager.isLowRamDeviceStatic()) {
16193                        pw.print(" (low-ram)");
16194                    }
16195                    if (ActivityManager.isHighEndGfx()) {
16196                        pw.print(" (high-end-gfx)");
16197                    }
16198                    pw.println();
16199                } else {
16200                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16201                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16202                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16203                    pw.print("tuning,");
16204                    pw.print(ActivityManager.staticGetMemoryClass());
16205                    pw.print(',');
16206                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16207                    pw.print(',');
16208                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16209                    if (ActivityManager.isLowRamDeviceStatic()) {
16210                        pw.print(",low-ram");
16211                    }
16212                    if (ActivityManager.isHighEndGfx()) {
16213                        pw.print(",high-end-gfx");
16214                    }
16215                    pw.println();
16216                }
16217            }
16218        }
16219    }
16220
16221    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16222            long memtrack, String name) {
16223        sb.append("  ");
16224        sb.append(ProcessList.makeOomAdjString(oomAdj));
16225        sb.append(' ');
16226        sb.append(ProcessList.makeProcStateString(procState));
16227        sb.append(' ');
16228        ProcessList.appendRamKb(sb, pss);
16229        sb.append(": ");
16230        sb.append(name);
16231        if (memtrack > 0) {
16232            sb.append(" (");
16233            sb.append(stringifyKBSize(memtrack));
16234            sb.append(" memtrack)");
16235        }
16236    }
16237
16238    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16239        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16240        sb.append(" (pid ");
16241        sb.append(mi.pid);
16242        sb.append(") ");
16243        sb.append(mi.adjType);
16244        sb.append('\n');
16245        if (mi.adjReason != null) {
16246            sb.append("                      ");
16247            sb.append(mi.adjReason);
16248            sb.append('\n');
16249        }
16250    }
16251
16252    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16253        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16254        for (int i=0, N=memInfos.size(); i<N; i++) {
16255            ProcessMemInfo mi = memInfos.get(i);
16256            infoMap.put(mi.pid, mi);
16257        }
16258        updateCpuStatsNow();
16259        long[] memtrackTmp = new long[1];
16260        synchronized (mProcessCpuTracker) {
16261            final int N = mProcessCpuTracker.countStats();
16262            for (int i=0; i<N; i++) {
16263                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16264                if (st.vsize > 0) {
16265                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16266                    if (pss > 0) {
16267                        if (infoMap.indexOfKey(st.pid) < 0) {
16268                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16269                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16270                            mi.pss = pss;
16271                            mi.memtrack = memtrackTmp[0];
16272                            memInfos.add(mi);
16273                        }
16274                    }
16275                }
16276            }
16277        }
16278
16279        long totalPss = 0;
16280        long totalMemtrack = 0;
16281        for (int i=0, N=memInfos.size(); i<N; i++) {
16282            ProcessMemInfo mi = memInfos.get(i);
16283            if (mi.pss == 0) {
16284                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16285                mi.memtrack = memtrackTmp[0];
16286            }
16287            totalPss += mi.pss;
16288            totalMemtrack += mi.memtrack;
16289        }
16290        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16291            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16292                if (lhs.oomAdj != rhs.oomAdj) {
16293                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16294                }
16295                if (lhs.pss != rhs.pss) {
16296                    return lhs.pss < rhs.pss ? 1 : -1;
16297                }
16298                return 0;
16299            }
16300        });
16301
16302        StringBuilder tag = new StringBuilder(128);
16303        StringBuilder stack = new StringBuilder(128);
16304        tag.append("Low on memory -- ");
16305        appendMemBucket(tag, totalPss, "total", false);
16306        appendMemBucket(stack, totalPss, "total", true);
16307
16308        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16309        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16310        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16311
16312        boolean firstLine = true;
16313        int lastOomAdj = Integer.MIN_VALUE;
16314        long extraNativeRam = 0;
16315        long extraNativeMemtrack = 0;
16316        long cachedPss = 0;
16317        for (int i=0, N=memInfos.size(); i<N; i++) {
16318            ProcessMemInfo mi = memInfos.get(i);
16319
16320            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16321                cachedPss += mi.pss;
16322            }
16323
16324            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16325                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16326                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16327                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16328                if (lastOomAdj != mi.oomAdj) {
16329                    lastOomAdj = mi.oomAdj;
16330                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16331                        tag.append(" / ");
16332                    }
16333                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16334                        if (firstLine) {
16335                            stack.append(":");
16336                            firstLine = false;
16337                        }
16338                        stack.append("\n\t at ");
16339                    } else {
16340                        stack.append("$");
16341                    }
16342                } else {
16343                    tag.append(" ");
16344                    stack.append("$");
16345                }
16346                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16347                    appendMemBucket(tag, mi.pss, mi.name, false);
16348                }
16349                appendMemBucket(stack, mi.pss, mi.name, true);
16350                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16351                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16352                    stack.append("(");
16353                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16354                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16355                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16356                            stack.append(":");
16357                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16358                        }
16359                    }
16360                    stack.append(")");
16361                }
16362            }
16363
16364            appendMemInfo(fullNativeBuilder, mi);
16365            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16366                // The short form only has native processes that are >= 512K.
16367                if (mi.pss >= 512) {
16368                    appendMemInfo(shortNativeBuilder, mi);
16369                } else {
16370                    extraNativeRam += mi.pss;
16371                    extraNativeMemtrack += mi.memtrack;
16372                }
16373            } else {
16374                // Short form has all other details, but if we have collected RAM
16375                // from smaller native processes let's dump a summary of that.
16376                if (extraNativeRam > 0) {
16377                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16378                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16379                    shortNativeBuilder.append('\n');
16380                    extraNativeRam = 0;
16381                }
16382                appendMemInfo(fullJavaBuilder, mi);
16383            }
16384        }
16385
16386        fullJavaBuilder.append("           ");
16387        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16388        fullJavaBuilder.append(": TOTAL");
16389        if (totalMemtrack > 0) {
16390            fullJavaBuilder.append(" (");
16391            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16392            fullJavaBuilder.append(" memtrack)");
16393        } else {
16394        }
16395        fullJavaBuilder.append("\n");
16396
16397        MemInfoReader memInfo = new MemInfoReader();
16398        memInfo.readMemInfo();
16399        final long[] infos = memInfo.getRawInfo();
16400
16401        StringBuilder memInfoBuilder = new StringBuilder(1024);
16402        Debug.getMemInfo(infos);
16403        memInfoBuilder.append("  MemInfo: ");
16404        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16405        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16406        memInfoBuilder.append(stringifyKBSize(
16407                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16408        memInfoBuilder.append(stringifyKBSize(
16409                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16410        memInfoBuilder.append(stringifyKBSize(
16411                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16412        memInfoBuilder.append("           ");
16413        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16414        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16415        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16416        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16417        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16418            memInfoBuilder.append("  ZRAM: ");
16419            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16420            memInfoBuilder.append(" RAM, ");
16421            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16422            memInfoBuilder.append(" swap total, ");
16423            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16424            memInfoBuilder.append(" swap free\n");
16425        }
16426        final long[] ksm = getKsmInfo();
16427        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16428                || ksm[KSM_VOLATILE] != 0) {
16429            memInfoBuilder.append("  KSM: ");
16430            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16431            memInfoBuilder.append(" saved from shared ");
16432            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16433            memInfoBuilder.append("\n       ");
16434            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16435            memInfoBuilder.append(" unshared; ");
16436            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16437            memInfoBuilder.append(" volatile\n");
16438        }
16439        memInfoBuilder.append("  Free RAM: ");
16440        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16441                + memInfo.getFreeSizeKb()));
16442        memInfoBuilder.append("\n");
16443        memInfoBuilder.append("  Used RAM: ");
16444        memInfoBuilder.append(stringifyKBSize(
16445                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16446        memInfoBuilder.append("\n");
16447        memInfoBuilder.append("  Lost RAM: ");
16448        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16449                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16450                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16451        memInfoBuilder.append("\n");
16452        Slog.i(TAG, "Low on memory:");
16453        Slog.i(TAG, shortNativeBuilder.toString());
16454        Slog.i(TAG, fullJavaBuilder.toString());
16455        Slog.i(TAG, memInfoBuilder.toString());
16456
16457        StringBuilder dropBuilder = new StringBuilder(1024);
16458        /*
16459        StringWriter oomSw = new StringWriter();
16460        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16461        StringWriter catSw = new StringWriter();
16462        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16463        String[] emptyArgs = new String[] { };
16464        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16465        oomPw.flush();
16466        String oomString = oomSw.toString();
16467        */
16468        dropBuilder.append("Low on memory:");
16469        dropBuilder.append(stack);
16470        dropBuilder.append('\n');
16471        dropBuilder.append(fullNativeBuilder);
16472        dropBuilder.append(fullJavaBuilder);
16473        dropBuilder.append('\n');
16474        dropBuilder.append(memInfoBuilder);
16475        dropBuilder.append('\n');
16476        /*
16477        dropBuilder.append(oomString);
16478        dropBuilder.append('\n');
16479        */
16480        StringWriter catSw = new StringWriter();
16481        synchronized (ActivityManagerService.this) {
16482            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16483            String[] emptyArgs = new String[] { };
16484            catPw.println();
16485            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16486            catPw.println();
16487            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16488                    false, null).dumpLocked();
16489            catPw.println();
16490            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16491            catPw.flush();
16492        }
16493        dropBuilder.append(catSw.toString());
16494        addErrorToDropBox("lowmem", null, "system_server", null,
16495                null, tag.toString(), dropBuilder.toString(), null, null);
16496        //Slog.i(TAG, "Sent to dropbox:");
16497        //Slog.i(TAG, dropBuilder.toString());
16498        synchronized (ActivityManagerService.this) {
16499            long now = SystemClock.uptimeMillis();
16500            if (mLastMemUsageReportTime < now) {
16501                mLastMemUsageReportTime = now;
16502            }
16503        }
16504    }
16505
16506    /**
16507     * Searches array of arguments for the specified string
16508     * @param args array of argument strings
16509     * @param value value to search for
16510     * @return true if the value is contained in the array
16511     */
16512    private static boolean scanArgs(String[] args, String value) {
16513        if (args != null) {
16514            for (String arg : args) {
16515                if (value.equals(arg)) {
16516                    return true;
16517                }
16518            }
16519        }
16520        return false;
16521    }
16522
16523    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16524            ContentProviderRecord cpr, boolean always) {
16525        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16526
16527        if (!inLaunching || always) {
16528            synchronized (cpr) {
16529                cpr.launchingApp = null;
16530                cpr.notifyAll();
16531            }
16532            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16533            String names[] = cpr.info.authority.split(";");
16534            for (int j = 0; j < names.length; j++) {
16535                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16536            }
16537        }
16538
16539        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16540            ContentProviderConnection conn = cpr.connections.get(i);
16541            if (conn.waiting) {
16542                // If this connection is waiting for the provider, then we don't
16543                // need to mess with its process unless we are always removing
16544                // or for some reason the provider is not currently launching.
16545                if (inLaunching && !always) {
16546                    continue;
16547                }
16548            }
16549            ProcessRecord capp = conn.client;
16550            conn.dead = true;
16551            if (conn.stableCount > 0) {
16552                if (!capp.persistent && capp.thread != null
16553                        && capp.pid != 0
16554                        && capp.pid != MY_PID) {
16555                    capp.kill("depends on provider "
16556                            + cpr.name.flattenToShortString()
16557                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16558                }
16559            } else if (capp.thread != null && conn.provider.provider != null) {
16560                try {
16561                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16562                } catch (RemoteException e) {
16563                }
16564                // In the protocol here, we don't expect the client to correctly
16565                // clean up this connection, we'll just remove it.
16566                cpr.connections.remove(i);
16567                if (conn.client.conProviders.remove(conn)) {
16568                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16569                }
16570            }
16571        }
16572
16573        if (inLaunching && always) {
16574            mLaunchingProviders.remove(cpr);
16575        }
16576        return inLaunching;
16577    }
16578
16579    /**
16580     * Main code for cleaning up a process when it has gone away.  This is
16581     * called both as a result of the process dying, or directly when stopping
16582     * a process when running in single process mode.
16583     *
16584     * @return Returns true if the given process has been restarted, so the
16585     * app that was passed in must remain on the process lists.
16586     */
16587    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16588            boolean restarting, boolean allowRestart, int index) {
16589        if (index >= 0) {
16590            removeLruProcessLocked(app);
16591            ProcessList.remove(app.pid);
16592        }
16593
16594        mProcessesToGc.remove(app);
16595        mPendingPssProcesses.remove(app);
16596
16597        // Dismiss any open dialogs.
16598        if (app.crashDialog != null && !app.forceCrashReport) {
16599            app.crashDialog.dismiss();
16600            app.crashDialog = null;
16601        }
16602        if (app.anrDialog != null) {
16603            app.anrDialog.dismiss();
16604            app.anrDialog = null;
16605        }
16606        if (app.waitDialog != null) {
16607            app.waitDialog.dismiss();
16608            app.waitDialog = null;
16609        }
16610
16611        app.crashing = false;
16612        app.notResponding = false;
16613
16614        app.resetPackageList(mProcessStats);
16615        app.unlinkDeathRecipient();
16616        app.makeInactive(mProcessStats);
16617        app.waitingToKill = null;
16618        app.forcingToForeground = null;
16619        updateProcessForegroundLocked(app, false, false);
16620        app.foregroundActivities = false;
16621        app.hasShownUi = false;
16622        app.treatLikeActivity = false;
16623        app.hasAboveClient = false;
16624        app.hasClientActivities = false;
16625
16626        mServices.killServicesLocked(app, allowRestart);
16627
16628        boolean restart = false;
16629
16630        // Remove published content providers.
16631        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16632            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16633            final boolean always = app.bad || !allowRestart;
16634            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16635            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16636                // We left the provider in the launching list, need to
16637                // restart it.
16638                restart = true;
16639            }
16640
16641            cpr.provider = null;
16642            cpr.proc = null;
16643        }
16644        app.pubProviders.clear();
16645
16646        // Take care of any launching providers waiting for this process.
16647        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16648            restart = true;
16649        }
16650
16651        // Unregister from connected content providers.
16652        if (!app.conProviders.isEmpty()) {
16653            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16654                ContentProviderConnection conn = app.conProviders.get(i);
16655                conn.provider.connections.remove(conn);
16656                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16657                        conn.provider.name);
16658            }
16659            app.conProviders.clear();
16660        }
16661
16662        // At this point there may be remaining entries in mLaunchingProviders
16663        // where we were the only one waiting, so they are no longer of use.
16664        // Look for these and clean up if found.
16665        // XXX Commented out for now.  Trying to figure out a way to reproduce
16666        // the actual situation to identify what is actually going on.
16667        if (false) {
16668            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16669                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16670                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16671                    synchronized (cpr) {
16672                        cpr.launchingApp = null;
16673                        cpr.notifyAll();
16674                    }
16675                }
16676            }
16677        }
16678
16679        skipCurrentReceiverLocked(app);
16680
16681        // Unregister any receivers.
16682        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16683            removeReceiverLocked(app.receivers.valueAt(i));
16684        }
16685        app.receivers.clear();
16686
16687        // If the app is undergoing backup, tell the backup manager about it
16688        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16689            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16690                    + mBackupTarget.appInfo + " died during backup");
16691            try {
16692                IBackupManager bm = IBackupManager.Stub.asInterface(
16693                        ServiceManager.getService(Context.BACKUP_SERVICE));
16694                bm.agentDisconnected(app.info.packageName);
16695            } catch (RemoteException e) {
16696                // can't happen; backup manager is local
16697            }
16698        }
16699
16700        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16701            ProcessChangeItem item = mPendingProcessChanges.get(i);
16702            if (item.pid == app.pid) {
16703                mPendingProcessChanges.remove(i);
16704                mAvailProcessChanges.add(item);
16705            }
16706        }
16707        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16708                null).sendToTarget();
16709
16710        // If the caller is restarting this app, then leave it in its
16711        // current lists and let the caller take care of it.
16712        if (restarting) {
16713            return false;
16714        }
16715
16716        if (!app.persistent || app.isolated) {
16717            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16718                    "Removing non-persistent process during cleanup: " + app);
16719            removeProcessNameLocked(app.processName, app.uid);
16720            if (mHeavyWeightProcess == app) {
16721                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16722                        mHeavyWeightProcess.userId, 0));
16723                mHeavyWeightProcess = null;
16724            }
16725        } else if (!app.removed) {
16726            // This app is persistent, so we need to keep its record around.
16727            // If it is not already on the pending app list, add it there
16728            // and start a new process for it.
16729            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16730                mPersistentStartingProcesses.add(app);
16731                restart = true;
16732            }
16733        }
16734        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16735                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16736        mProcessesOnHold.remove(app);
16737
16738        if (app == mHomeProcess) {
16739            mHomeProcess = null;
16740        }
16741        if (app == mPreviousProcess) {
16742            mPreviousProcess = null;
16743        }
16744
16745        if (restart && !app.isolated) {
16746            // We have components that still need to be running in the
16747            // process, so re-launch it.
16748            if (index < 0) {
16749                ProcessList.remove(app.pid);
16750            }
16751            addProcessNameLocked(app);
16752            startProcessLocked(app, "restart", app.processName);
16753            return true;
16754        } else if (app.pid > 0 && app.pid != MY_PID) {
16755            // Goodbye!
16756            boolean removed;
16757            synchronized (mPidsSelfLocked) {
16758                mPidsSelfLocked.remove(app.pid);
16759                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16760            }
16761            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16762            if (app.isolated) {
16763                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16764            }
16765            app.setPid(0);
16766        }
16767        return false;
16768    }
16769
16770    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16771        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16772            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16773            if (cpr.launchingApp == app) {
16774                return true;
16775            }
16776        }
16777        return false;
16778    }
16779
16780    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16781        // Look through the content providers we are waiting to have launched,
16782        // and if any run in this process then either schedule a restart of
16783        // the process or kill the client waiting for it if this process has
16784        // gone bad.
16785        boolean restart = false;
16786        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16787            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16788            if (cpr.launchingApp == app) {
16789                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16790                    restart = true;
16791                } else {
16792                    removeDyingProviderLocked(app, cpr, true);
16793                }
16794            }
16795        }
16796        return restart;
16797    }
16798
16799    // =========================================================
16800    // SERVICES
16801    // =========================================================
16802
16803    @Override
16804    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16805            int flags) {
16806        enforceNotIsolatedCaller("getServices");
16807        synchronized (this) {
16808            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16809        }
16810    }
16811
16812    @Override
16813    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16814        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16815        synchronized (this) {
16816            return mServices.getRunningServiceControlPanelLocked(name);
16817        }
16818    }
16819
16820    @Override
16821    public ComponentName startService(IApplicationThread caller, Intent service,
16822            String resolvedType, String callingPackage, int userId)
16823            throws TransactionTooLargeException {
16824        enforceNotIsolatedCaller("startService");
16825        // Refuse possible leaked file descriptors
16826        if (service != null && service.hasFileDescriptors() == true) {
16827            throw new IllegalArgumentException("File descriptors passed in Intent");
16828        }
16829
16830        if (callingPackage == null) {
16831            throw new IllegalArgumentException("callingPackage cannot be null");
16832        }
16833
16834        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16835                "startService: " + service + " type=" + resolvedType);
16836        synchronized(this) {
16837            final int callingPid = Binder.getCallingPid();
16838            final int callingUid = Binder.getCallingUid();
16839            final long origId = Binder.clearCallingIdentity();
16840            ComponentName res = mServices.startServiceLocked(caller, service,
16841                    resolvedType, callingPid, callingUid, callingPackage, userId);
16842            Binder.restoreCallingIdentity(origId);
16843            return res;
16844        }
16845    }
16846
16847    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16848            String callingPackage, int userId)
16849            throws TransactionTooLargeException {
16850        synchronized(this) {
16851            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16852                    "startServiceInPackage: " + service + " type=" + resolvedType);
16853            final long origId = Binder.clearCallingIdentity();
16854            ComponentName res = mServices.startServiceLocked(null, service,
16855                    resolvedType, -1, uid, callingPackage, userId);
16856            Binder.restoreCallingIdentity(origId);
16857            return res;
16858        }
16859    }
16860
16861    @Override
16862    public int stopService(IApplicationThread caller, Intent service,
16863            String resolvedType, int userId) {
16864        enforceNotIsolatedCaller("stopService");
16865        // Refuse possible leaked file descriptors
16866        if (service != null && service.hasFileDescriptors() == true) {
16867            throw new IllegalArgumentException("File descriptors passed in Intent");
16868        }
16869
16870        synchronized(this) {
16871            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16872        }
16873    }
16874
16875    @Override
16876    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16877        enforceNotIsolatedCaller("peekService");
16878        // Refuse possible leaked file descriptors
16879        if (service != null && service.hasFileDescriptors() == true) {
16880            throw new IllegalArgumentException("File descriptors passed in Intent");
16881        }
16882
16883        if (callingPackage == null) {
16884            throw new IllegalArgumentException("callingPackage cannot be null");
16885        }
16886
16887        synchronized(this) {
16888            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16889        }
16890    }
16891
16892    @Override
16893    public boolean stopServiceToken(ComponentName className, IBinder token,
16894            int startId) {
16895        synchronized(this) {
16896            return mServices.stopServiceTokenLocked(className, token, startId);
16897        }
16898    }
16899
16900    @Override
16901    public void setServiceForeground(ComponentName className, IBinder token,
16902            int id, Notification notification, int flags) {
16903        synchronized(this) {
16904            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16905        }
16906    }
16907
16908    @Override
16909    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16910            boolean requireFull, String name, String callerPackage) {
16911        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16912                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16913    }
16914
16915    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16916            String className, int flags) {
16917        boolean result = false;
16918        // For apps that don't have pre-defined UIDs, check for permission
16919        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16920            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16921                if (ActivityManager.checkUidPermission(
16922                        INTERACT_ACROSS_USERS,
16923                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16924                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16925                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16926                            + " requests FLAG_SINGLE_USER, but app does not hold "
16927                            + INTERACT_ACROSS_USERS;
16928                    Slog.w(TAG, msg);
16929                    throw new SecurityException(msg);
16930                }
16931                // Permission passed
16932                result = true;
16933            }
16934        } else if ("system".equals(componentProcessName)) {
16935            result = true;
16936        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16937            // Phone app and persistent apps are allowed to export singleuser providers.
16938            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16939                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16940        }
16941        if (DEBUG_MU) Slog.v(TAG_MU,
16942                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16943                + Integer.toHexString(flags) + ") = " + result);
16944        return result;
16945    }
16946
16947    /**
16948     * Checks to see if the caller is in the same app as the singleton
16949     * component, or the component is in a special app. It allows special apps
16950     * to export singleton components but prevents exporting singleton
16951     * components for regular apps.
16952     */
16953    boolean isValidSingletonCall(int callingUid, int componentUid) {
16954        int componentAppId = UserHandle.getAppId(componentUid);
16955        return UserHandle.isSameApp(callingUid, componentUid)
16956                || componentAppId == Process.SYSTEM_UID
16957                || componentAppId == Process.PHONE_UID
16958                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16959                        == PackageManager.PERMISSION_GRANTED;
16960    }
16961
16962    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16963            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16964            int userId) throws TransactionTooLargeException {
16965        enforceNotIsolatedCaller("bindService");
16966
16967        // Refuse possible leaked file descriptors
16968        if (service != null && service.hasFileDescriptors() == true) {
16969            throw new IllegalArgumentException("File descriptors passed in Intent");
16970        }
16971
16972        if (callingPackage == null) {
16973            throw new IllegalArgumentException("callingPackage cannot be null");
16974        }
16975
16976        synchronized(this) {
16977            return mServices.bindServiceLocked(caller, token, service,
16978                    resolvedType, connection, flags, callingPackage, userId);
16979        }
16980    }
16981
16982    public boolean unbindService(IServiceConnection connection) {
16983        synchronized (this) {
16984            return mServices.unbindServiceLocked(connection);
16985        }
16986    }
16987
16988    public void publishService(IBinder token, Intent intent, IBinder service) {
16989        // Refuse possible leaked file descriptors
16990        if (intent != null && intent.hasFileDescriptors() == true) {
16991            throw new IllegalArgumentException("File descriptors passed in Intent");
16992        }
16993
16994        synchronized(this) {
16995            if (!(token instanceof ServiceRecord)) {
16996                throw new IllegalArgumentException("Invalid service token");
16997            }
16998            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16999        }
17000    }
17001
17002    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17003        // Refuse possible leaked file descriptors
17004        if (intent != null && intent.hasFileDescriptors() == true) {
17005            throw new IllegalArgumentException("File descriptors passed in Intent");
17006        }
17007
17008        synchronized(this) {
17009            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17010        }
17011    }
17012
17013    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17014        synchronized(this) {
17015            if (!(token instanceof ServiceRecord)) {
17016                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17017                throw new IllegalArgumentException("Invalid service token");
17018            }
17019            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17020        }
17021    }
17022
17023    // =========================================================
17024    // BACKUP AND RESTORE
17025    // =========================================================
17026
17027    // Cause the target app to be launched if necessary and its backup agent
17028    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17029    // activity manager to announce its creation.
17030    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17031        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17032                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17033        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17034
17035        synchronized(this) {
17036            // !!! TODO: currently no check here that we're already bound
17037            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17038            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17039            synchronized (stats) {
17040                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17041            }
17042
17043            // Backup agent is now in use, its package can't be stopped.
17044            try {
17045                AppGlobals.getPackageManager().setPackageStoppedState(
17046                        app.packageName, false, UserHandle.getUserId(app.uid));
17047            } catch (RemoteException e) {
17048            } catch (IllegalArgumentException e) {
17049                Slog.w(TAG, "Failed trying to unstop package "
17050                        + app.packageName + ": " + e);
17051            }
17052
17053            BackupRecord r = new BackupRecord(ss, app, backupMode);
17054            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17055                    ? new ComponentName(app.packageName, app.backupAgentName)
17056                    : new ComponentName("android", "FullBackupAgent");
17057            // startProcessLocked() returns existing proc's record if it's already running
17058            ProcessRecord proc = startProcessLocked(app.processName, app,
17059                    false, 0, "backup", hostingName, false, false, false);
17060            if (proc == null) {
17061                Slog.e(TAG, "Unable to start backup agent process " + r);
17062                return false;
17063            }
17064
17065            // If the app is a regular app (uid >= 10000) and not the system server or phone
17066            // process, etc, then mark it as being in full backup so that certain calls to the
17067            // process can be blocked. This is not reset to false anywhere because we kill the
17068            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17069            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17070                proc.inFullBackup = true;
17071            }
17072            r.app = proc;
17073            mBackupTarget = r;
17074            mBackupAppName = app.packageName;
17075
17076            // Try not to kill the process during backup
17077            updateOomAdjLocked(proc);
17078
17079            // If the process is already attached, schedule the creation of the backup agent now.
17080            // If it is not yet live, this will be done when it attaches to the framework.
17081            if (proc.thread != null) {
17082                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17083                try {
17084                    proc.thread.scheduleCreateBackupAgent(app,
17085                            compatibilityInfoForPackageLocked(app), backupMode);
17086                } catch (RemoteException e) {
17087                    // Will time out on the backup manager side
17088                }
17089            } else {
17090                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17091            }
17092            // Invariants: at this point, the target app process exists and the application
17093            // is either already running or in the process of coming up.  mBackupTarget and
17094            // mBackupAppName describe the app, so that when it binds back to the AM we
17095            // know that it's scheduled for a backup-agent operation.
17096        }
17097
17098        return true;
17099    }
17100
17101    @Override
17102    public void clearPendingBackup() {
17103        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17104        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17105
17106        synchronized (this) {
17107            mBackupTarget = null;
17108            mBackupAppName = null;
17109        }
17110    }
17111
17112    // A backup agent has just come up
17113    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17114        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17115                + " = " + agent);
17116
17117        synchronized(this) {
17118            if (!agentPackageName.equals(mBackupAppName)) {
17119                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17120                return;
17121            }
17122        }
17123
17124        long oldIdent = Binder.clearCallingIdentity();
17125        try {
17126            IBackupManager bm = IBackupManager.Stub.asInterface(
17127                    ServiceManager.getService(Context.BACKUP_SERVICE));
17128            bm.agentConnected(agentPackageName, agent);
17129        } catch (RemoteException e) {
17130            // can't happen; the backup manager service is local
17131        } catch (Exception e) {
17132            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17133            e.printStackTrace();
17134        } finally {
17135            Binder.restoreCallingIdentity(oldIdent);
17136        }
17137    }
17138
17139    // done with this agent
17140    public void unbindBackupAgent(ApplicationInfo appInfo) {
17141        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17142        if (appInfo == null) {
17143            Slog.w(TAG, "unbind backup agent for null app");
17144            return;
17145        }
17146
17147        synchronized(this) {
17148            try {
17149                if (mBackupAppName == null) {
17150                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17151                    return;
17152                }
17153
17154                if (!mBackupAppName.equals(appInfo.packageName)) {
17155                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17156                    return;
17157                }
17158
17159                // Not backing this app up any more; reset its OOM adjustment
17160                final ProcessRecord proc = mBackupTarget.app;
17161                updateOomAdjLocked(proc);
17162
17163                // If the app crashed during backup, 'thread' will be null here
17164                if (proc.thread != null) {
17165                    try {
17166                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17167                                compatibilityInfoForPackageLocked(appInfo));
17168                    } catch (Exception e) {
17169                        Slog.e(TAG, "Exception when unbinding backup agent:");
17170                        e.printStackTrace();
17171                    }
17172                }
17173            } finally {
17174                mBackupTarget = null;
17175                mBackupAppName = null;
17176            }
17177        }
17178    }
17179    // =========================================================
17180    // BROADCASTS
17181    // =========================================================
17182
17183    boolean isPendingBroadcastProcessLocked(int pid) {
17184        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17185                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17186    }
17187
17188    void skipPendingBroadcastLocked(int pid) {
17189            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17190            for (BroadcastQueue queue : mBroadcastQueues) {
17191                queue.skipPendingBroadcastLocked(pid);
17192            }
17193    }
17194
17195    // The app just attached; send any pending broadcasts that it should receive
17196    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17197        boolean didSomething = false;
17198        for (BroadcastQueue queue : mBroadcastQueues) {
17199            didSomething |= queue.sendPendingBroadcastsLocked(app);
17200        }
17201        return didSomething;
17202    }
17203
17204    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17205            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17206        enforceNotIsolatedCaller("registerReceiver");
17207        ArrayList<Intent> stickyIntents = null;
17208        ProcessRecord callerApp = null;
17209        int callingUid;
17210        int callingPid;
17211        synchronized(this) {
17212            if (caller != null) {
17213                callerApp = getRecordForAppLocked(caller);
17214                if (callerApp == null) {
17215                    throw new SecurityException(
17216                            "Unable to find app for caller " + caller
17217                            + " (pid=" + Binder.getCallingPid()
17218                            + ") when registering receiver " + receiver);
17219                }
17220                if (callerApp.info.uid != Process.SYSTEM_UID &&
17221                        !callerApp.pkgList.containsKey(callerPackage) &&
17222                        !"android".equals(callerPackage)) {
17223                    throw new SecurityException("Given caller package " + callerPackage
17224                            + " is not running in process " + callerApp);
17225                }
17226                callingUid = callerApp.info.uid;
17227                callingPid = callerApp.pid;
17228            } else {
17229                callerPackage = null;
17230                callingUid = Binder.getCallingUid();
17231                callingPid = Binder.getCallingPid();
17232            }
17233
17234            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17235                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17236
17237            Iterator<String> actions = filter.actionsIterator();
17238            if (actions == null) {
17239                ArrayList<String> noAction = new ArrayList<String>(1);
17240                noAction.add(null);
17241                actions = noAction.iterator();
17242            }
17243
17244            // Collect stickies of users
17245            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17246            while (actions.hasNext()) {
17247                String action = actions.next();
17248                for (int id : userIds) {
17249                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17250                    if (stickies != null) {
17251                        ArrayList<Intent> intents = stickies.get(action);
17252                        if (intents != null) {
17253                            if (stickyIntents == null) {
17254                                stickyIntents = new ArrayList<Intent>();
17255                            }
17256                            stickyIntents.addAll(intents);
17257                        }
17258                    }
17259                }
17260            }
17261        }
17262
17263        ArrayList<Intent> allSticky = null;
17264        if (stickyIntents != null) {
17265            final ContentResolver resolver = mContext.getContentResolver();
17266            // Look for any matching sticky broadcasts...
17267            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17268                Intent intent = stickyIntents.get(i);
17269                // If intent has scheme "content", it will need to acccess
17270                // provider that needs to lock mProviderMap in ActivityThread
17271                // and also it may need to wait application response, so we
17272                // cannot lock ActivityManagerService here.
17273                if (filter.match(resolver, intent, true, TAG) >= 0) {
17274                    if (allSticky == null) {
17275                        allSticky = new ArrayList<Intent>();
17276                    }
17277                    allSticky.add(intent);
17278                }
17279            }
17280        }
17281
17282        // The first sticky in the list is returned directly back to the client.
17283        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17284        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17285        if (receiver == null) {
17286            return sticky;
17287        }
17288
17289        synchronized (this) {
17290            if (callerApp != null && (callerApp.thread == null
17291                    || callerApp.thread.asBinder() != caller.asBinder())) {
17292                // Original caller already died
17293                return null;
17294            }
17295            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17296            if (rl == null) {
17297                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17298                        userId, receiver);
17299                if (rl.app != null) {
17300                    rl.app.receivers.add(rl);
17301                } else {
17302                    try {
17303                        receiver.asBinder().linkToDeath(rl, 0);
17304                    } catch (RemoteException e) {
17305                        return sticky;
17306                    }
17307                    rl.linkedToDeath = true;
17308                }
17309                mRegisteredReceivers.put(receiver.asBinder(), rl);
17310            } else if (rl.uid != callingUid) {
17311                throw new IllegalArgumentException(
17312                        "Receiver requested to register for uid " + callingUid
17313                        + " was previously registered for uid " + rl.uid);
17314            } else if (rl.pid != callingPid) {
17315                throw new IllegalArgumentException(
17316                        "Receiver requested to register for pid " + callingPid
17317                        + " was previously registered for pid " + rl.pid);
17318            } else if (rl.userId != userId) {
17319                throw new IllegalArgumentException(
17320                        "Receiver requested to register for user " + userId
17321                        + " was previously registered for user " + rl.userId);
17322            }
17323            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17324                    permission, callingUid, userId);
17325            rl.add(bf);
17326            if (!bf.debugCheck()) {
17327                Slog.w(TAG, "==> For Dynamic broadcast");
17328            }
17329            mReceiverResolver.addFilter(bf);
17330
17331            // Enqueue broadcasts for all existing stickies that match
17332            // this filter.
17333            if (allSticky != null) {
17334                ArrayList receivers = new ArrayList();
17335                receivers.add(bf);
17336
17337                final int stickyCount = allSticky.size();
17338                for (int i = 0; i < stickyCount; i++) {
17339                    Intent intent = allSticky.get(i);
17340                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17341                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17342                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17343                            null, 0, null, null, false, true, true, -1);
17344                    queue.enqueueParallelBroadcastLocked(r);
17345                    queue.scheduleBroadcastsLocked();
17346                }
17347            }
17348
17349            return sticky;
17350        }
17351    }
17352
17353    public void unregisterReceiver(IIntentReceiver receiver) {
17354        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17355
17356        final long origId = Binder.clearCallingIdentity();
17357        try {
17358            boolean doTrim = false;
17359
17360            synchronized(this) {
17361                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17362                if (rl != null) {
17363                    final BroadcastRecord r = rl.curBroadcast;
17364                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17365                        final boolean doNext = r.queue.finishReceiverLocked(
17366                                r, r.resultCode, r.resultData, r.resultExtras,
17367                                r.resultAbort, false);
17368                        if (doNext) {
17369                            doTrim = true;
17370                            r.queue.processNextBroadcast(false);
17371                        }
17372                    }
17373
17374                    if (rl.app != null) {
17375                        rl.app.receivers.remove(rl);
17376                    }
17377                    removeReceiverLocked(rl);
17378                    if (rl.linkedToDeath) {
17379                        rl.linkedToDeath = false;
17380                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17381                    }
17382                }
17383            }
17384
17385            // If we actually concluded any broadcasts, we might now be able
17386            // to trim the recipients' apps from our working set
17387            if (doTrim) {
17388                trimApplications();
17389                return;
17390            }
17391
17392        } finally {
17393            Binder.restoreCallingIdentity(origId);
17394        }
17395    }
17396
17397    void removeReceiverLocked(ReceiverList rl) {
17398        mRegisteredReceivers.remove(rl.receiver.asBinder());
17399        for (int i = rl.size() - 1; i >= 0; i--) {
17400            mReceiverResolver.removeFilter(rl.get(i));
17401        }
17402    }
17403
17404    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17405        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17406            ProcessRecord r = mLruProcesses.get(i);
17407            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17408                try {
17409                    r.thread.dispatchPackageBroadcast(cmd, packages);
17410                } catch (RemoteException ex) {
17411                }
17412            }
17413        }
17414    }
17415
17416    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17417            int callingUid, int[] users) {
17418        // TODO: come back and remove this assumption to triage all broadcasts
17419        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17420
17421        List<ResolveInfo> receivers = null;
17422        try {
17423            HashSet<ComponentName> singleUserReceivers = null;
17424            boolean scannedFirstReceivers = false;
17425            for (int user : users) {
17426                // Skip users that have Shell restrictions, with exception of always permitted
17427                // Shell broadcasts
17428                if (callingUid == Process.SHELL_UID
17429                        && mUserController.hasUserRestriction(
17430                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17431                        && !isPermittedShellBroadcast(intent)) {
17432                    continue;
17433                }
17434                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17435                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17436                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17437                    // If this is not the system user, we need to check for
17438                    // any receivers that should be filtered out.
17439                    for (int i=0; i<newReceivers.size(); i++) {
17440                        ResolveInfo ri = newReceivers.get(i);
17441                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17442                            newReceivers.remove(i);
17443                            i--;
17444                        }
17445                    }
17446                }
17447                if (newReceivers != null && newReceivers.size() == 0) {
17448                    newReceivers = null;
17449                }
17450                if (receivers == null) {
17451                    receivers = newReceivers;
17452                } else if (newReceivers != null) {
17453                    // We need to concatenate the additional receivers
17454                    // found with what we have do far.  This would be easy,
17455                    // but we also need to de-dup any receivers that are
17456                    // singleUser.
17457                    if (!scannedFirstReceivers) {
17458                        // Collect any single user receivers we had already retrieved.
17459                        scannedFirstReceivers = true;
17460                        for (int i=0; i<receivers.size(); i++) {
17461                            ResolveInfo ri = receivers.get(i);
17462                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17463                                ComponentName cn = new ComponentName(
17464                                        ri.activityInfo.packageName, ri.activityInfo.name);
17465                                if (singleUserReceivers == null) {
17466                                    singleUserReceivers = new HashSet<ComponentName>();
17467                                }
17468                                singleUserReceivers.add(cn);
17469                            }
17470                        }
17471                    }
17472                    // Add the new results to the existing results, tracking
17473                    // and de-dupping single user receivers.
17474                    for (int i=0; i<newReceivers.size(); i++) {
17475                        ResolveInfo ri = newReceivers.get(i);
17476                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17477                            ComponentName cn = new ComponentName(
17478                                    ri.activityInfo.packageName, ri.activityInfo.name);
17479                            if (singleUserReceivers == null) {
17480                                singleUserReceivers = new HashSet<ComponentName>();
17481                            }
17482                            if (!singleUserReceivers.contains(cn)) {
17483                                singleUserReceivers.add(cn);
17484                                receivers.add(ri);
17485                            }
17486                        } else {
17487                            receivers.add(ri);
17488                        }
17489                    }
17490                }
17491            }
17492        } catch (RemoteException ex) {
17493            // pm is in same process, this will never happen.
17494        }
17495        return receivers;
17496    }
17497
17498    private boolean isPermittedShellBroadcast(Intent intent) {
17499        // remote bugreport should always be allowed to be taken
17500        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17501    }
17502
17503    final int broadcastIntentLocked(ProcessRecord callerApp,
17504            String callerPackage, Intent intent, String resolvedType,
17505            IIntentReceiver resultTo, int resultCode, String resultData,
17506            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17507            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17508        intent = new Intent(intent);
17509
17510        // By default broadcasts do not go to stopped apps.
17511        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17512
17513        // If we have not finished booting, don't allow this to launch new processes.
17514        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17515            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17516        }
17517
17518        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17519                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17520                + " ordered=" + ordered + " userid=" + userId);
17521        if ((resultTo != null) && !ordered) {
17522            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17523        }
17524
17525        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17526                ALLOW_NON_FULL, "broadcast", callerPackage);
17527
17528        // Make sure that the user who is receiving this broadcast is running.
17529        // If not, we will just skip it. Make an exception for shutdown broadcasts
17530        // and upgrade steps.
17531
17532        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17533            if ((callingUid != Process.SYSTEM_UID
17534                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17535                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17536                Slog.w(TAG, "Skipping broadcast of " + intent
17537                        + ": user " + userId + " is stopped");
17538                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17539            }
17540        }
17541
17542        BroadcastOptions brOptions = null;
17543        if (bOptions != null) {
17544            brOptions = new BroadcastOptions(bOptions);
17545            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17546                // See if the caller is allowed to do this.  Note we are checking against
17547                // the actual real caller (not whoever provided the operation as say a
17548                // PendingIntent), because that who is actually supplied the arguments.
17549                if (checkComponentPermission(
17550                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17551                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17552                        != PackageManager.PERMISSION_GRANTED) {
17553                    String msg = "Permission Denial: " + intent.getAction()
17554                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17555                            + ", uid=" + callingUid + ")"
17556                            + " requires "
17557                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17558                    Slog.w(TAG, msg);
17559                    throw new SecurityException(msg);
17560                }
17561            }
17562        }
17563
17564        // Verify that protected broadcasts are only being sent by system code,
17565        // and that system code is only sending protected broadcasts.
17566        final String action = intent.getAction();
17567        final boolean isProtectedBroadcast;
17568        try {
17569            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17570        } catch (RemoteException e) {
17571            Slog.w(TAG, "Remote exception", e);
17572            return ActivityManager.BROADCAST_SUCCESS;
17573        }
17574
17575        final boolean isCallerSystem;
17576        switch (UserHandle.getAppId(callingUid)) {
17577            case Process.ROOT_UID:
17578            case Process.SYSTEM_UID:
17579            case Process.PHONE_UID:
17580            case Process.BLUETOOTH_UID:
17581            case Process.NFC_UID:
17582                isCallerSystem = true;
17583                break;
17584            default:
17585                isCallerSystem = (callerApp != null) && callerApp.persistent;
17586                break;
17587        }
17588
17589        if (isCallerSystem) {
17590            if (isProtectedBroadcast
17591                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17592                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17593                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17594                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17595                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17596                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17597                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17598                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17599                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17600                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17601                // Broadcast is either protected, or it's a public action that
17602                // we've relaxed, so it's fine for system internals to send.
17603            } else {
17604                // The vast majority of broadcasts sent from system internals
17605                // should be protected to avoid security holes, so yell loudly
17606                // to ensure we examine these cases.
17607                if (callerApp != null) {
17608                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17609                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17610                            new Throwable());
17611                } else {
17612                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17613                            + " from system uid " + UserHandle.formatUid(callingUid)
17614                            + " pkg " + callerPackage,
17615                            new Throwable());
17616                }
17617            }
17618
17619        } else {
17620            if (isProtectedBroadcast) {
17621                String msg = "Permission Denial: not allowed to send broadcast "
17622                        + action + " from pid="
17623                        + callingPid + ", uid=" + callingUid;
17624                Slog.w(TAG, msg);
17625                throw new SecurityException(msg);
17626
17627            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17628                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17629                // Special case for compatibility: we don't want apps to send this,
17630                // but historically it has not been protected and apps may be using it
17631                // to poke their own app widget.  So, instead of making it protected,
17632                // just limit it to the caller.
17633                if (callerPackage == null) {
17634                    String msg = "Permission Denial: not allowed to send broadcast "
17635                            + action + " from unknown caller.";
17636                    Slog.w(TAG, msg);
17637                    throw new SecurityException(msg);
17638                } else if (intent.getComponent() != null) {
17639                    // They are good enough to send to an explicit component...  verify
17640                    // it is being sent to the calling app.
17641                    if (!intent.getComponent().getPackageName().equals(
17642                            callerPackage)) {
17643                        String msg = "Permission Denial: not allowed to send broadcast "
17644                                + action + " to "
17645                                + intent.getComponent().getPackageName() + " from "
17646                                + callerPackage;
17647                        Slog.w(TAG, msg);
17648                        throw new SecurityException(msg);
17649                    }
17650                } else {
17651                    // Limit broadcast to their own package.
17652                    intent.setPackage(callerPackage);
17653                }
17654            }
17655        }
17656
17657        if (action != null) {
17658            switch (action) {
17659                case Intent.ACTION_UID_REMOVED:
17660                case Intent.ACTION_PACKAGE_REMOVED:
17661                case Intent.ACTION_PACKAGE_CHANGED:
17662                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17663                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17664                case Intent.ACTION_PACKAGES_SUSPENDED:
17665                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17666                    // Handle special intents: if this broadcast is from the package
17667                    // manager about a package being removed, we need to remove all of
17668                    // its activities from the history stack.
17669                    if (checkComponentPermission(
17670                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17671                            callingPid, callingUid, -1, true)
17672                            != PackageManager.PERMISSION_GRANTED) {
17673                        String msg = "Permission Denial: " + intent.getAction()
17674                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17675                                + ", uid=" + callingUid + ")"
17676                                + " requires "
17677                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17678                        Slog.w(TAG, msg);
17679                        throw new SecurityException(msg);
17680                    }
17681                    switch (action) {
17682                        case Intent.ACTION_UID_REMOVED:
17683                            final Bundle intentExtras = intent.getExtras();
17684                            final int uid = intentExtras != null
17685                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17686                            if (uid >= 0) {
17687                                mBatteryStatsService.removeUid(uid);
17688                                mAppOpsService.uidRemoved(uid);
17689                            }
17690                            break;
17691                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17692                            // If resources are unavailable just force stop all those packages
17693                            // and flush the attribute cache as well.
17694                            String list[] =
17695                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17696                            if (list != null && list.length > 0) {
17697                                for (int i = 0; i < list.length; i++) {
17698                                    forceStopPackageLocked(list[i], -1, false, true, true,
17699                                            false, false, userId, "storage unmount");
17700                                }
17701                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17702                                sendPackageBroadcastLocked(
17703                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17704                                        userId);
17705                            }
17706                            break;
17707                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17708                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17709                            break;
17710                        case Intent.ACTION_PACKAGE_REMOVED:
17711                        case Intent.ACTION_PACKAGE_CHANGED:
17712                            Uri data = intent.getData();
17713                            String ssp;
17714                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17715                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17716                                final boolean replacing =
17717                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17718                                final boolean killProcess =
17719                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17720                                final boolean fullUninstall = removed && !replacing;
17721                                if (removed) {
17722                                    if (killProcess) {
17723                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17724                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17725                                                false, true, true, false, fullUninstall, userId,
17726                                                removed ? "pkg removed" : "pkg changed");
17727                                    }
17728                                    final int cmd = killProcess
17729                                            ? IApplicationThread.PACKAGE_REMOVED
17730                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17731                                    sendPackageBroadcastLocked(cmd,
17732                                            new String[] {ssp}, userId);
17733                                    if (fullUninstall) {
17734                                        mAppOpsService.packageRemoved(
17735                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17736
17737                                        // Remove all permissions granted from/to this package
17738                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17739
17740                                        removeTasksByPackageNameLocked(ssp, userId);
17741                                        mBatteryStatsService.notePackageUninstalled(ssp);
17742                                    }
17743                                } else {
17744                                    if (killProcess) {
17745                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17746                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17747                                                userId, ProcessList.INVALID_ADJ,
17748                                                false, true, true, false, "change " + ssp);
17749                                    }
17750                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17751                                            intent.getStringArrayExtra(
17752                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17753                                }
17754                            }
17755                            break;
17756                        case Intent.ACTION_PACKAGES_SUSPENDED:
17757                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17758                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17759                                    intent.getAction());
17760                            final String[] packageNames = intent.getStringArrayExtra(
17761                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17762                            final int userHandle = intent.getIntExtra(
17763                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17764
17765                            synchronized(ActivityManagerService.this) {
17766                                mRecentTasks.onPackagesSuspendedChanged(
17767                                        packageNames, suspended, userHandle);
17768                            }
17769                            break;
17770                    }
17771                    break;
17772                case Intent.ACTION_PACKAGE_REPLACED:
17773                {
17774                    final Uri data = intent.getData();
17775                    final String ssp;
17776                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17777                        final ApplicationInfo aInfo =
17778                                getPackageManagerInternalLocked().getApplicationInfo(
17779                                        ssp,
17780                                        userId);
17781                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17782                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17783                                new String[] {ssp}, userId);
17784                    }
17785                    break;
17786                }
17787                case Intent.ACTION_PACKAGE_ADDED:
17788                {
17789                    // Special case for adding a package: by default turn on compatibility mode.
17790                    Uri data = intent.getData();
17791                    String ssp;
17792                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17793                        final boolean replacing =
17794                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17795                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17796
17797                        try {
17798                            ApplicationInfo ai = AppGlobals.getPackageManager().
17799                                    getApplicationInfo(ssp, 0, 0);
17800                            mBatteryStatsService.notePackageInstalled(ssp,
17801                                    ai != null ? ai.versionCode : 0);
17802                        } catch (RemoteException e) {
17803                        }
17804                    }
17805                    break;
17806                }
17807                case Intent.ACTION_TIMEZONE_CHANGED:
17808                    // If this is the time zone changed action, queue up a message that will reset
17809                    // the timezone of all currently running processes. This message will get
17810                    // queued up before the broadcast happens.
17811                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17812                    break;
17813                case Intent.ACTION_TIME_CHANGED:
17814                    // If the user set the time, let all running processes know.
17815                    final int is24Hour =
17816                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17817                                    : 0;
17818                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17819                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17820                    synchronized (stats) {
17821                        stats.noteCurrentTimeChangedLocked();
17822                    }
17823                    break;
17824                case Intent.ACTION_CLEAR_DNS_CACHE:
17825                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17826                    break;
17827                case Proxy.PROXY_CHANGE_ACTION:
17828                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17829                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17830                    break;
17831                case android.hardware.Camera.ACTION_NEW_PICTURE:
17832                case android.hardware.Camera.ACTION_NEW_VIDEO:
17833                    // These broadcasts are no longer allowed by the system, since they can
17834                    // cause significant thrashing at a crictical point (using the camera).
17835                    // Apps should use JobScehduler to monitor for media provider changes.
17836                    Slog.w(TAG, action + " no longer allowed; dropping from "
17837                            + UserHandle.formatUid(callingUid));
17838                    // Lie; we don't want to crash the app.
17839                    return ActivityManager.BROADCAST_SUCCESS;
17840            }
17841        }
17842
17843        // Add to the sticky list if requested.
17844        if (sticky) {
17845            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17846                    callingPid, callingUid)
17847                    != PackageManager.PERMISSION_GRANTED) {
17848                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17849                        + callingPid + ", uid=" + callingUid
17850                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17851                Slog.w(TAG, msg);
17852                throw new SecurityException(msg);
17853            }
17854            if (requiredPermissions != null && requiredPermissions.length > 0) {
17855                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17856                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17857                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17858            }
17859            if (intent.getComponent() != null) {
17860                throw new SecurityException(
17861                        "Sticky broadcasts can't target a specific component");
17862            }
17863            // We use userId directly here, since the "all" target is maintained
17864            // as a separate set of sticky broadcasts.
17865            if (userId != UserHandle.USER_ALL) {
17866                // But first, if this is not a broadcast to all users, then
17867                // make sure it doesn't conflict with an existing broadcast to
17868                // all users.
17869                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17870                        UserHandle.USER_ALL);
17871                if (stickies != null) {
17872                    ArrayList<Intent> list = stickies.get(intent.getAction());
17873                    if (list != null) {
17874                        int N = list.size();
17875                        int i;
17876                        for (i=0; i<N; i++) {
17877                            if (intent.filterEquals(list.get(i))) {
17878                                throw new IllegalArgumentException(
17879                                        "Sticky broadcast " + intent + " for user "
17880                                        + userId + " conflicts with existing global broadcast");
17881                            }
17882                        }
17883                    }
17884                }
17885            }
17886            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17887            if (stickies == null) {
17888                stickies = new ArrayMap<>();
17889                mStickyBroadcasts.put(userId, stickies);
17890            }
17891            ArrayList<Intent> list = stickies.get(intent.getAction());
17892            if (list == null) {
17893                list = new ArrayList<>();
17894                stickies.put(intent.getAction(), list);
17895            }
17896            final int stickiesCount = list.size();
17897            int i;
17898            for (i = 0; i < stickiesCount; i++) {
17899                if (intent.filterEquals(list.get(i))) {
17900                    // This sticky already exists, replace it.
17901                    list.set(i, new Intent(intent));
17902                    break;
17903                }
17904            }
17905            if (i >= stickiesCount) {
17906                list.add(new Intent(intent));
17907            }
17908        }
17909
17910        int[] users;
17911        if (userId == UserHandle.USER_ALL) {
17912            // Caller wants broadcast to go to all started users.
17913            users = mUserController.getStartedUserArrayLocked();
17914        } else {
17915            // Caller wants broadcast to go to one specific user.
17916            users = new int[] {userId};
17917        }
17918
17919        // Figure out who all will receive this broadcast.
17920        List receivers = null;
17921        List<BroadcastFilter> registeredReceivers = null;
17922        // Need to resolve the intent to interested receivers...
17923        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17924                 == 0) {
17925            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17926        }
17927        if (intent.getComponent() == null) {
17928            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17929                // Query one target user at a time, excluding shell-restricted users
17930                for (int i = 0; i < users.length; i++) {
17931                    if (mUserController.hasUserRestriction(
17932                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17933                        continue;
17934                    }
17935                    List<BroadcastFilter> registeredReceiversForUser =
17936                            mReceiverResolver.queryIntent(intent,
17937                                    resolvedType, false, users[i]);
17938                    if (registeredReceivers == null) {
17939                        registeredReceivers = registeredReceiversForUser;
17940                    } else if (registeredReceiversForUser != null) {
17941                        registeredReceivers.addAll(registeredReceiversForUser);
17942                    }
17943                }
17944            } else {
17945                registeredReceivers = mReceiverResolver.queryIntent(intent,
17946                        resolvedType, false, userId);
17947            }
17948        }
17949
17950        final boolean replacePending =
17951                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17952
17953        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17954                + " replacePending=" + replacePending);
17955
17956        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17957        if (!ordered && NR > 0) {
17958            // If we are not serializing this broadcast, then send the
17959            // registered receivers separately so they don't wait for the
17960            // components to be launched.
17961            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17962            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17963                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17964                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17965                    resultExtras, ordered, sticky, false, userId);
17966            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17967            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17968            if (!replaced) {
17969                queue.enqueueParallelBroadcastLocked(r);
17970                queue.scheduleBroadcastsLocked();
17971            }
17972            registeredReceivers = null;
17973            NR = 0;
17974        }
17975
17976        // Merge into one list.
17977        int ir = 0;
17978        if (receivers != null) {
17979            // A special case for PACKAGE_ADDED: do not allow the package
17980            // being added to see this broadcast.  This prevents them from
17981            // using this as a back door to get run as soon as they are
17982            // installed.  Maybe in the future we want to have a special install
17983            // broadcast or such for apps, but we'd like to deliberately make
17984            // this decision.
17985            String skipPackages[] = null;
17986            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17987                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17988                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17989                Uri data = intent.getData();
17990                if (data != null) {
17991                    String pkgName = data.getSchemeSpecificPart();
17992                    if (pkgName != null) {
17993                        skipPackages = new String[] { pkgName };
17994                    }
17995                }
17996            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17997                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17998            }
17999            if (skipPackages != null && (skipPackages.length > 0)) {
18000                for (String skipPackage : skipPackages) {
18001                    if (skipPackage != null) {
18002                        int NT = receivers.size();
18003                        for (int it=0; it<NT; it++) {
18004                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18005                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18006                                receivers.remove(it);
18007                                it--;
18008                                NT--;
18009                            }
18010                        }
18011                    }
18012                }
18013            }
18014
18015            int NT = receivers != null ? receivers.size() : 0;
18016            int it = 0;
18017            ResolveInfo curt = null;
18018            BroadcastFilter curr = null;
18019            while (it < NT && ir < NR) {
18020                if (curt == null) {
18021                    curt = (ResolveInfo)receivers.get(it);
18022                }
18023                if (curr == null) {
18024                    curr = registeredReceivers.get(ir);
18025                }
18026                if (curr.getPriority() >= curt.priority) {
18027                    // Insert this broadcast record into the final list.
18028                    receivers.add(it, curr);
18029                    ir++;
18030                    curr = null;
18031                    it++;
18032                    NT++;
18033                } else {
18034                    // Skip to the next ResolveInfo in the final list.
18035                    it++;
18036                    curt = null;
18037                }
18038            }
18039        }
18040        while (ir < NR) {
18041            if (receivers == null) {
18042                receivers = new ArrayList();
18043            }
18044            receivers.add(registeredReceivers.get(ir));
18045            ir++;
18046        }
18047
18048        if ((receivers != null && receivers.size() > 0)
18049                || resultTo != null) {
18050            BroadcastQueue queue = broadcastQueueForIntent(intent);
18051            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18052                    callerPackage, callingPid, callingUid, resolvedType,
18053                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18054                    resultData, resultExtras, ordered, sticky, false, userId);
18055
18056            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18057                    + ": prev had " + queue.mOrderedBroadcasts.size());
18058            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18059                    "Enqueueing broadcast " + r.intent.getAction());
18060
18061            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18062            if (!replaced) {
18063                queue.enqueueOrderedBroadcastLocked(r);
18064                queue.scheduleBroadcastsLocked();
18065            }
18066        } else {
18067            // There was nobody interested in the broadcast, but we still want to record
18068            // that it happened.
18069            if (intent.getComponent() == null && intent.getPackage() == null
18070                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18071                // This was an implicit broadcast... let's record it for posterity.
18072                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18073            }
18074        }
18075
18076        return ActivityManager.BROADCAST_SUCCESS;
18077    }
18078
18079    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18080            int skipCount, long dispatchTime) {
18081        final long now = SystemClock.elapsedRealtime();
18082        if (mCurBroadcastStats == null ||
18083                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18084            mLastBroadcastStats = mCurBroadcastStats;
18085            if (mLastBroadcastStats != null) {
18086                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18087                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18088            }
18089            mCurBroadcastStats = new BroadcastStats();
18090        }
18091        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18092    }
18093
18094    final Intent verifyBroadcastLocked(Intent intent) {
18095        // Refuse possible leaked file descriptors
18096        if (intent != null && intent.hasFileDescriptors() == true) {
18097            throw new IllegalArgumentException("File descriptors passed in Intent");
18098        }
18099
18100        int flags = intent.getFlags();
18101
18102        if (!mProcessesReady) {
18103            // if the caller really truly claims to know what they're doing, go
18104            // ahead and allow the broadcast without launching any receivers
18105            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18106                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18107            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18108                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18109                        + " before boot completion");
18110                throw new IllegalStateException("Cannot broadcast before boot completed");
18111            }
18112        }
18113
18114        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18115            throw new IllegalArgumentException(
18116                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18117        }
18118
18119        return intent;
18120    }
18121
18122    public final int broadcastIntent(IApplicationThread caller,
18123            Intent intent, String resolvedType, IIntentReceiver resultTo,
18124            int resultCode, String resultData, Bundle resultExtras,
18125            String[] requiredPermissions, int appOp, Bundle bOptions,
18126            boolean serialized, boolean sticky, int userId) {
18127        enforceNotIsolatedCaller("broadcastIntent");
18128        synchronized(this) {
18129            intent = verifyBroadcastLocked(intent);
18130
18131            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18132            final int callingPid = Binder.getCallingPid();
18133            final int callingUid = Binder.getCallingUid();
18134            final long origId = Binder.clearCallingIdentity();
18135            int res = broadcastIntentLocked(callerApp,
18136                    callerApp != null ? callerApp.info.packageName : null,
18137                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18138                    requiredPermissions, appOp, bOptions, serialized, sticky,
18139                    callingPid, callingUid, userId);
18140            Binder.restoreCallingIdentity(origId);
18141            return res;
18142        }
18143    }
18144
18145
18146    int broadcastIntentInPackage(String packageName, int uid,
18147            Intent intent, String resolvedType, IIntentReceiver resultTo,
18148            int resultCode, String resultData, Bundle resultExtras,
18149            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18150            int userId) {
18151        synchronized(this) {
18152            intent = verifyBroadcastLocked(intent);
18153
18154            final long origId = Binder.clearCallingIdentity();
18155            String[] requiredPermissions = requiredPermission == null ? null
18156                    : new String[] {requiredPermission};
18157            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18158                    resultTo, resultCode, resultData, resultExtras,
18159                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18160                    sticky, -1, uid, userId);
18161            Binder.restoreCallingIdentity(origId);
18162            return res;
18163        }
18164    }
18165
18166    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18167        // Refuse possible leaked file descriptors
18168        if (intent != null && intent.hasFileDescriptors() == true) {
18169            throw new IllegalArgumentException("File descriptors passed in Intent");
18170        }
18171
18172        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18173                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18174
18175        synchronized(this) {
18176            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18177                    != PackageManager.PERMISSION_GRANTED) {
18178                String msg = "Permission Denial: unbroadcastIntent() from pid="
18179                        + Binder.getCallingPid()
18180                        + ", uid=" + Binder.getCallingUid()
18181                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18182                Slog.w(TAG, msg);
18183                throw new SecurityException(msg);
18184            }
18185            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18186            if (stickies != null) {
18187                ArrayList<Intent> list = stickies.get(intent.getAction());
18188                if (list != null) {
18189                    int N = list.size();
18190                    int i;
18191                    for (i=0; i<N; i++) {
18192                        if (intent.filterEquals(list.get(i))) {
18193                            list.remove(i);
18194                            break;
18195                        }
18196                    }
18197                    if (list.size() <= 0) {
18198                        stickies.remove(intent.getAction());
18199                    }
18200                }
18201                if (stickies.size() <= 0) {
18202                    mStickyBroadcasts.remove(userId);
18203                }
18204            }
18205        }
18206    }
18207
18208    void backgroundServicesFinishedLocked(int userId) {
18209        for (BroadcastQueue queue : mBroadcastQueues) {
18210            queue.backgroundServicesFinishedLocked(userId);
18211        }
18212    }
18213
18214    public void finishReceiver(IBinder who, int resultCode, String resultData,
18215            Bundle resultExtras, boolean resultAbort, int flags) {
18216        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18217
18218        // Refuse possible leaked file descriptors
18219        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18220            throw new IllegalArgumentException("File descriptors passed in Bundle");
18221        }
18222
18223        final long origId = Binder.clearCallingIdentity();
18224        try {
18225            boolean doNext = false;
18226            BroadcastRecord r;
18227
18228            synchronized(this) {
18229                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18230                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18231                r = queue.getMatchingOrderedReceiver(who);
18232                if (r != null) {
18233                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18234                        resultData, resultExtras, resultAbort, true);
18235                }
18236            }
18237
18238            if (doNext) {
18239                r.queue.processNextBroadcast(false);
18240            }
18241            trimApplications();
18242        } finally {
18243            Binder.restoreCallingIdentity(origId);
18244        }
18245    }
18246
18247    // =========================================================
18248    // INSTRUMENTATION
18249    // =========================================================
18250
18251    public boolean startInstrumentation(ComponentName className,
18252            String profileFile, int flags, Bundle arguments,
18253            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18254            int userId, String abiOverride) {
18255        enforceNotIsolatedCaller("startInstrumentation");
18256        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18257                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18258        // Refuse possible leaked file descriptors
18259        if (arguments != null && arguments.hasFileDescriptors()) {
18260            throw new IllegalArgumentException("File descriptors passed in Bundle");
18261        }
18262
18263        synchronized(this) {
18264            InstrumentationInfo ii = null;
18265            ApplicationInfo ai = null;
18266            try {
18267                ii = mContext.getPackageManager().getInstrumentationInfo(
18268                    className, STOCK_PM_FLAGS);
18269                ai = AppGlobals.getPackageManager().getApplicationInfo(
18270                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18271            } catch (PackageManager.NameNotFoundException e) {
18272            } catch (RemoteException e) {
18273            }
18274            if (ii == null) {
18275                reportStartInstrumentationFailureLocked(watcher, className,
18276                        "Unable to find instrumentation info for: " + className);
18277                return false;
18278            }
18279            if (ai == null) {
18280                reportStartInstrumentationFailureLocked(watcher, className,
18281                        "Unable to find instrumentation target package: " + ii.targetPackage);
18282                return false;
18283            }
18284            if (!ai.hasCode()) {
18285                reportStartInstrumentationFailureLocked(watcher, className,
18286                        "Instrumentation target has no code: " + ii.targetPackage);
18287                return false;
18288            }
18289
18290            int match = mContext.getPackageManager().checkSignatures(
18291                    ii.targetPackage, ii.packageName);
18292            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18293                String msg = "Permission Denial: starting instrumentation "
18294                        + className + " from pid="
18295                        + Binder.getCallingPid()
18296                        + ", uid=" + Binder.getCallingPid()
18297                        + " not allowed because package " + ii.packageName
18298                        + " does not have a signature matching the target "
18299                        + ii.targetPackage;
18300                reportStartInstrumentationFailureLocked(watcher, className, msg);
18301                throw new SecurityException(msg);
18302            }
18303
18304            final long origId = Binder.clearCallingIdentity();
18305            // Instrumentation can kill and relaunch even persistent processes
18306            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18307                    "start instr");
18308            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18309            app.instrumentationClass = className;
18310            app.instrumentationInfo = ai;
18311            app.instrumentationProfileFile = profileFile;
18312            app.instrumentationArguments = arguments;
18313            app.instrumentationWatcher = watcher;
18314            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18315            app.instrumentationResultClass = className;
18316            Binder.restoreCallingIdentity(origId);
18317        }
18318
18319        return true;
18320    }
18321
18322    /**
18323     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18324     * error to the logs, but if somebody is watching, send the report there too.  This enables
18325     * the "am" command to report errors with more information.
18326     *
18327     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18328     * @param cn The component name of the instrumentation.
18329     * @param report The error report.
18330     */
18331    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18332            ComponentName cn, String report) {
18333        Slog.w(TAG, report);
18334        if (watcher != null) {
18335            Bundle results = new Bundle();
18336            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18337            results.putString("Error", report);
18338            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18339        }
18340    }
18341
18342    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18343        if (app.instrumentationWatcher != null) {
18344            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18345                    app.instrumentationClass, resultCode, results);
18346        }
18347
18348        // Can't call out of the system process with a lock held, so post a message.
18349        if (app.instrumentationUiAutomationConnection != null) {
18350            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18351                    app.instrumentationUiAutomationConnection).sendToTarget();
18352        }
18353
18354        app.instrumentationWatcher = null;
18355        app.instrumentationUiAutomationConnection = null;
18356        app.instrumentationClass = null;
18357        app.instrumentationInfo = null;
18358        app.instrumentationProfileFile = null;
18359        app.instrumentationArguments = null;
18360
18361        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18362                "finished inst");
18363    }
18364
18365    public void finishInstrumentation(IApplicationThread target,
18366            int resultCode, Bundle results) {
18367        int userId = UserHandle.getCallingUserId();
18368        // Refuse possible leaked file descriptors
18369        if (results != null && results.hasFileDescriptors()) {
18370            throw new IllegalArgumentException("File descriptors passed in Intent");
18371        }
18372
18373        synchronized(this) {
18374            ProcessRecord app = getRecordForAppLocked(target);
18375            if (app == null) {
18376                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18377                return;
18378            }
18379            final long origId = Binder.clearCallingIdentity();
18380            finishInstrumentationLocked(app, resultCode, results);
18381            Binder.restoreCallingIdentity(origId);
18382        }
18383    }
18384
18385    // =========================================================
18386    // CONFIGURATION
18387    // =========================================================
18388
18389    public ConfigurationInfo getDeviceConfigurationInfo() {
18390        ConfigurationInfo config = new ConfigurationInfo();
18391        synchronized (this) {
18392            config.reqTouchScreen = mConfiguration.touchscreen;
18393            config.reqKeyboardType = mConfiguration.keyboard;
18394            config.reqNavigation = mConfiguration.navigation;
18395            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18396                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18397                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18398            }
18399            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18400                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18401                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18402            }
18403            config.reqGlEsVersion = GL_ES_VERSION;
18404        }
18405        return config;
18406    }
18407
18408    ActivityStack getFocusedStack() {
18409        return mStackSupervisor.getFocusedStack();
18410    }
18411
18412    @Override
18413    public int getFocusedStackId() throws RemoteException {
18414        ActivityStack focusedStack = getFocusedStack();
18415        if (focusedStack != null) {
18416            return focusedStack.getStackId();
18417        }
18418        return -1;
18419    }
18420
18421    public Configuration getConfiguration() {
18422        Configuration ci;
18423        synchronized(this) {
18424            ci = new Configuration(mConfiguration);
18425            ci.userSetLocale = false;
18426        }
18427        return ci;
18428    }
18429
18430    @Override
18431    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18432        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18433        synchronized (this) {
18434            mSuppressResizeConfigChanges = suppress;
18435        }
18436    }
18437
18438    @Override
18439    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18440        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18441        if (fromStackId == HOME_STACK_ID) {
18442            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18443        }
18444        synchronized (this) {
18445            final long origId = Binder.clearCallingIdentity();
18446            try {
18447                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18448            } finally {
18449                Binder.restoreCallingIdentity(origId);
18450            }
18451        }
18452    }
18453
18454    @Override
18455    public void updatePersistentConfiguration(Configuration values) {
18456        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18457                "updateConfiguration()");
18458        enforceWriteSettingsPermission("updateConfiguration()");
18459        if (values == null) {
18460            throw new NullPointerException("Configuration must not be null");
18461        }
18462
18463        int userId = UserHandle.getCallingUserId();
18464
18465        synchronized(this) {
18466            final long origId = Binder.clearCallingIdentity();
18467            updateConfigurationLocked(values, null, false, true, userId);
18468            Binder.restoreCallingIdentity(origId);
18469        }
18470    }
18471
18472    private void updateFontScaleIfNeeded() {
18473        final int currentUserId;
18474        synchronized(this) {
18475            currentUserId = mUserController.getCurrentUserIdLocked();
18476        }
18477        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18478                FONT_SCALE, 1.0f, currentUserId);
18479        if (mConfiguration.fontScale != scaleFactor) {
18480            final Configuration configuration = mWindowManager.computeNewConfiguration();
18481            configuration.fontScale = scaleFactor;
18482            updatePersistentConfiguration(configuration);
18483        }
18484    }
18485
18486    private void enforceWriteSettingsPermission(String func) {
18487        int uid = Binder.getCallingUid();
18488        if (uid == Process.ROOT_UID) {
18489            return;
18490        }
18491
18492        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18493                Settings.getPackageNameForUid(mContext, uid), false)) {
18494            return;
18495        }
18496
18497        String msg = "Permission Denial: " + func + " from pid="
18498                + Binder.getCallingPid()
18499                + ", uid=" + uid
18500                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18501        Slog.w(TAG, msg);
18502        throw new SecurityException(msg);
18503    }
18504
18505    public void updateConfiguration(Configuration values) {
18506        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18507                "updateConfiguration()");
18508
18509        synchronized(this) {
18510            if (values == null && mWindowManager != null) {
18511                // sentinel: fetch the current configuration from the window manager
18512                values = mWindowManager.computeNewConfiguration();
18513            }
18514
18515            if (mWindowManager != null) {
18516                mProcessList.applyDisplaySize(mWindowManager);
18517            }
18518
18519            final long origId = Binder.clearCallingIdentity();
18520            if (values != null) {
18521                Settings.System.clearConfiguration(values);
18522            }
18523            updateConfigurationLocked(values, null, false);
18524            Binder.restoreCallingIdentity(origId);
18525        }
18526    }
18527
18528    void updateUserConfigurationLocked() {
18529        Configuration configuration = new Configuration(mConfiguration);
18530        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18531                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18532        updateConfigurationLocked(configuration, null, false);
18533    }
18534
18535    boolean updateConfigurationLocked(Configuration values,
18536            ActivityRecord starting, boolean initLocale) {
18537        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18538        return updateConfigurationLocked(values, starting, initLocale, false,
18539                UserHandle.USER_NULL);
18540    }
18541
18542    // To cache the list of supported system locales
18543    private String[] mSupportedSystemLocales = null;
18544
18545    /**
18546     * Do either or both things: (1) change the current configuration, and (2)
18547     * make sure the given activity is running with the (now) current
18548     * configuration.  Returns true if the activity has been left running, or
18549     * false if <var>starting</var> is being destroyed to match the new
18550     * configuration.
18551     *
18552     * @param userId is only used when persistent parameter is set to true to persist configuration
18553     *               for that particular user
18554     */
18555    private boolean updateConfigurationLocked(Configuration values,
18556            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18557        int changes = 0;
18558
18559        if (mWindowManager != null) {
18560            mWindowManager.deferSurfaceLayout();
18561        }
18562        if (values != null) {
18563            Configuration newConfig = new Configuration(mConfiguration);
18564            changes = newConfig.updateFrom(values);
18565            if (changes != 0) {
18566                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18567                        "Updating configuration to: " + values);
18568
18569                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18570
18571                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18572                    final LocaleList locales = values.getLocales();
18573                    int bestLocaleIndex = 0;
18574                    if (locales.size() > 1) {
18575                        if (mSupportedSystemLocales == null) {
18576                            mSupportedSystemLocales =
18577                                    Resources.getSystem().getAssets().getLocales();
18578                        }
18579                        bestLocaleIndex = Math.max(0,
18580                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18581                    }
18582                    SystemProperties.set("persist.sys.locale",
18583                            locales.get(bestLocaleIndex).toLanguageTag());
18584                    LocaleList.setDefault(locales, bestLocaleIndex);
18585                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18586                            locales.get(bestLocaleIndex)));
18587                }
18588
18589                mConfigurationSeq++;
18590                if (mConfigurationSeq <= 0) {
18591                    mConfigurationSeq = 1;
18592                }
18593                newConfig.seq = mConfigurationSeq;
18594                mConfiguration = newConfig;
18595                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18596                mUsageStatsService.reportConfigurationChange(newConfig,
18597                        mUserController.getCurrentUserIdLocked());
18598                //mUsageStatsService.noteStartConfig(newConfig);
18599
18600                final Configuration configCopy = new Configuration(mConfiguration);
18601
18602                // TODO: If our config changes, should we auto dismiss any currently
18603                // showing dialogs?
18604                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18605
18606                AttributeCache ac = AttributeCache.instance();
18607                if (ac != null) {
18608                    ac.updateConfiguration(configCopy);
18609                }
18610
18611                // Make sure all resources in our process are updated
18612                // right now, so that anyone who is going to retrieve
18613                // resource values after we return will be sure to get
18614                // the new ones.  This is especially important during
18615                // boot, where the first config change needs to guarantee
18616                // all resources have that config before following boot
18617                // code is executed.
18618                mSystemThread.applyConfigurationToResources(configCopy);
18619
18620                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18621                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18622                    msg.obj = new Configuration(configCopy);
18623                    msg.arg1 = userId;
18624                    mHandler.sendMessage(msg);
18625                }
18626
18627                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18628                if (isDensityChange) {
18629                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18630                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18631                }
18632
18633                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18634                    ProcessRecord app = mLruProcesses.get(i);
18635                    try {
18636                        if (app.thread != null) {
18637                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18638                                    + app.processName + " new config " + mConfiguration);
18639                            app.thread.scheduleConfigurationChanged(configCopy);
18640                        }
18641                    } catch (Exception e) {
18642                    }
18643                }
18644                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18645                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18646                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18647                        | Intent.FLAG_RECEIVER_FOREGROUND);
18648                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18649                        null, AppOpsManager.OP_NONE, null, false, false,
18650                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18651                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18652                    // Tell the shortcut manager that the system locale changed.  It needs to know
18653                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18654                    // we "push" from here, rather than having the service listen to the broadcast.
18655                    final ShortcutServiceInternal shortcutService =
18656                            LocalServices.getService(ShortcutServiceInternal.class);
18657                    if (shortcutService != null) {
18658                        shortcutService.onSystemLocaleChangedNoLock();
18659                    }
18660
18661                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18662                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18663                    if (!mProcessesReady) {
18664                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18665                    }
18666                    broadcastIntentLocked(null, null, intent,
18667                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18668                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18669                }
18670            }
18671            // Update the configuration with WM first and check if any of the stacks need to be
18672            // resized due to the configuration change. If so, resize the stacks now and do any
18673            // relaunches if necessary. This way we don't need to relaunch again below in
18674            // ensureActivityConfigurationLocked().
18675            if (mWindowManager != null) {
18676                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18677                if (resizedStacks != null) {
18678                    for (int stackId : resizedStacks) {
18679                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18680                        mStackSupervisor.resizeStackLocked(
18681                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18682                    }
18683                }
18684            }
18685        }
18686
18687        boolean kept = true;
18688        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18689        // mainStack is null during startup.
18690        if (mainStack != null) {
18691            if (changes != 0 && starting == null) {
18692                // If the configuration changed, and the caller is not already
18693                // in the process of starting an activity, then find the top
18694                // activity to check if its configuration needs to change.
18695                starting = mainStack.topRunningActivityLocked();
18696            }
18697
18698            if (starting != null) {
18699                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18700                // And we need to make sure at this point that all other activities
18701                // are made visible with the correct configuration.
18702                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18703                        !PRESERVE_WINDOWS);
18704            }
18705        }
18706        if (mWindowManager != null) {
18707            mWindowManager.continueSurfaceLayout();
18708        }
18709        return kept;
18710    }
18711
18712    /**
18713     * Decide based on the configuration whether we should shouw the ANR,
18714     * crash, etc dialogs.  The idea is that if there is no affordence to
18715     * press the on-screen buttons, or the user experience would be more
18716     * greatly impacted than the crash itself, we shouldn't show the dialog.
18717     *
18718     * A thought: SystemUI might also want to get told about this, the Power
18719     * dialog / global actions also might want different behaviors.
18720     */
18721    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18722        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18723                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18724                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18725        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18726        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18727                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18728        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18729    }
18730
18731    @Override
18732    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18733        synchronized (this) {
18734            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18735            if (srec != null) {
18736                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18737            }
18738        }
18739        return false;
18740    }
18741
18742    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18743            Intent resultData) {
18744
18745        synchronized (this) {
18746            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18747            if (r != null) {
18748                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18749            }
18750            return false;
18751        }
18752    }
18753
18754    public int getLaunchedFromUid(IBinder activityToken) {
18755        ActivityRecord srec;
18756        synchronized (this) {
18757            srec = ActivityRecord.forTokenLocked(activityToken);
18758        }
18759        if (srec == null) {
18760            return -1;
18761        }
18762        return srec.launchedFromUid;
18763    }
18764
18765    public String getLaunchedFromPackage(IBinder activityToken) {
18766        ActivityRecord srec;
18767        synchronized (this) {
18768            srec = ActivityRecord.forTokenLocked(activityToken);
18769        }
18770        if (srec == null) {
18771            return null;
18772        }
18773        return srec.launchedFromPackage;
18774    }
18775
18776    // =========================================================
18777    // LIFETIME MANAGEMENT
18778    // =========================================================
18779
18780    // Returns which broadcast queue the app is the current [or imminent] receiver
18781    // on, or 'null' if the app is not an active broadcast recipient.
18782    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18783        BroadcastRecord r = app.curReceiver;
18784        if (r != null) {
18785            return r.queue;
18786        }
18787
18788        // It's not the current receiver, but it might be starting up to become one
18789        synchronized (this) {
18790            for (BroadcastQueue queue : mBroadcastQueues) {
18791                r = queue.mPendingBroadcast;
18792                if (r != null && r.curApp == app) {
18793                    // found it; report which queue it's in
18794                    return queue;
18795                }
18796            }
18797        }
18798
18799        return null;
18800    }
18801
18802    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18803            int targetUid, ComponentName targetComponent, String targetProcess) {
18804        if (!mTrackingAssociations) {
18805            return null;
18806        }
18807        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18808                = mAssociations.get(targetUid);
18809        if (components == null) {
18810            components = new ArrayMap<>();
18811            mAssociations.put(targetUid, components);
18812        }
18813        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18814        if (sourceUids == null) {
18815            sourceUids = new SparseArray<>();
18816            components.put(targetComponent, sourceUids);
18817        }
18818        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18819        if (sourceProcesses == null) {
18820            sourceProcesses = new ArrayMap<>();
18821            sourceUids.put(sourceUid, sourceProcesses);
18822        }
18823        Association ass = sourceProcesses.get(sourceProcess);
18824        if (ass == null) {
18825            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18826                    targetProcess);
18827            sourceProcesses.put(sourceProcess, ass);
18828        }
18829        ass.mCount++;
18830        ass.mNesting++;
18831        if (ass.mNesting == 1) {
18832            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18833            ass.mLastState = sourceState;
18834        }
18835        return ass;
18836    }
18837
18838    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18839            ComponentName targetComponent) {
18840        if (!mTrackingAssociations) {
18841            return;
18842        }
18843        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18844                = mAssociations.get(targetUid);
18845        if (components == null) {
18846            return;
18847        }
18848        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18849        if (sourceUids == null) {
18850            return;
18851        }
18852        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18853        if (sourceProcesses == null) {
18854            return;
18855        }
18856        Association ass = sourceProcesses.get(sourceProcess);
18857        if (ass == null || ass.mNesting <= 0) {
18858            return;
18859        }
18860        ass.mNesting--;
18861        if (ass.mNesting == 0) {
18862            long uptime = SystemClock.uptimeMillis();
18863            ass.mTime += uptime - ass.mStartTime;
18864            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18865                    += uptime - ass.mLastStateUptime;
18866            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18867        }
18868    }
18869
18870    private void noteUidProcessState(final int uid, final int state) {
18871        mBatteryStatsService.noteUidProcessState(uid, state);
18872        if (mTrackingAssociations) {
18873            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18874                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18875                        = mAssociations.valueAt(i1);
18876                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18877                    SparseArray<ArrayMap<String, Association>> sourceUids
18878                            = targetComponents.valueAt(i2);
18879                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18880                    if (sourceProcesses != null) {
18881                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18882                            Association ass = sourceProcesses.valueAt(i4);
18883                            if (ass.mNesting >= 1) {
18884                                // currently associated
18885                                long uptime = SystemClock.uptimeMillis();
18886                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18887                                        += uptime - ass.mLastStateUptime;
18888                                ass.mLastState = state;
18889                                ass.mLastStateUptime = uptime;
18890                            }
18891                        }
18892                    }
18893                }
18894            }
18895        }
18896    }
18897
18898    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18899            boolean doingAll, long now) {
18900        if (mAdjSeq == app.adjSeq) {
18901            // This adjustment has already been computed.
18902            return app.curRawAdj;
18903        }
18904
18905        if (app.thread == null) {
18906            app.adjSeq = mAdjSeq;
18907            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18908            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18909            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18910        }
18911
18912        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18913        app.adjSource = null;
18914        app.adjTarget = null;
18915        app.empty = false;
18916        app.cached = false;
18917
18918        final int activitiesSize = app.activities.size();
18919
18920        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18921            // The max adjustment doesn't allow this app to be anything
18922            // below foreground, so it is not worth doing work for it.
18923            app.adjType = "fixed";
18924            app.adjSeq = mAdjSeq;
18925            app.curRawAdj = app.maxAdj;
18926            app.foregroundActivities = false;
18927            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18928            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18929            // System processes can do UI, and when they do we want to have
18930            // them trim their memory after the user leaves the UI.  To
18931            // facilitate this, here we need to determine whether or not it
18932            // is currently showing UI.
18933            app.systemNoUi = true;
18934            if (app == TOP_APP) {
18935                app.systemNoUi = false;
18936                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18937                app.adjType = "pers-top-activity";
18938            } else if (activitiesSize > 0) {
18939                for (int j = 0; j < activitiesSize; j++) {
18940                    final ActivityRecord r = app.activities.get(j);
18941                    if (r.visible) {
18942                        app.systemNoUi = false;
18943                    }
18944                }
18945            }
18946            if (!app.systemNoUi) {
18947                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18948            }
18949            return (app.curAdj=app.maxAdj);
18950        }
18951
18952        app.systemNoUi = false;
18953
18954        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18955
18956        // Determine the importance of the process, starting with most
18957        // important to least, and assign an appropriate OOM adjustment.
18958        int adj;
18959        int schedGroup;
18960        int procState;
18961        boolean foregroundActivities = false;
18962        BroadcastQueue queue;
18963        if (app == TOP_APP) {
18964            // The last app on the list is the foreground app.
18965            adj = ProcessList.FOREGROUND_APP_ADJ;
18966            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18967            app.adjType = "top-activity";
18968            foregroundActivities = true;
18969            procState = PROCESS_STATE_CUR_TOP;
18970        } else if (app.instrumentationClass != null) {
18971            // Don't want to kill running instrumentation.
18972            adj = ProcessList.FOREGROUND_APP_ADJ;
18973            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18974            app.adjType = "instrumentation";
18975            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18976        } else if ((queue = isReceivingBroadcast(app)) != null) {
18977            // An app that is currently receiving a broadcast also
18978            // counts as being in the foreground for OOM killer purposes.
18979            // It's placed in a sched group based on the nature of the
18980            // broadcast as reflected by which queue it's active in.
18981            adj = ProcessList.FOREGROUND_APP_ADJ;
18982            schedGroup = (queue == mFgBroadcastQueue)
18983                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18984            app.adjType = "broadcast";
18985            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18986        } else if (app.executingServices.size() > 0) {
18987            // An app that is currently executing a service callback also
18988            // counts as being in the foreground.
18989            adj = ProcessList.FOREGROUND_APP_ADJ;
18990            schedGroup = app.execServicesFg ?
18991                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18992            app.adjType = "exec-service";
18993            procState = ActivityManager.PROCESS_STATE_SERVICE;
18994            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18995        } else {
18996            // As far as we know the process is empty.  We may change our mind later.
18997            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18998            // At this point we don't actually know the adjustment.  Use the cached adj
18999            // value that the caller wants us to.
19000            adj = cachedAdj;
19001            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19002            app.cached = true;
19003            app.empty = true;
19004            app.adjType = "cch-empty";
19005        }
19006
19007        // Examine all activities if not already foreground.
19008        if (!foregroundActivities && activitiesSize > 0) {
19009            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19010            for (int j = 0; j < activitiesSize; j++) {
19011                final ActivityRecord r = app.activities.get(j);
19012                if (r.app != app) {
19013                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19014                            + " instead of expected " + app);
19015                    if (r.app == null || (r.app.uid == app.uid)) {
19016                        // Only fix things up when they look sane
19017                        r.app = app;
19018                    } else {
19019                        continue;
19020                    }
19021                }
19022                if (r.visible) {
19023                    // App has a visible activity; only upgrade adjustment.
19024                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19025                        adj = ProcessList.VISIBLE_APP_ADJ;
19026                        app.adjType = "visible";
19027                    }
19028                    if (procState > PROCESS_STATE_CUR_TOP) {
19029                        procState = PROCESS_STATE_CUR_TOP;
19030                    }
19031                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19032                    app.cached = false;
19033                    app.empty = false;
19034                    foregroundActivities = true;
19035                    if (r.task != null && minLayer > 0) {
19036                        final int layer = r.task.mLayerRank;
19037                        if (layer >= 0 && minLayer > layer) {
19038                            minLayer = layer;
19039                        }
19040                    }
19041                    break;
19042                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19043                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19044                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19045                        app.adjType = "pausing";
19046                    }
19047                    if (procState > PROCESS_STATE_CUR_TOP) {
19048                        procState = PROCESS_STATE_CUR_TOP;
19049                    }
19050                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19051                    app.cached = false;
19052                    app.empty = false;
19053                    foregroundActivities = true;
19054                } else if (r.state == ActivityState.STOPPING) {
19055                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19056                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19057                        app.adjType = "stopping";
19058                    }
19059                    // For the process state, we will at this point consider the
19060                    // process to be cached.  It will be cached either as an activity
19061                    // or empty depending on whether the activity is finishing.  We do
19062                    // this so that we can treat the process as cached for purposes of
19063                    // memory trimming (determing current memory level, trim command to
19064                    // send to process) since there can be an arbitrary number of stopping
19065                    // processes and they should soon all go into the cached state.
19066                    if (!r.finishing) {
19067                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19068                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19069                        }
19070                    }
19071                    app.cached = false;
19072                    app.empty = false;
19073                    foregroundActivities = true;
19074                } else {
19075                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19076                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19077                        app.adjType = "cch-act";
19078                    }
19079                }
19080            }
19081            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19082                adj += minLayer;
19083            }
19084        }
19085
19086        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19087                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19088            if (app.foregroundServices) {
19089                // The user is aware of this app, so make it visible.
19090                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19091                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19092                app.cached = false;
19093                app.adjType = "fg-service";
19094                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19095            } else if (app.forcingToForeground != null) {
19096                // The user is aware of this app, so make it visible.
19097                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19098                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19099                app.cached = false;
19100                app.adjType = "force-fg";
19101                app.adjSource = app.forcingToForeground;
19102                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19103            }
19104        }
19105
19106        if (app == mHeavyWeightProcess) {
19107            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19108                // We don't want to kill the current heavy-weight process.
19109                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19110                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19111                app.cached = false;
19112                app.adjType = "heavy";
19113            }
19114            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19115                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19116            }
19117        }
19118
19119        if (app == mHomeProcess) {
19120            if (adj > ProcessList.HOME_APP_ADJ) {
19121                // This process is hosting what we currently consider to be the
19122                // home app, so we don't want to let it go into the background.
19123                adj = ProcessList.HOME_APP_ADJ;
19124                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19125                app.cached = false;
19126                app.adjType = "home";
19127            }
19128            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19129                procState = ActivityManager.PROCESS_STATE_HOME;
19130            }
19131        }
19132
19133        if (app == mPreviousProcess && app.activities.size() > 0) {
19134            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19135                // This was the previous process that showed UI to the user.
19136                // We want to try to keep it around more aggressively, to give
19137                // a good experience around switching between two apps.
19138                adj = ProcessList.PREVIOUS_APP_ADJ;
19139                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19140                app.cached = false;
19141                app.adjType = "previous";
19142            }
19143            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19144                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19145            }
19146        }
19147
19148        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19149                + " reason=" + app.adjType);
19150
19151        // By default, we use the computed adjustment.  It may be changed if
19152        // there are applications dependent on our services or providers, but
19153        // this gives us a baseline and makes sure we don't get into an
19154        // infinite recursion.
19155        app.adjSeq = mAdjSeq;
19156        app.curRawAdj = adj;
19157        app.hasStartedServices = false;
19158
19159        if (mBackupTarget != null && app == mBackupTarget.app) {
19160            // If possible we want to avoid killing apps while they're being backed up
19161            if (adj > ProcessList.BACKUP_APP_ADJ) {
19162                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19163                adj = ProcessList.BACKUP_APP_ADJ;
19164                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19165                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19166                }
19167                app.adjType = "backup";
19168                app.cached = false;
19169            }
19170            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19171                procState = ActivityManager.PROCESS_STATE_BACKUP;
19172            }
19173        }
19174
19175        boolean mayBeTop = false;
19176
19177        for (int is = app.services.size()-1;
19178                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19179                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19180                        || procState > ActivityManager.PROCESS_STATE_TOP);
19181                is--) {
19182            ServiceRecord s = app.services.valueAt(is);
19183            if (s.startRequested) {
19184                app.hasStartedServices = true;
19185                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19186                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19187                }
19188                if (app.hasShownUi && app != mHomeProcess) {
19189                    // If this process has shown some UI, let it immediately
19190                    // go to the LRU list because it may be pretty heavy with
19191                    // UI stuff.  We'll tag it with a label just to help
19192                    // debug and understand what is going on.
19193                    if (adj > ProcessList.SERVICE_ADJ) {
19194                        app.adjType = "cch-started-ui-services";
19195                    }
19196                } else {
19197                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19198                        // This service has seen some activity within
19199                        // recent memory, so we will keep its process ahead
19200                        // of the background processes.
19201                        if (adj > ProcessList.SERVICE_ADJ) {
19202                            adj = ProcessList.SERVICE_ADJ;
19203                            app.adjType = "started-services";
19204                            app.cached = false;
19205                        }
19206                    }
19207                    // If we have let the service slide into the background
19208                    // state, still have some text describing what it is doing
19209                    // even though the service no longer has an impact.
19210                    if (adj > ProcessList.SERVICE_ADJ) {
19211                        app.adjType = "cch-started-services";
19212                    }
19213                }
19214            }
19215
19216            app.whitelistManager = false;
19217
19218            for (int conni = s.connections.size()-1;
19219                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19220                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19221                            || procState > ActivityManager.PROCESS_STATE_TOP);
19222                    conni--) {
19223                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19224                for (int i = 0;
19225                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19226                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19227                                || procState > ActivityManager.PROCESS_STATE_TOP);
19228                        i++) {
19229                    // XXX should compute this based on the max of
19230                    // all connected clients.
19231                    ConnectionRecord cr = clist.get(i);
19232                    if (cr.binding.client == app) {
19233                        // Binding to ourself is not interesting.
19234                        continue;
19235                    }
19236                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19237                        app.whitelistManager = true;
19238                    }
19239
19240                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19241                        ProcessRecord client = cr.binding.client;
19242                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19243                                TOP_APP, doingAll, now);
19244                        int clientProcState = client.curProcState;
19245                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19246                            // If the other app is cached for any reason, for purposes here
19247                            // we are going to consider it empty.  The specific cached state
19248                            // doesn't propagate except under certain conditions.
19249                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19250                        }
19251                        String adjType = null;
19252                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19253                            // Not doing bind OOM management, so treat
19254                            // this guy more like a started service.
19255                            if (app.hasShownUi && app != mHomeProcess) {
19256                                // If this process has shown some UI, let it immediately
19257                                // go to the LRU list because it may be pretty heavy with
19258                                // UI stuff.  We'll tag it with a label just to help
19259                                // debug and understand what is going on.
19260                                if (adj > clientAdj) {
19261                                    adjType = "cch-bound-ui-services";
19262                                }
19263                                app.cached = false;
19264                                clientAdj = adj;
19265                                clientProcState = procState;
19266                            } else {
19267                                if (now >= (s.lastActivity
19268                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19269                                    // This service has not seen activity within
19270                                    // recent memory, so allow it to drop to the
19271                                    // LRU list if there is no other reason to keep
19272                                    // it around.  We'll also tag it with a label just
19273                                    // to help debug and undertand what is going on.
19274                                    if (adj > clientAdj) {
19275                                        adjType = "cch-bound-services";
19276                                    }
19277                                    clientAdj = adj;
19278                                }
19279                            }
19280                        }
19281                        if (adj > clientAdj) {
19282                            // If this process has recently shown UI, and
19283                            // the process that is binding to it is less
19284                            // important than being visible, then we don't
19285                            // care about the binding as much as we care
19286                            // about letting this process get into the LRU
19287                            // list to be killed and restarted if needed for
19288                            // memory.
19289                            if (app.hasShownUi && app != mHomeProcess
19290                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19291                                adjType = "cch-bound-ui-services";
19292                            } else {
19293                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19294                                        |Context.BIND_IMPORTANT)) != 0) {
19295                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19296                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19297                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19298                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19299                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19300                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19301                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19302                                    adj = clientAdj;
19303                                } else {
19304                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19305                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19306                                    }
19307                                }
19308                                if (!client.cached) {
19309                                    app.cached = false;
19310                                }
19311                                adjType = "service";
19312                            }
19313                        }
19314                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19315                            // This will treat important bound services identically to
19316                            // the top app, which may behave differently than generic
19317                            // foreground work.
19318                            if (client.curSchedGroup > schedGroup) {
19319                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19320                                    schedGroup = client.curSchedGroup;
19321                                } else {
19322                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19323                                }
19324                            }
19325                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19326                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19327                                    // Special handling of clients who are in the top state.
19328                                    // We *may* want to consider this process to be in the
19329                                    // top state as well, but only if there is not another
19330                                    // reason for it to be running.  Being on the top is a
19331                                    // special state, meaning you are specifically running
19332                                    // for the current top app.  If the process is already
19333                                    // running in the background for some other reason, it
19334                                    // is more important to continue considering it to be
19335                                    // in the background state.
19336                                    mayBeTop = true;
19337                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19338                                } else {
19339                                    // Special handling for above-top states (persistent
19340                                    // processes).  These should not bring the current process
19341                                    // into the top state, since they are not on top.  Instead
19342                                    // give them the best state after that.
19343                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19344                                        clientProcState =
19345                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19346                                    } else if (mWakefulness
19347                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19348                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19349                                                    != 0) {
19350                                        clientProcState =
19351                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19352                                    } else {
19353                                        clientProcState =
19354                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19355                                    }
19356                                }
19357                            }
19358                        } else {
19359                            if (clientProcState <
19360                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19361                                clientProcState =
19362                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19363                            }
19364                        }
19365                        if (procState > clientProcState) {
19366                            procState = clientProcState;
19367                        }
19368                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19369                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19370                            app.pendingUiClean = true;
19371                        }
19372                        if (adjType != null) {
19373                            app.adjType = adjType;
19374                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19375                                    .REASON_SERVICE_IN_USE;
19376                            app.adjSource = cr.binding.client;
19377                            app.adjSourceProcState = clientProcState;
19378                            app.adjTarget = s.name;
19379                        }
19380                    }
19381                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19382                        app.treatLikeActivity = true;
19383                    }
19384                    final ActivityRecord a = cr.activity;
19385                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19386                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19387                            (a.visible || a.state == ActivityState.RESUMED ||
19388                             a.state == ActivityState.PAUSING)) {
19389                            adj = ProcessList.FOREGROUND_APP_ADJ;
19390                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19391                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19392                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19393                                } else {
19394                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19395                                }
19396                            }
19397                            app.cached = false;
19398                            app.adjType = "service";
19399                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19400                                    .REASON_SERVICE_IN_USE;
19401                            app.adjSource = a;
19402                            app.adjSourceProcState = procState;
19403                            app.adjTarget = s.name;
19404                        }
19405                    }
19406                }
19407            }
19408        }
19409
19410        for (int provi = app.pubProviders.size()-1;
19411                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19412                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19413                        || procState > ActivityManager.PROCESS_STATE_TOP);
19414                provi--) {
19415            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19416            for (int i = cpr.connections.size()-1;
19417                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19418                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19419                            || procState > ActivityManager.PROCESS_STATE_TOP);
19420                    i--) {
19421                ContentProviderConnection conn = cpr.connections.get(i);
19422                ProcessRecord client = conn.client;
19423                if (client == app) {
19424                    // Being our own client is not interesting.
19425                    continue;
19426                }
19427                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19428                int clientProcState = client.curProcState;
19429                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19430                    // If the other app is cached for any reason, for purposes here
19431                    // we are going to consider it empty.
19432                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19433                }
19434                if (adj > clientAdj) {
19435                    if (app.hasShownUi && app != mHomeProcess
19436                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19437                        app.adjType = "cch-ui-provider";
19438                    } else {
19439                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19440                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19441                        app.adjType = "provider";
19442                    }
19443                    app.cached &= client.cached;
19444                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19445                            .REASON_PROVIDER_IN_USE;
19446                    app.adjSource = client;
19447                    app.adjSourceProcState = clientProcState;
19448                    app.adjTarget = cpr.name;
19449                }
19450                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19451                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19452                        // Special handling of clients who are in the top state.
19453                        // We *may* want to consider this process to be in the
19454                        // top state as well, but only if there is not another
19455                        // reason for it to be running.  Being on the top is a
19456                        // special state, meaning you are specifically running
19457                        // for the current top app.  If the process is already
19458                        // running in the background for some other reason, it
19459                        // is more important to continue considering it to be
19460                        // in the background state.
19461                        mayBeTop = true;
19462                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19463                    } else {
19464                        // Special handling for above-top states (persistent
19465                        // processes).  These should not bring the current process
19466                        // into the top state, since they are not on top.  Instead
19467                        // give them the best state after that.
19468                        clientProcState =
19469                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19470                    }
19471                }
19472                if (procState > clientProcState) {
19473                    procState = clientProcState;
19474                }
19475                if (client.curSchedGroup > schedGroup) {
19476                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19477                }
19478            }
19479            // If the provider has external (non-framework) process
19480            // dependencies, ensure that its adjustment is at least
19481            // FOREGROUND_APP_ADJ.
19482            if (cpr.hasExternalProcessHandles()) {
19483                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19484                    adj = ProcessList.FOREGROUND_APP_ADJ;
19485                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19486                    app.cached = false;
19487                    app.adjType = "provider";
19488                    app.adjTarget = cpr.name;
19489                }
19490                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19491                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19492                }
19493            }
19494        }
19495
19496        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19497            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19498                adj = ProcessList.PREVIOUS_APP_ADJ;
19499                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19500                app.cached = false;
19501                app.adjType = "provider";
19502            }
19503            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19504                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19505            }
19506        }
19507
19508        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19509            // A client of one of our services or providers is in the top state.  We
19510            // *may* want to be in the top state, but not if we are already running in
19511            // the background for some other reason.  For the decision here, we are going
19512            // to pick out a few specific states that we want to remain in when a client
19513            // is top (states that tend to be longer-term) and otherwise allow it to go
19514            // to the top state.
19515            switch (procState) {
19516                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19517                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19518                case ActivityManager.PROCESS_STATE_SERVICE:
19519                    // These all are longer-term states, so pull them up to the top
19520                    // of the background states, but not all the way to the top state.
19521                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19522                    break;
19523                default:
19524                    // Otherwise, top is a better choice, so take it.
19525                    procState = ActivityManager.PROCESS_STATE_TOP;
19526                    break;
19527            }
19528        }
19529
19530        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19531            if (app.hasClientActivities) {
19532                // This is a cached process, but with client activities.  Mark it so.
19533                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19534                app.adjType = "cch-client-act";
19535            } else if (app.treatLikeActivity) {
19536                // This is a cached process, but somebody wants us to treat it like it has
19537                // an activity, okay!
19538                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19539                app.adjType = "cch-as-act";
19540            }
19541        }
19542
19543        if (adj == ProcessList.SERVICE_ADJ) {
19544            if (doingAll) {
19545                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19546                mNewNumServiceProcs++;
19547                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19548                if (!app.serviceb) {
19549                    // This service isn't far enough down on the LRU list to
19550                    // normally be a B service, but if we are low on RAM and it
19551                    // is large we want to force it down since we would prefer to
19552                    // keep launcher over it.
19553                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19554                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19555                        app.serviceHighRam = true;
19556                        app.serviceb = true;
19557                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19558                    } else {
19559                        mNewNumAServiceProcs++;
19560                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19561                    }
19562                } else {
19563                    app.serviceHighRam = false;
19564                }
19565            }
19566            if (app.serviceb) {
19567                adj = ProcessList.SERVICE_B_ADJ;
19568            }
19569        }
19570
19571        app.curRawAdj = adj;
19572
19573        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19574        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19575        if (adj > app.maxAdj) {
19576            adj = app.maxAdj;
19577            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19578                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19579            }
19580        }
19581
19582        // Do final modification to adj.  Everything we do between here and applying
19583        // the final setAdj must be done in this function, because we will also use
19584        // it when computing the final cached adj later.  Note that we don't need to
19585        // worry about this for max adj above, since max adj will always be used to
19586        // keep it out of the cached vaues.
19587        app.curAdj = app.modifyRawOomAdj(adj);
19588        app.curSchedGroup = schedGroup;
19589        app.curProcState = procState;
19590        app.foregroundActivities = foregroundActivities;
19591
19592        return app.curRawAdj;
19593    }
19594
19595    /**
19596     * Record new PSS sample for a process.
19597     */
19598    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19599            long now) {
19600        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19601                swapPss * 1024);
19602        proc.lastPssTime = now;
19603        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19604        if (DEBUG_PSS) Slog.d(TAG_PSS,
19605                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19606                + " state=" + ProcessList.makeProcStateString(procState));
19607        if (proc.initialIdlePss == 0) {
19608            proc.initialIdlePss = pss;
19609        }
19610        proc.lastPss = pss;
19611        proc.lastSwapPss = swapPss;
19612        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19613            proc.lastCachedPss = pss;
19614            proc.lastCachedSwapPss = swapPss;
19615        }
19616
19617        final SparseArray<Pair<Long, String>> watchUids
19618                = mMemWatchProcesses.getMap().get(proc.processName);
19619        Long check = null;
19620        if (watchUids != null) {
19621            Pair<Long, String> val = watchUids.get(proc.uid);
19622            if (val == null) {
19623                val = watchUids.get(0);
19624            }
19625            if (val != null) {
19626                check = val.first;
19627            }
19628        }
19629        if (check != null) {
19630            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19631                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19632                if (!isDebuggable) {
19633                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19634                        isDebuggable = true;
19635                    }
19636                }
19637                if (isDebuggable) {
19638                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19639                    final ProcessRecord myProc = proc;
19640                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19641                    mMemWatchDumpProcName = proc.processName;
19642                    mMemWatchDumpFile = heapdumpFile.toString();
19643                    mMemWatchDumpPid = proc.pid;
19644                    mMemWatchDumpUid = proc.uid;
19645                    BackgroundThread.getHandler().post(new Runnable() {
19646                        @Override
19647                        public void run() {
19648                            revokeUriPermission(ActivityThread.currentActivityThread()
19649                                            .getApplicationThread(),
19650                                    DumpHeapActivity.JAVA_URI,
19651                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19652                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19653                                    UserHandle.myUserId());
19654                            ParcelFileDescriptor fd = null;
19655                            try {
19656                                heapdumpFile.delete();
19657                                fd = ParcelFileDescriptor.open(heapdumpFile,
19658                                        ParcelFileDescriptor.MODE_CREATE |
19659                                                ParcelFileDescriptor.MODE_TRUNCATE |
19660                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19661                                                ParcelFileDescriptor.MODE_APPEND);
19662                                IApplicationThread thread = myProc.thread;
19663                                if (thread != null) {
19664                                    try {
19665                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19666                                                "Requesting dump heap from "
19667                                                + myProc + " to " + heapdumpFile);
19668                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19669                                    } catch (RemoteException e) {
19670                                    }
19671                                }
19672                            } catch (FileNotFoundException e) {
19673                                e.printStackTrace();
19674                            } finally {
19675                                if (fd != null) {
19676                                    try {
19677                                        fd.close();
19678                                    } catch (IOException e) {
19679                                    }
19680                                }
19681                            }
19682                        }
19683                    });
19684                } else {
19685                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19686                            + ", but debugging not enabled");
19687                }
19688            }
19689        }
19690    }
19691
19692    /**
19693     * Schedule PSS collection of a process.
19694     */
19695    void requestPssLocked(ProcessRecord proc, int procState) {
19696        if (mPendingPssProcesses.contains(proc)) {
19697            return;
19698        }
19699        if (mPendingPssProcesses.size() == 0) {
19700            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19701        }
19702        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19703        proc.pssProcState = procState;
19704        mPendingPssProcesses.add(proc);
19705    }
19706
19707    /**
19708     * Schedule PSS collection of all processes.
19709     */
19710    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19711        if (!always) {
19712            if (now < (mLastFullPssTime +
19713                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19714                return;
19715            }
19716        }
19717        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19718        mLastFullPssTime = now;
19719        mFullPssPending = true;
19720        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19721        mPendingPssProcesses.clear();
19722        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19723            ProcessRecord app = mLruProcesses.get(i);
19724            if (app.thread == null
19725                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19726                continue;
19727            }
19728            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19729                app.pssProcState = app.setProcState;
19730                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19731                        mTestPssMode, isSleeping(), now);
19732                mPendingPssProcesses.add(app);
19733            }
19734        }
19735        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19736    }
19737
19738    public void setTestPssMode(boolean enabled) {
19739        synchronized (this) {
19740            mTestPssMode = enabled;
19741            if (enabled) {
19742                // Whenever we enable the mode, we want to take a snapshot all of current
19743                // process mem use.
19744                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19745            }
19746        }
19747    }
19748
19749    /**
19750     * Ask a given process to GC right now.
19751     */
19752    final void performAppGcLocked(ProcessRecord app) {
19753        try {
19754            app.lastRequestedGc = SystemClock.uptimeMillis();
19755            if (app.thread != null) {
19756                if (app.reportLowMemory) {
19757                    app.reportLowMemory = false;
19758                    app.thread.scheduleLowMemory();
19759                } else {
19760                    app.thread.processInBackground();
19761                }
19762            }
19763        } catch (Exception e) {
19764            // whatever.
19765        }
19766    }
19767
19768    /**
19769     * Returns true if things are idle enough to perform GCs.
19770     */
19771    private final boolean canGcNowLocked() {
19772        boolean processingBroadcasts = false;
19773        for (BroadcastQueue q : mBroadcastQueues) {
19774            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19775                processingBroadcasts = true;
19776            }
19777        }
19778        return !processingBroadcasts
19779                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19780    }
19781
19782    /**
19783     * Perform GCs on all processes that are waiting for it, but only
19784     * if things are idle.
19785     */
19786    final void performAppGcsLocked() {
19787        final int N = mProcessesToGc.size();
19788        if (N <= 0) {
19789            return;
19790        }
19791        if (canGcNowLocked()) {
19792            while (mProcessesToGc.size() > 0) {
19793                ProcessRecord proc = mProcessesToGc.remove(0);
19794                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19795                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19796                            <= SystemClock.uptimeMillis()) {
19797                        // To avoid spamming the system, we will GC processes one
19798                        // at a time, waiting a few seconds between each.
19799                        performAppGcLocked(proc);
19800                        scheduleAppGcsLocked();
19801                        return;
19802                    } else {
19803                        // It hasn't been long enough since we last GCed this
19804                        // process...  put it in the list to wait for its time.
19805                        addProcessToGcListLocked(proc);
19806                        break;
19807                    }
19808                }
19809            }
19810
19811            scheduleAppGcsLocked();
19812        }
19813    }
19814
19815    /**
19816     * If all looks good, perform GCs on all processes waiting for them.
19817     */
19818    final void performAppGcsIfAppropriateLocked() {
19819        if (canGcNowLocked()) {
19820            performAppGcsLocked();
19821            return;
19822        }
19823        // Still not idle, wait some more.
19824        scheduleAppGcsLocked();
19825    }
19826
19827    /**
19828     * Schedule the execution of all pending app GCs.
19829     */
19830    final void scheduleAppGcsLocked() {
19831        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19832
19833        if (mProcessesToGc.size() > 0) {
19834            // Schedule a GC for the time to the next process.
19835            ProcessRecord proc = mProcessesToGc.get(0);
19836            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19837
19838            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19839            long now = SystemClock.uptimeMillis();
19840            if (when < (now+GC_TIMEOUT)) {
19841                when = now + GC_TIMEOUT;
19842            }
19843            mHandler.sendMessageAtTime(msg, when);
19844        }
19845    }
19846
19847    /**
19848     * Add a process to the array of processes waiting to be GCed.  Keeps the
19849     * list in sorted order by the last GC time.  The process can't already be
19850     * on the list.
19851     */
19852    final void addProcessToGcListLocked(ProcessRecord proc) {
19853        boolean added = false;
19854        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19855            if (mProcessesToGc.get(i).lastRequestedGc <
19856                    proc.lastRequestedGc) {
19857                added = true;
19858                mProcessesToGc.add(i+1, proc);
19859                break;
19860            }
19861        }
19862        if (!added) {
19863            mProcessesToGc.add(0, proc);
19864        }
19865    }
19866
19867    /**
19868     * Set up to ask a process to GC itself.  This will either do it
19869     * immediately, or put it on the list of processes to gc the next
19870     * time things are idle.
19871     */
19872    final void scheduleAppGcLocked(ProcessRecord app) {
19873        long now = SystemClock.uptimeMillis();
19874        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19875            return;
19876        }
19877        if (!mProcessesToGc.contains(app)) {
19878            addProcessToGcListLocked(app);
19879            scheduleAppGcsLocked();
19880        }
19881    }
19882
19883    final void checkExcessivePowerUsageLocked(boolean doKills) {
19884        updateCpuStatsNow();
19885
19886        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19887        boolean doWakeKills = doKills;
19888        boolean doCpuKills = doKills;
19889        if (mLastPowerCheckRealtime == 0) {
19890            doWakeKills = false;
19891        }
19892        if (mLastPowerCheckUptime == 0) {
19893            doCpuKills = false;
19894        }
19895        if (stats.isScreenOn()) {
19896            doWakeKills = false;
19897        }
19898        final long curRealtime = SystemClock.elapsedRealtime();
19899        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19900        final long curUptime = SystemClock.uptimeMillis();
19901        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19902        mLastPowerCheckRealtime = curRealtime;
19903        mLastPowerCheckUptime = curUptime;
19904        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19905            doWakeKills = false;
19906        }
19907        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19908            doCpuKills = false;
19909        }
19910        int i = mLruProcesses.size();
19911        while (i > 0) {
19912            i--;
19913            ProcessRecord app = mLruProcesses.get(i);
19914            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19915                long wtime;
19916                synchronized (stats) {
19917                    wtime = stats.getProcessWakeTime(app.info.uid,
19918                            app.pid, curRealtime);
19919                }
19920                long wtimeUsed = wtime - app.lastWakeTime;
19921                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19922                if (DEBUG_POWER) {
19923                    StringBuilder sb = new StringBuilder(128);
19924                    sb.append("Wake for ");
19925                    app.toShortString(sb);
19926                    sb.append(": over ");
19927                    TimeUtils.formatDuration(realtimeSince, sb);
19928                    sb.append(" used ");
19929                    TimeUtils.formatDuration(wtimeUsed, sb);
19930                    sb.append(" (");
19931                    sb.append((wtimeUsed*100)/realtimeSince);
19932                    sb.append("%)");
19933                    Slog.i(TAG_POWER, sb.toString());
19934                    sb.setLength(0);
19935                    sb.append("CPU for ");
19936                    app.toShortString(sb);
19937                    sb.append(": over ");
19938                    TimeUtils.formatDuration(uptimeSince, sb);
19939                    sb.append(" used ");
19940                    TimeUtils.formatDuration(cputimeUsed, sb);
19941                    sb.append(" (");
19942                    sb.append((cputimeUsed*100)/uptimeSince);
19943                    sb.append("%)");
19944                    Slog.i(TAG_POWER, sb.toString());
19945                }
19946                // If a process has held a wake lock for more
19947                // than 50% of the time during this period,
19948                // that sounds bad.  Kill!
19949                if (doWakeKills && realtimeSince > 0
19950                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19951                    synchronized (stats) {
19952                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19953                                realtimeSince, wtimeUsed);
19954                    }
19955                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19956                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19957                } else if (doCpuKills && uptimeSince > 0
19958                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19959                    synchronized (stats) {
19960                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19961                                uptimeSince, cputimeUsed);
19962                    }
19963                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19964                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19965                } else {
19966                    app.lastWakeTime = wtime;
19967                    app.lastCpuTime = app.curCpuTime;
19968                }
19969            }
19970        }
19971    }
19972
19973    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19974            long nowElapsed) {
19975        boolean success = true;
19976
19977        if (app.curRawAdj != app.setRawAdj) {
19978            app.setRawAdj = app.curRawAdj;
19979        }
19980
19981        int changes = 0;
19982
19983        if (app.curAdj != app.setAdj) {
19984            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19985            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19986                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19987                    + app.adjType);
19988            app.setAdj = app.curAdj;
19989        }
19990
19991        if (app.setSchedGroup != app.curSchedGroup) {
19992            app.setSchedGroup = app.curSchedGroup;
19993            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19994                    "Setting sched group of " + app.processName
19995                    + " to " + app.curSchedGroup);
19996            if (app.waitingToKill != null && app.curReceiver == null
19997                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19998                app.kill(app.waitingToKill, true);
19999                success = false;
20000            } else {
20001                int processGroup;
20002                switch (app.curSchedGroup) {
20003                    case ProcessList.SCHED_GROUP_BACKGROUND:
20004                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20005                        break;
20006                    case ProcessList.SCHED_GROUP_TOP_APP:
20007                        processGroup = Process.THREAD_GROUP_TOP_APP;
20008                        break;
20009                    default:
20010                        processGroup = Process.THREAD_GROUP_DEFAULT;
20011                        break;
20012                }
20013                if (true) {
20014                    long oldId = Binder.clearCallingIdentity();
20015                    try {
20016                        Process.setProcessGroup(app.pid, processGroup);
20017                    } catch (Exception e) {
20018                        Slog.w(TAG, "Failed setting process group of " + app.pid
20019                                + " to " + app.curSchedGroup);
20020                        e.printStackTrace();
20021                    } finally {
20022                        Binder.restoreCallingIdentity(oldId);
20023                    }
20024                } else {
20025                    if (app.thread != null) {
20026                        try {
20027                            app.thread.setSchedulingGroup(processGroup);
20028                        } catch (RemoteException e) {
20029                        }
20030                    }
20031                }
20032            }
20033        }
20034        if (app.repForegroundActivities != app.foregroundActivities) {
20035            app.repForegroundActivities = app.foregroundActivities;
20036            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20037        }
20038        if (app.repProcState != app.curProcState) {
20039            app.repProcState = app.curProcState;
20040            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20041            if (app.thread != null) {
20042                try {
20043                    if (false) {
20044                        //RuntimeException h = new RuntimeException("here");
20045                        Slog.i(TAG, "Sending new process state " + app.repProcState
20046                                + " to " + app /*, h*/);
20047                    }
20048                    app.thread.setProcessState(app.repProcState);
20049                } catch (RemoteException e) {
20050                }
20051            }
20052        }
20053        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20054                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20055            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20056                // Experimental code to more aggressively collect pss while
20057                // running test...  the problem is that this tends to collect
20058                // the data right when a process is transitioning between process
20059                // states, which well tend to give noisy data.
20060                long start = SystemClock.uptimeMillis();
20061                long pss = Debug.getPss(app.pid, mTmpLong, null);
20062                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20063                mPendingPssProcesses.remove(app);
20064                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20065                        + " to " + app.curProcState + ": "
20066                        + (SystemClock.uptimeMillis()-start) + "ms");
20067            }
20068            app.lastStateTime = now;
20069            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20070                    mTestPssMode, isSleeping(), now);
20071            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20072                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20073                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20074                    + (app.nextPssTime-now) + ": " + app);
20075        } else {
20076            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20077                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20078                    mTestPssMode)))) {
20079                requestPssLocked(app, app.setProcState);
20080                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20081                        mTestPssMode, isSleeping(), now);
20082            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20083                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20084        }
20085        if (app.setProcState != app.curProcState) {
20086            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20087                    "Proc state change of " + app.processName
20088                            + " to " + app.curProcState);
20089            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20090            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20091            if (setImportant && !curImportant) {
20092                // This app is no longer something we consider important enough to allow to
20093                // use arbitrary amounts of battery power.  Note
20094                // its current wake lock time to later know to kill it if
20095                // it is not behaving well.
20096                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20097                synchronized (stats) {
20098                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20099                            app.pid, nowElapsed);
20100                }
20101                app.lastCpuTime = app.curCpuTime;
20102
20103            }
20104            // Inform UsageStats of important process state change
20105            // Must be called before updating setProcState
20106            maybeUpdateUsageStatsLocked(app, nowElapsed);
20107
20108            app.setProcState = app.curProcState;
20109            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20110                app.notCachedSinceIdle = false;
20111            }
20112            if (!doingAll) {
20113                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20114            } else {
20115                app.procStateChanged = true;
20116            }
20117        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20118                > USAGE_STATS_INTERACTION_INTERVAL) {
20119            // For apps that sit around for a long time in the interactive state, we need
20120            // to report this at least once a day so they don't go idle.
20121            maybeUpdateUsageStatsLocked(app, nowElapsed);
20122        }
20123
20124        if (changes != 0) {
20125            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20126                    "Changes in " + app + ": " + changes);
20127            int i = mPendingProcessChanges.size()-1;
20128            ProcessChangeItem item = null;
20129            while (i >= 0) {
20130                item = mPendingProcessChanges.get(i);
20131                if (item.pid == app.pid) {
20132                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20133                            "Re-using existing item: " + item);
20134                    break;
20135                }
20136                i--;
20137            }
20138            if (i < 0) {
20139                // No existing item in pending changes; need a new one.
20140                final int NA = mAvailProcessChanges.size();
20141                if (NA > 0) {
20142                    item = mAvailProcessChanges.remove(NA-1);
20143                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20144                            "Retrieving available item: " + item);
20145                } else {
20146                    item = new ProcessChangeItem();
20147                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20148                            "Allocating new item: " + item);
20149                }
20150                item.changes = 0;
20151                item.pid = app.pid;
20152                item.uid = app.info.uid;
20153                if (mPendingProcessChanges.size() == 0) {
20154                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20155                            "*** Enqueueing dispatch processes changed!");
20156                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20157                }
20158                mPendingProcessChanges.add(item);
20159            }
20160            item.changes |= changes;
20161            item.processState = app.repProcState;
20162            item.foregroundActivities = app.repForegroundActivities;
20163            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20164                    "Item " + Integer.toHexString(System.identityHashCode(item))
20165                    + " " + app.toShortString() + ": changes=" + item.changes
20166                    + " procState=" + item.processState
20167                    + " foreground=" + item.foregroundActivities
20168                    + " type=" + app.adjType + " source=" + app.adjSource
20169                    + " target=" + app.adjTarget);
20170        }
20171
20172        return success;
20173    }
20174
20175    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20176        final UidRecord.ChangeItem pendingChange;
20177        if (uidRec == null || uidRec.pendingChange == null) {
20178            if (mPendingUidChanges.size() == 0) {
20179                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20180                        "*** Enqueueing dispatch uid changed!");
20181                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20182            }
20183            final int NA = mAvailUidChanges.size();
20184            if (NA > 0) {
20185                pendingChange = mAvailUidChanges.remove(NA-1);
20186                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20187                        "Retrieving available item: " + pendingChange);
20188            } else {
20189                pendingChange = new UidRecord.ChangeItem();
20190                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20191                        "Allocating new item: " + pendingChange);
20192            }
20193            if (uidRec != null) {
20194                uidRec.pendingChange = pendingChange;
20195                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20196                    // If this uid is going away, and we haven't yet reported it is gone,
20197                    // then do so now.
20198                    change = UidRecord.CHANGE_GONE_IDLE;
20199                }
20200            } else if (uid < 0) {
20201                throw new IllegalArgumentException("No UidRecord or uid");
20202            }
20203            pendingChange.uidRecord = uidRec;
20204            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20205            mPendingUidChanges.add(pendingChange);
20206        } else {
20207            pendingChange = uidRec.pendingChange;
20208            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20209                change = UidRecord.CHANGE_GONE_IDLE;
20210            }
20211        }
20212        pendingChange.change = change;
20213        pendingChange.processState = uidRec != null
20214                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20215    }
20216
20217    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20218            String authority) {
20219        if (app == null) return;
20220        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20221            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20222            if (userState == null) return;
20223            final long now = SystemClock.elapsedRealtime();
20224            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20225            if (lastReported == null || lastReported < now - 60 * 1000L) {
20226                mUsageStatsService.reportContentProviderUsage(
20227                        authority, providerPkgName, app.userId);
20228                userState.mProviderLastReportedFg.put(authority, now);
20229            }
20230        }
20231    }
20232
20233    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20234        if (DEBUG_USAGE_STATS) {
20235            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20236                    + "] state changes: old = " + app.setProcState + ", new = "
20237                    + app.curProcState);
20238        }
20239        if (mUsageStatsService == null) {
20240            return;
20241        }
20242        boolean isInteraction;
20243        // To avoid some abuse patterns, we are going to be careful about what we consider
20244        // to be an app interaction.  Being the top activity doesn't count while the display
20245        // is sleeping, nor do short foreground services.
20246        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20247            isInteraction = true;
20248            app.fgInteractionTime = 0;
20249        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20250            if (app.fgInteractionTime == 0) {
20251                app.fgInteractionTime = nowElapsed;
20252                isInteraction = false;
20253            } else {
20254                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20255            }
20256        } else {
20257            isInteraction = app.curProcState
20258                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20259            app.fgInteractionTime = 0;
20260        }
20261        if (isInteraction && (!app.reportedInteraction
20262                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20263            app.interactionEventTime = nowElapsed;
20264            String[] packages = app.getPackageList();
20265            if (packages != null) {
20266                for (int i = 0; i < packages.length; i++) {
20267                    mUsageStatsService.reportEvent(packages[i], app.userId,
20268                            UsageEvents.Event.SYSTEM_INTERACTION);
20269                }
20270            }
20271        }
20272        app.reportedInteraction = isInteraction;
20273        if (!isInteraction) {
20274            app.interactionEventTime = 0;
20275        }
20276    }
20277
20278    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20279        if (proc.thread != null) {
20280            if (proc.baseProcessTracker != null) {
20281                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20282            }
20283        }
20284    }
20285
20286    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20287            ProcessRecord TOP_APP, boolean doingAll, long now) {
20288        if (app.thread == null) {
20289            return false;
20290        }
20291
20292        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20293
20294        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20295    }
20296
20297    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20298            boolean oomAdj) {
20299        if (isForeground != proc.foregroundServices) {
20300            proc.foregroundServices = isForeground;
20301            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20302                    proc.info.uid);
20303            if (isForeground) {
20304                if (curProcs == null) {
20305                    curProcs = new ArrayList<ProcessRecord>();
20306                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20307                }
20308                if (!curProcs.contains(proc)) {
20309                    curProcs.add(proc);
20310                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20311                            proc.info.packageName, proc.info.uid);
20312                }
20313            } else {
20314                if (curProcs != null) {
20315                    if (curProcs.remove(proc)) {
20316                        mBatteryStatsService.noteEvent(
20317                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20318                                proc.info.packageName, proc.info.uid);
20319                        if (curProcs.size() <= 0) {
20320                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20321                        }
20322                    }
20323                }
20324            }
20325            if (oomAdj) {
20326                updateOomAdjLocked();
20327            }
20328        }
20329    }
20330
20331    private final ActivityRecord resumedAppLocked() {
20332        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20333        String pkg;
20334        int uid;
20335        if (act != null) {
20336            pkg = act.packageName;
20337            uid = act.info.applicationInfo.uid;
20338        } else {
20339            pkg = null;
20340            uid = -1;
20341        }
20342        // Has the UID or resumed package name changed?
20343        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20344                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20345            if (mCurResumedPackage != null) {
20346                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20347                        mCurResumedPackage, mCurResumedUid);
20348            }
20349            mCurResumedPackage = pkg;
20350            mCurResumedUid = uid;
20351            if (mCurResumedPackage != null) {
20352                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20353                        mCurResumedPackage, mCurResumedUid);
20354            }
20355        }
20356        return act;
20357    }
20358
20359    final boolean updateOomAdjLocked(ProcessRecord app) {
20360        final ActivityRecord TOP_ACT = resumedAppLocked();
20361        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20362        final boolean wasCached = app.cached;
20363
20364        mAdjSeq++;
20365
20366        // This is the desired cached adjusment we want to tell it to use.
20367        // If our app is currently cached, we know it, and that is it.  Otherwise,
20368        // we don't know it yet, and it needs to now be cached we will then
20369        // need to do a complete oom adj.
20370        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20371                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20372        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20373                SystemClock.uptimeMillis());
20374        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20375            // Changed to/from cached state, so apps after it in the LRU
20376            // list may also be changed.
20377            updateOomAdjLocked();
20378        }
20379        return success;
20380    }
20381
20382    final void updateOomAdjLocked() {
20383        final ActivityRecord TOP_ACT = resumedAppLocked();
20384        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20385        final long now = SystemClock.uptimeMillis();
20386        final long nowElapsed = SystemClock.elapsedRealtime();
20387        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20388        final int N = mLruProcesses.size();
20389
20390        if (false) {
20391            RuntimeException e = new RuntimeException();
20392            e.fillInStackTrace();
20393            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20394        }
20395
20396        // Reset state in all uid records.
20397        for (int i=mActiveUids.size()-1; i>=0; i--) {
20398            final UidRecord uidRec = mActiveUids.valueAt(i);
20399            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20400                    "Starting update of " + uidRec);
20401            uidRec.reset();
20402        }
20403
20404        mStackSupervisor.rankTaskLayersIfNeeded();
20405
20406        mAdjSeq++;
20407        mNewNumServiceProcs = 0;
20408        mNewNumAServiceProcs = 0;
20409
20410        final int emptyProcessLimit;
20411        final int cachedProcessLimit;
20412        if (mProcessLimit <= 0) {
20413            emptyProcessLimit = cachedProcessLimit = 0;
20414        } else if (mProcessLimit == 1) {
20415            emptyProcessLimit = 1;
20416            cachedProcessLimit = 0;
20417        } else {
20418            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20419            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20420        }
20421
20422        // Let's determine how many processes we have running vs.
20423        // how many slots we have for background processes; we may want
20424        // to put multiple processes in a slot of there are enough of
20425        // them.
20426        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20427                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20428        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20429        if (numEmptyProcs > cachedProcessLimit) {
20430            // If there are more empty processes than our limit on cached
20431            // processes, then use the cached process limit for the factor.
20432            // This ensures that the really old empty processes get pushed
20433            // down to the bottom, so if we are running low on memory we will
20434            // have a better chance at keeping around more cached processes
20435            // instead of a gazillion empty processes.
20436            numEmptyProcs = cachedProcessLimit;
20437        }
20438        int emptyFactor = numEmptyProcs/numSlots;
20439        if (emptyFactor < 1) emptyFactor = 1;
20440        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20441        if (cachedFactor < 1) cachedFactor = 1;
20442        int stepCached = 0;
20443        int stepEmpty = 0;
20444        int numCached = 0;
20445        int numEmpty = 0;
20446        int numTrimming = 0;
20447
20448        mNumNonCachedProcs = 0;
20449        mNumCachedHiddenProcs = 0;
20450
20451        // First update the OOM adjustment for each of the
20452        // application processes based on their current state.
20453        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20454        int nextCachedAdj = curCachedAdj+1;
20455        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20456        int nextEmptyAdj = curEmptyAdj+2;
20457        for (int i=N-1; i>=0; i--) {
20458            ProcessRecord app = mLruProcesses.get(i);
20459            if (!app.killedByAm && app.thread != null) {
20460                app.procStateChanged = false;
20461                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20462
20463                // If we haven't yet assigned the final cached adj
20464                // to the process, do that now.
20465                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20466                    switch (app.curProcState) {
20467                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20468                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20469                            // This process is a cached process holding activities...
20470                            // assign it the next cached value for that type, and then
20471                            // step that cached level.
20472                            app.curRawAdj = curCachedAdj;
20473                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20474                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20475                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20476                                    + ")");
20477                            if (curCachedAdj != nextCachedAdj) {
20478                                stepCached++;
20479                                if (stepCached >= cachedFactor) {
20480                                    stepCached = 0;
20481                                    curCachedAdj = nextCachedAdj;
20482                                    nextCachedAdj += 2;
20483                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20484                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20485                                    }
20486                                }
20487                            }
20488                            break;
20489                        default:
20490                            // For everything else, assign next empty cached process
20491                            // level and bump that up.  Note that this means that
20492                            // long-running services that have dropped down to the
20493                            // cached level will be treated as empty (since their process
20494                            // state is still as a service), which is what we want.
20495                            app.curRawAdj = curEmptyAdj;
20496                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20497                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20498                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20499                                    + ")");
20500                            if (curEmptyAdj != nextEmptyAdj) {
20501                                stepEmpty++;
20502                                if (stepEmpty >= emptyFactor) {
20503                                    stepEmpty = 0;
20504                                    curEmptyAdj = nextEmptyAdj;
20505                                    nextEmptyAdj += 2;
20506                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20507                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20508                                    }
20509                                }
20510                            }
20511                            break;
20512                    }
20513                }
20514
20515                applyOomAdjLocked(app, true, now, nowElapsed);
20516
20517                // Count the number of process types.
20518                switch (app.curProcState) {
20519                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20520                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20521                        mNumCachedHiddenProcs++;
20522                        numCached++;
20523                        if (numCached > cachedProcessLimit) {
20524                            app.kill("cached #" + numCached, true);
20525                        }
20526                        break;
20527                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20528                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20529                                && app.lastActivityTime < oldTime) {
20530                            app.kill("empty for "
20531                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20532                                    / 1000) + "s", true);
20533                        } else {
20534                            numEmpty++;
20535                            if (numEmpty > emptyProcessLimit) {
20536                                app.kill("empty #" + numEmpty, true);
20537                            }
20538                        }
20539                        break;
20540                    default:
20541                        mNumNonCachedProcs++;
20542                        break;
20543                }
20544
20545                if (app.isolated && app.services.size() <= 0) {
20546                    // If this is an isolated process, and there are no
20547                    // services running in it, then the process is no longer
20548                    // needed.  We agressively kill these because we can by
20549                    // definition not re-use the same process again, and it is
20550                    // good to avoid having whatever code was running in them
20551                    // left sitting around after no longer needed.
20552                    app.kill("isolated not needed", true);
20553                } else {
20554                    // Keeping this process, update its uid.
20555                    final UidRecord uidRec = app.uidRecord;
20556                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20557                        uidRec.curProcState = app.curProcState;
20558                    }
20559                }
20560
20561                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20562                        && !app.killedByAm) {
20563                    numTrimming++;
20564                }
20565            }
20566        }
20567
20568        mNumServiceProcs = mNewNumServiceProcs;
20569
20570        // Now determine the memory trimming level of background processes.
20571        // Unfortunately we need to start at the back of the list to do this
20572        // properly.  We only do this if the number of background apps we
20573        // are managing to keep around is less than half the maximum we desire;
20574        // if we are keeping a good number around, we'll let them use whatever
20575        // memory they want.
20576        final int numCachedAndEmpty = numCached + numEmpty;
20577        int memFactor;
20578        if (numCached <= ProcessList.TRIM_CACHED_APPS
20579                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20580            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20581                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20582            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20583                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20584            } else {
20585                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20586            }
20587        } else {
20588            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20589        }
20590        // We always allow the memory level to go up (better).  We only allow it to go
20591        // down if we are in a state where that is allowed, *and* the total number of processes
20592        // has gone down since last time.
20593        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20594                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20595                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20596        if (memFactor > mLastMemoryLevel) {
20597            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20598                memFactor = mLastMemoryLevel;
20599                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20600            }
20601        }
20602        if (memFactor != mLastMemoryLevel) {
20603            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20604        }
20605        mLastMemoryLevel = memFactor;
20606        mLastNumProcesses = mLruProcesses.size();
20607        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20608        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20609        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20610            if (mLowRamStartTime == 0) {
20611                mLowRamStartTime = now;
20612            }
20613            int step = 0;
20614            int fgTrimLevel;
20615            switch (memFactor) {
20616                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20617                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20618                    break;
20619                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20620                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20621                    break;
20622                default:
20623                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20624                    break;
20625            }
20626            int factor = numTrimming/3;
20627            int minFactor = 2;
20628            if (mHomeProcess != null) minFactor++;
20629            if (mPreviousProcess != null) minFactor++;
20630            if (factor < minFactor) factor = minFactor;
20631            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20632            for (int i=N-1; i>=0; i--) {
20633                ProcessRecord app = mLruProcesses.get(i);
20634                if (allChanged || app.procStateChanged) {
20635                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20636                    app.procStateChanged = false;
20637                }
20638                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20639                        && !app.killedByAm) {
20640                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20641                        try {
20642                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20643                                    "Trimming memory of " + app.processName + " to " + curLevel);
20644                            app.thread.scheduleTrimMemory(curLevel);
20645                        } catch (RemoteException e) {
20646                        }
20647                        if (false) {
20648                            // For now we won't do this; our memory trimming seems
20649                            // to be good enough at this point that destroying
20650                            // activities causes more harm than good.
20651                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20652                                    && app != mHomeProcess && app != mPreviousProcess) {
20653                                // Need to do this on its own message because the stack may not
20654                                // be in a consistent state at this point.
20655                                // For these apps we will also finish their activities
20656                                // to help them free memory.
20657                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20658                            }
20659                        }
20660                    }
20661                    app.trimMemoryLevel = curLevel;
20662                    step++;
20663                    if (step >= factor) {
20664                        step = 0;
20665                        switch (curLevel) {
20666                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20667                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20668                                break;
20669                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20670                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20671                                break;
20672                        }
20673                    }
20674                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20675                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20676                            && app.thread != null) {
20677                        try {
20678                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20679                                    "Trimming memory of heavy-weight " + app.processName
20680                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20681                            app.thread.scheduleTrimMemory(
20682                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20683                        } catch (RemoteException e) {
20684                        }
20685                    }
20686                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20687                } else {
20688                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20689                            || app.systemNoUi) && app.pendingUiClean) {
20690                        // If this application is now in the background and it
20691                        // had done UI, then give it the special trim level to
20692                        // have it free UI resources.
20693                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20694                        if (app.trimMemoryLevel < level && app.thread != null) {
20695                            try {
20696                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20697                                        "Trimming memory of bg-ui " + app.processName
20698                                        + " to " + level);
20699                                app.thread.scheduleTrimMemory(level);
20700                            } catch (RemoteException e) {
20701                            }
20702                        }
20703                        app.pendingUiClean = false;
20704                    }
20705                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20706                        try {
20707                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20708                                    "Trimming memory of fg " + app.processName
20709                                    + " to " + fgTrimLevel);
20710                            app.thread.scheduleTrimMemory(fgTrimLevel);
20711                        } catch (RemoteException e) {
20712                        }
20713                    }
20714                    app.trimMemoryLevel = fgTrimLevel;
20715                }
20716            }
20717        } else {
20718            if (mLowRamStartTime != 0) {
20719                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20720                mLowRamStartTime = 0;
20721            }
20722            for (int i=N-1; i>=0; i--) {
20723                ProcessRecord app = mLruProcesses.get(i);
20724                if (allChanged || app.procStateChanged) {
20725                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20726                    app.procStateChanged = false;
20727                }
20728                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20729                        || app.systemNoUi) && app.pendingUiClean) {
20730                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20731                            && app.thread != null) {
20732                        try {
20733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20734                                    "Trimming memory of ui hidden " + app.processName
20735                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20736                            app.thread.scheduleTrimMemory(
20737                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20738                        } catch (RemoteException e) {
20739                        }
20740                    }
20741                    app.pendingUiClean = false;
20742                }
20743                app.trimMemoryLevel = 0;
20744            }
20745        }
20746
20747        if (mAlwaysFinishActivities) {
20748            // Need to do this on its own message because the stack may not
20749            // be in a consistent state at this point.
20750            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20751        }
20752
20753        if (allChanged) {
20754            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20755        }
20756
20757        // Update from any uid changes.
20758        for (int i=mActiveUids.size()-1; i>=0; i--) {
20759            final UidRecord uidRec = mActiveUids.valueAt(i);
20760            int uidChange = UidRecord.CHANGE_PROCSTATE;
20761            if (uidRec.setProcState != uidRec.curProcState) {
20762                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20763                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20764                        + " to " + uidRec.curProcState);
20765                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20766                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20767                        uidRec.lastBackgroundTime = nowElapsed;
20768                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20769                            // Note: the background settle time is in elapsed realtime, while
20770                            // the handler time base is uptime.  All this means is that we may
20771                            // stop background uids later than we had intended, but that only
20772                            // happens because the device was sleeping so we are okay anyway.
20773                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20774                        }
20775                    }
20776                } else {
20777                    if (uidRec.idle) {
20778                        uidChange = UidRecord.CHANGE_ACTIVE;
20779                        uidRec.idle = false;
20780                    }
20781                    uidRec.lastBackgroundTime = 0;
20782                }
20783                uidRec.setProcState = uidRec.curProcState;
20784                enqueueUidChangeLocked(uidRec, -1, uidChange);
20785                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20786            }
20787        }
20788
20789        if (mProcessStats.shouldWriteNowLocked(now)) {
20790            mHandler.post(new Runnable() {
20791                @Override public void run() {
20792                    synchronized (ActivityManagerService.this) {
20793                        mProcessStats.writeStateAsyncLocked();
20794                    }
20795                }
20796            });
20797        }
20798
20799        if (DEBUG_OOM_ADJ) {
20800            final long duration = SystemClock.uptimeMillis() - now;
20801            if (false) {
20802                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20803                        new RuntimeException("here").fillInStackTrace());
20804            } else {
20805                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20806            }
20807        }
20808    }
20809
20810    final void idleUids() {
20811        synchronized (this) {
20812            final long nowElapsed = SystemClock.elapsedRealtime();
20813            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20814            long nextTime = 0;
20815            for (int i=mActiveUids.size()-1; i>=0; i--) {
20816                final UidRecord uidRec = mActiveUids.valueAt(i);
20817                final long bgTime = uidRec.lastBackgroundTime;
20818                if (bgTime > 0 && !uidRec.idle) {
20819                    if (bgTime <= maxBgTime) {
20820                        uidRec.idle = true;
20821                        doStopUidLocked(uidRec.uid, uidRec);
20822                    } else {
20823                        if (nextTime == 0 || nextTime > bgTime) {
20824                            nextTime = bgTime;
20825                        }
20826                    }
20827                }
20828            }
20829            if (nextTime > 0) {
20830                mHandler.removeMessages(IDLE_UIDS_MSG);
20831                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20832                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20833            }
20834        }
20835    }
20836
20837    final void runInBackgroundDisabled(int uid) {
20838        synchronized (this) {
20839            UidRecord uidRec = mActiveUids.get(uid);
20840            if (uidRec != null) {
20841                // This uid is actually running...  should it be considered background now?
20842                if (uidRec.idle) {
20843                    doStopUidLocked(uidRec.uid, uidRec);
20844                }
20845            } else {
20846                // This uid isn't actually running...  still send a report about it being "stopped".
20847                doStopUidLocked(uid, null);
20848            }
20849        }
20850    }
20851
20852    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20853        mServices.stopInBackgroundLocked(uid);
20854        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20855    }
20856
20857    final void trimApplications() {
20858        synchronized (this) {
20859            int i;
20860
20861            // First remove any unused application processes whose package
20862            // has been removed.
20863            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20864                final ProcessRecord app = mRemovedProcesses.get(i);
20865                if (app.activities.size() == 0
20866                        && app.curReceiver == null && app.services.size() == 0) {
20867                    Slog.i(
20868                        TAG, "Exiting empty application process "
20869                        + app.toShortString() + " ("
20870                        + (app.thread != null ? app.thread.asBinder() : null)
20871                        + ")\n");
20872                    if (app.pid > 0 && app.pid != MY_PID) {
20873                        app.kill("empty", false);
20874                    } else {
20875                        try {
20876                            app.thread.scheduleExit();
20877                        } catch (Exception e) {
20878                            // Ignore exceptions.
20879                        }
20880                    }
20881                    cleanUpApplicationRecordLocked(app, false, true, -1);
20882                    mRemovedProcesses.remove(i);
20883
20884                    if (app.persistent) {
20885                        addAppLocked(app.info, false, null /* ABI override */);
20886                    }
20887                }
20888            }
20889
20890            // Now update the oom adj for all processes.
20891            updateOomAdjLocked();
20892        }
20893    }
20894
20895    /** This method sends the specified signal to each of the persistent apps */
20896    public void signalPersistentProcesses(int sig) throws RemoteException {
20897        if (sig != Process.SIGNAL_USR1) {
20898            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20899        }
20900
20901        synchronized (this) {
20902            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20903                    != PackageManager.PERMISSION_GRANTED) {
20904                throw new SecurityException("Requires permission "
20905                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20906            }
20907
20908            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20909                ProcessRecord r = mLruProcesses.get(i);
20910                if (r.thread != null && r.persistent) {
20911                    Process.sendSignal(r.pid, sig);
20912                }
20913            }
20914        }
20915    }
20916
20917    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20918        if (proc == null || proc == mProfileProc) {
20919            proc = mProfileProc;
20920            profileType = mProfileType;
20921            clearProfilerLocked();
20922        }
20923        if (proc == null) {
20924            return;
20925        }
20926        try {
20927            proc.thread.profilerControl(false, null, profileType);
20928        } catch (RemoteException e) {
20929            throw new IllegalStateException("Process disappeared");
20930        }
20931    }
20932
20933    private void clearProfilerLocked() {
20934        if (mProfileFd != null) {
20935            try {
20936                mProfileFd.close();
20937            } catch (IOException e) {
20938            }
20939        }
20940        mProfileApp = null;
20941        mProfileProc = null;
20942        mProfileFile = null;
20943        mProfileType = 0;
20944        mAutoStopProfiler = false;
20945        mSamplingInterval = 0;
20946    }
20947
20948    public boolean profileControl(String process, int userId, boolean start,
20949            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20950
20951        try {
20952            synchronized (this) {
20953                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20954                // its own permission.
20955                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20956                        != PackageManager.PERMISSION_GRANTED) {
20957                    throw new SecurityException("Requires permission "
20958                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20959                }
20960
20961                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20962                    throw new IllegalArgumentException("null profile info or fd");
20963                }
20964
20965                ProcessRecord proc = null;
20966                if (process != null) {
20967                    proc = findProcessLocked(process, userId, "profileControl");
20968                }
20969
20970                if (start && (proc == null || proc.thread == null)) {
20971                    throw new IllegalArgumentException("Unknown process: " + process);
20972                }
20973
20974                if (start) {
20975                    stopProfilerLocked(null, 0);
20976                    setProfileApp(proc.info, proc.processName, profilerInfo);
20977                    mProfileProc = proc;
20978                    mProfileType = profileType;
20979                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20980                    try {
20981                        fd = fd.dup();
20982                    } catch (IOException e) {
20983                        fd = null;
20984                    }
20985                    profilerInfo.profileFd = fd;
20986                    proc.thread.profilerControl(start, profilerInfo, profileType);
20987                    fd = null;
20988                    mProfileFd = null;
20989                } else {
20990                    stopProfilerLocked(proc, profileType);
20991                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20992                        try {
20993                            profilerInfo.profileFd.close();
20994                        } catch (IOException e) {
20995                        }
20996                    }
20997                }
20998
20999                return true;
21000            }
21001        } catch (RemoteException e) {
21002            throw new IllegalStateException("Process disappeared");
21003        } finally {
21004            if (profilerInfo != null && profilerInfo.profileFd != null) {
21005                try {
21006                    profilerInfo.profileFd.close();
21007                } catch (IOException e) {
21008                }
21009            }
21010        }
21011    }
21012
21013    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21014        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21015                userId, true, ALLOW_FULL_ONLY, callName, null);
21016        ProcessRecord proc = null;
21017        try {
21018            int pid = Integer.parseInt(process);
21019            synchronized (mPidsSelfLocked) {
21020                proc = mPidsSelfLocked.get(pid);
21021            }
21022        } catch (NumberFormatException e) {
21023        }
21024
21025        if (proc == null) {
21026            ArrayMap<String, SparseArray<ProcessRecord>> all
21027                    = mProcessNames.getMap();
21028            SparseArray<ProcessRecord> procs = all.get(process);
21029            if (procs != null && procs.size() > 0) {
21030                proc = procs.valueAt(0);
21031                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21032                    for (int i=1; i<procs.size(); i++) {
21033                        ProcessRecord thisProc = procs.valueAt(i);
21034                        if (thisProc.userId == userId) {
21035                            proc = thisProc;
21036                            break;
21037                        }
21038                    }
21039                }
21040            }
21041        }
21042
21043        return proc;
21044    }
21045
21046    public boolean dumpHeap(String process, int userId, boolean managed,
21047            String path, ParcelFileDescriptor fd) throws RemoteException {
21048
21049        try {
21050            synchronized (this) {
21051                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21052                // its own permission (same as profileControl).
21053                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21054                        != PackageManager.PERMISSION_GRANTED) {
21055                    throw new SecurityException("Requires permission "
21056                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21057                }
21058
21059                if (fd == null) {
21060                    throw new IllegalArgumentException("null fd");
21061                }
21062
21063                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21064                if (proc == null || proc.thread == null) {
21065                    throw new IllegalArgumentException("Unknown process: " + process);
21066                }
21067
21068                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21069                if (!isDebuggable) {
21070                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21071                        throw new SecurityException("Process not debuggable: " + proc);
21072                    }
21073                }
21074
21075                proc.thread.dumpHeap(managed, path, fd);
21076                fd = null;
21077                return true;
21078            }
21079        } catch (RemoteException e) {
21080            throw new IllegalStateException("Process disappeared");
21081        } finally {
21082            if (fd != null) {
21083                try {
21084                    fd.close();
21085                } catch (IOException e) {
21086                }
21087            }
21088        }
21089    }
21090
21091    @Override
21092    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21093            String reportPackage) {
21094        if (processName != null) {
21095            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21096                    "setDumpHeapDebugLimit()");
21097        } else {
21098            synchronized (mPidsSelfLocked) {
21099                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21100                if (proc == null) {
21101                    throw new SecurityException("No process found for calling pid "
21102                            + Binder.getCallingPid());
21103                }
21104                if (!Build.IS_DEBUGGABLE
21105                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21106                    throw new SecurityException("Not running a debuggable build");
21107                }
21108                processName = proc.processName;
21109                uid = proc.uid;
21110                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21111                    throw new SecurityException("Package " + reportPackage + " is not running in "
21112                            + proc);
21113                }
21114            }
21115        }
21116        synchronized (this) {
21117            if (maxMemSize > 0) {
21118                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21119            } else {
21120                if (uid != 0) {
21121                    mMemWatchProcesses.remove(processName, uid);
21122                } else {
21123                    mMemWatchProcesses.getMap().remove(processName);
21124                }
21125            }
21126        }
21127    }
21128
21129    @Override
21130    public void dumpHeapFinished(String path) {
21131        synchronized (this) {
21132            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21133                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21134                        + " does not match last pid " + mMemWatchDumpPid);
21135                return;
21136            }
21137            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21138                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21139                        + " does not match last path " + mMemWatchDumpFile);
21140                return;
21141            }
21142            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21143            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21144        }
21145    }
21146
21147    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21148    public void monitor() {
21149        synchronized (this) { }
21150    }
21151
21152    void onCoreSettingsChange(Bundle settings) {
21153        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21154            ProcessRecord processRecord = mLruProcesses.get(i);
21155            try {
21156                if (processRecord.thread != null) {
21157                    processRecord.thread.setCoreSettings(settings);
21158                }
21159            } catch (RemoteException re) {
21160                /* ignore */
21161            }
21162        }
21163    }
21164
21165    // Multi-user methods
21166
21167    /**
21168     * Start user, if its not already running, but don't bring it to foreground.
21169     */
21170    @Override
21171    public boolean startUserInBackground(final int userId) {
21172        return mUserController.startUser(userId, /* foreground */ false);
21173    }
21174
21175    @Override
21176    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21177        return mUserController.unlockUser(userId, token, secret, listener);
21178    }
21179
21180    @Override
21181    public boolean switchUser(final int targetUserId) {
21182        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21183        UserInfo currentUserInfo;
21184        UserInfo targetUserInfo;
21185        synchronized (this) {
21186            int currentUserId = mUserController.getCurrentUserIdLocked();
21187            currentUserInfo = mUserController.getUserInfo(currentUserId);
21188            targetUserInfo = mUserController.getUserInfo(targetUserId);
21189            if (targetUserInfo == null) {
21190                Slog.w(TAG, "No user info for user #" + targetUserId);
21191                return false;
21192            }
21193            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21194                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21195                        + " when device is in demo mode");
21196                return false;
21197            }
21198            if (!targetUserInfo.supportsSwitchTo()) {
21199                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21200                return false;
21201            }
21202            if (targetUserInfo.isManagedProfile()) {
21203                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21204                return false;
21205            }
21206            mUserController.setTargetUserIdLocked(targetUserId);
21207        }
21208        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21209        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21210        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21211        return true;
21212    }
21213
21214    void scheduleStartProfilesLocked() {
21215        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21216            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21217                    DateUtils.SECOND_IN_MILLIS);
21218        }
21219    }
21220
21221    @Override
21222    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21223        return mUserController.stopUser(userId, force, callback);
21224    }
21225
21226    @Override
21227    public UserInfo getCurrentUser() {
21228        return mUserController.getCurrentUser();
21229    }
21230
21231    @Override
21232    public boolean isUserRunning(int userId, int flags) {
21233        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21234                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21235            String msg = "Permission Denial: isUserRunning() from pid="
21236                    + Binder.getCallingPid()
21237                    + ", uid=" + Binder.getCallingUid()
21238                    + " requires " + INTERACT_ACROSS_USERS;
21239            Slog.w(TAG, msg);
21240            throw new SecurityException(msg);
21241        }
21242        synchronized (this) {
21243            return mUserController.isUserRunningLocked(userId, flags);
21244        }
21245    }
21246
21247    @Override
21248    public int[] getRunningUserIds() {
21249        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21250                != PackageManager.PERMISSION_GRANTED) {
21251            String msg = "Permission Denial: isUserRunning() from pid="
21252                    + Binder.getCallingPid()
21253                    + ", uid=" + Binder.getCallingUid()
21254                    + " requires " + INTERACT_ACROSS_USERS;
21255            Slog.w(TAG, msg);
21256            throw new SecurityException(msg);
21257        }
21258        synchronized (this) {
21259            return mUserController.getStartedUserArrayLocked();
21260        }
21261    }
21262
21263    @Override
21264    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21265        mUserController.registerUserSwitchObserver(observer);
21266    }
21267
21268    @Override
21269    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21270        mUserController.unregisterUserSwitchObserver(observer);
21271    }
21272
21273    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21274        if (info == null) return null;
21275        ApplicationInfo newInfo = new ApplicationInfo(info);
21276        newInfo.initForUser(userId);
21277        return newInfo;
21278    }
21279
21280    public boolean isUserStopped(int userId) {
21281        synchronized (this) {
21282            return mUserController.getStartedUserStateLocked(userId) == null;
21283        }
21284    }
21285
21286    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21287        if (aInfo == null
21288                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21289            return aInfo;
21290        }
21291
21292        ActivityInfo info = new ActivityInfo(aInfo);
21293        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21294        return info;
21295    }
21296
21297    private boolean processSanityChecksLocked(ProcessRecord process) {
21298        if (process == null || process.thread == null) {
21299            return false;
21300        }
21301
21302        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21303        if (!isDebuggable) {
21304            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21305                return false;
21306            }
21307        }
21308
21309        return true;
21310    }
21311
21312    public boolean startBinderTracking() throws RemoteException {
21313        synchronized (this) {
21314            mBinderTransactionTrackingEnabled = true;
21315            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21316            // permission (same as profileControl).
21317            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21318                    != PackageManager.PERMISSION_GRANTED) {
21319                throw new SecurityException("Requires permission "
21320                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21321            }
21322
21323            for (int i = 0; i < mLruProcesses.size(); i++) {
21324                ProcessRecord process = mLruProcesses.get(i);
21325                if (!processSanityChecksLocked(process)) {
21326                    continue;
21327                }
21328                try {
21329                    process.thread.startBinderTracking();
21330                } catch (RemoteException e) {
21331                    Log.v(TAG, "Process disappared");
21332                }
21333            }
21334            return true;
21335        }
21336    }
21337
21338    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21339        try {
21340            synchronized (this) {
21341                mBinderTransactionTrackingEnabled = false;
21342                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21343                // permission (same as profileControl).
21344                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21345                        != PackageManager.PERMISSION_GRANTED) {
21346                    throw new SecurityException("Requires permission "
21347                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21348                }
21349
21350                if (fd == null) {
21351                    throw new IllegalArgumentException("null fd");
21352                }
21353
21354                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21355                pw.println("Binder transaction traces for all processes.\n");
21356                for (ProcessRecord process : mLruProcesses) {
21357                    if (!processSanityChecksLocked(process)) {
21358                        continue;
21359                    }
21360
21361                    pw.println("Traces for process: " + process.processName);
21362                    pw.flush();
21363                    try {
21364                        TransferPipe tp = new TransferPipe();
21365                        try {
21366                            process.thread.stopBinderTrackingAndDump(
21367                                    tp.getWriteFd().getFileDescriptor());
21368                            tp.go(fd.getFileDescriptor());
21369                        } finally {
21370                            tp.kill();
21371                        }
21372                    } catch (IOException e) {
21373                        pw.println("Failure while dumping IPC traces from " + process +
21374                                ".  Exception: " + e);
21375                        pw.flush();
21376                    } catch (RemoteException e) {
21377                        pw.println("Got a RemoteException while dumping IPC traces from " +
21378                                process + ".  Exception: " + e);
21379                        pw.flush();
21380                    }
21381                }
21382                fd = null;
21383                return true;
21384            }
21385        } finally {
21386            if (fd != null) {
21387                try {
21388                    fd.close();
21389                } catch (IOException e) {
21390                }
21391            }
21392        }
21393    }
21394
21395    private final class LocalService extends ActivityManagerInternal {
21396        @Override
21397        public void onWakefulnessChanged(int wakefulness) {
21398            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21399        }
21400
21401        @Override
21402        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21403                String processName, String abiOverride, int uid, Runnable crashHandler) {
21404            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21405                    processName, abiOverride, uid, crashHandler);
21406        }
21407
21408        @Override
21409        public SleepToken acquireSleepToken(String tag) {
21410            Preconditions.checkNotNull(tag);
21411
21412            synchronized (ActivityManagerService.this) {
21413                SleepTokenImpl token = new SleepTokenImpl(tag);
21414                mSleepTokens.add(token);
21415                updateSleepIfNeededLocked();
21416                applyVrModeIfNeededLocked(mFocusedActivity, false);
21417                return token;
21418            }
21419        }
21420
21421        @Override
21422        public ComponentName getHomeActivityForUser(int userId) {
21423            synchronized (ActivityManagerService.this) {
21424                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21425                return homeActivity == null ? null : homeActivity.realActivity;
21426            }
21427        }
21428
21429        @Override
21430        public void onUserRemoved(int userId) {
21431            synchronized (ActivityManagerService.this) {
21432                ActivityManagerService.this.onUserStoppedLocked(userId);
21433            }
21434        }
21435
21436        @Override
21437        public void onLocalVoiceInteractionStarted(IBinder activity,
21438                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21439            synchronized (ActivityManagerService.this) {
21440                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21441                        voiceSession, voiceInteractor);
21442            }
21443        }
21444
21445        @Override
21446        public void notifyStartingWindowDrawn() {
21447            synchronized (ActivityManagerService.this) {
21448                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21449            }
21450        }
21451
21452        @Override
21453        public void notifyAppTransitionStarting(int reason) {
21454            synchronized (ActivityManagerService.this) {
21455                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21456            }
21457        }
21458
21459        @Override
21460        public void notifyAppTransitionFinished() {
21461            synchronized (ActivityManagerService.this) {
21462                mStackSupervisor.notifyAppTransitionDone();
21463            }
21464        }
21465
21466        @Override
21467        public void notifyAppTransitionCancelled() {
21468            synchronized (ActivityManagerService.this) {
21469                mStackSupervisor.notifyAppTransitionDone();
21470            }
21471        }
21472
21473        @Override
21474        public List<IBinder> getTopVisibleActivities() {
21475            synchronized (ActivityManagerService.this) {
21476                return mStackSupervisor.getTopVisibleActivities();
21477            }
21478        }
21479
21480        @Override
21481        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21482            synchronized (ActivityManagerService.this) {
21483                mStackSupervisor.setDockedStackMinimized(minimized);
21484            }
21485        }
21486
21487        @Override
21488        public void killForegroundAppsForUser(int userHandle) {
21489            synchronized (ActivityManagerService.this) {
21490                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21491                final int NP = mProcessNames.getMap().size();
21492                for (int ip = 0; ip < NP; ip++) {
21493                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21494                    final int NA = apps.size();
21495                    for (int ia = 0; ia < NA; ia++) {
21496                        final ProcessRecord app = apps.valueAt(ia);
21497                        if (app.persistent) {
21498                            // We don't kill persistent processes.
21499                            continue;
21500                        }
21501                        if (app.removed) {
21502                            procs.add(app);
21503                        } else if (app.userId == userHandle && app.foregroundActivities) {
21504                            app.removed = true;
21505                            procs.add(app);
21506                        }
21507                    }
21508                }
21509
21510                final int N = procs.size();
21511                for (int i = 0; i < N; i++) {
21512                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21513                }
21514            }
21515        }
21516
21517        @Override
21518        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21519            if (!(target instanceof PendingIntentRecord)) {
21520                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21521                return;
21522            }
21523            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21524        }
21525    }
21526
21527    private final class SleepTokenImpl extends SleepToken {
21528        private final String mTag;
21529        private final long mAcquireTime;
21530
21531        public SleepTokenImpl(String tag) {
21532            mTag = tag;
21533            mAcquireTime = SystemClock.uptimeMillis();
21534        }
21535
21536        @Override
21537        public void release() {
21538            synchronized (ActivityManagerService.this) {
21539                if (mSleepTokens.remove(this)) {
21540                    updateSleepIfNeededLocked();
21541                }
21542            }
21543        }
21544
21545        @Override
21546        public String toString() {
21547            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21548        }
21549    }
21550
21551    /**
21552     * An implementation of IAppTask, that allows an app to manage its own tasks via
21553     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21554     * only the process that calls getAppTasks() can call the AppTask methods.
21555     */
21556    class AppTaskImpl extends IAppTask.Stub {
21557        private int mTaskId;
21558        private int mCallingUid;
21559
21560        public AppTaskImpl(int taskId, int callingUid) {
21561            mTaskId = taskId;
21562            mCallingUid = callingUid;
21563        }
21564
21565        private void checkCaller() {
21566            if (mCallingUid != Binder.getCallingUid()) {
21567                throw new SecurityException("Caller " + mCallingUid
21568                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21569            }
21570        }
21571
21572        @Override
21573        public void finishAndRemoveTask() {
21574            checkCaller();
21575
21576            synchronized (ActivityManagerService.this) {
21577                long origId = Binder.clearCallingIdentity();
21578                try {
21579                    // We remove the task from recents to preserve backwards
21580                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21581                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21582                    }
21583                } finally {
21584                    Binder.restoreCallingIdentity(origId);
21585                }
21586            }
21587        }
21588
21589        @Override
21590        public ActivityManager.RecentTaskInfo getTaskInfo() {
21591            checkCaller();
21592
21593            synchronized (ActivityManagerService.this) {
21594                long origId = Binder.clearCallingIdentity();
21595                try {
21596                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21597                    if (tr == null) {
21598                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21599                    }
21600                    return createRecentTaskInfoFromTaskRecord(tr);
21601                } finally {
21602                    Binder.restoreCallingIdentity(origId);
21603                }
21604            }
21605        }
21606
21607        @Override
21608        public void moveToFront() {
21609            checkCaller();
21610            // Will bring task to front if it already has a root activity.
21611            final long origId = Binder.clearCallingIdentity();
21612            try {
21613                synchronized (this) {
21614                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21615                }
21616            } finally {
21617                Binder.restoreCallingIdentity(origId);
21618            }
21619        }
21620
21621        @Override
21622        public int startActivity(IBinder whoThread, String callingPackage,
21623                Intent intent, String resolvedType, Bundle bOptions) {
21624            checkCaller();
21625
21626            int callingUser = UserHandle.getCallingUserId();
21627            TaskRecord tr;
21628            IApplicationThread appThread;
21629            synchronized (ActivityManagerService.this) {
21630                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21631                if (tr == null) {
21632                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21633                }
21634                appThread = ApplicationThreadNative.asInterface(whoThread);
21635                if (appThread == null) {
21636                    throw new IllegalArgumentException("Bad app thread " + appThread);
21637                }
21638            }
21639            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21640                    resolvedType, null, null, null, null, 0, 0, null, null,
21641                    null, bOptions, false, callingUser, null, tr);
21642        }
21643
21644        @Override
21645        public void setExcludeFromRecents(boolean exclude) {
21646            checkCaller();
21647
21648            synchronized (ActivityManagerService.this) {
21649                long origId = Binder.clearCallingIdentity();
21650                try {
21651                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21652                    if (tr == null) {
21653                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21654                    }
21655                    Intent intent = tr.getBaseIntent();
21656                    if (exclude) {
21657                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21658                    } else {
21659                        intent.setFlags(intent.getFlags()
21660                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21661                    }
21662                } finally {
21663                    Binder.restoreCallingIdentity(origId);
21664                }
21665            }
21666        }
21667    }
21668
21669    /**
21670     * Kill processes for the user with id userId and that depend on the package named packageName
21671     */
21672    @Override
21673    public void killPackageDependents(String packageName, int userId) {
21674        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21675        if (packageName == null) {
21676            throw new NullPointerException(
21677                    "Cannot kill the dependents of a package without its name.");
21678        }
21679
21680        long callingId = Binder.clearCallingIdentity();
21681        IPackageManager pm = AppGlobals.getPackageManager();
21682        int pkgUid = -1;
21683        try {
21684            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21685        } catch (RemoteException e) {
21686        }
21687        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21688            throw new IllegalArgumentException(
21689                    "Cannot kill dependents of non-existing package " + packageName);
21690        }
21691        try {
21692            synchronized(this) {
21693                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21694                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21695                        "dep: " + packageName);
21696            }
21697        } finally {
21698            Binder.restoreCallingIdentity(callingId);
21699        }
21700    }
21701}
21702