ActivityManagerService.java revision 8b655e0f57b071756e7d6a3547eeabe35885bcc9
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.telecom.TelecomManager;
203import android.text.format.DateUtils;
204import android.text.format.Time;
205import android.text.style.SuggestionSpan;
206import android.util.ArrayMap;
207import android.util.ArraySet;
208import android.util.AtomicFile;
209import android.util.DebugUtils;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Display;
219import android.view.Gravity;
220import android.view.LayoutInflater;
221import android.view.View;
222import android.view.WindowManager;
223
224import java.io.File;
225import java.io.FileDescriptor;
226import java.io.FileInputStream;
227import java.io.FileNotFoundException;
228import java.io.FileOutputStream;
229import java.io.IOException;
230import java.io.InputStreamReader;
231import java.io.PrintWriter;
232import java.io.StringWriter;
233import java.lang.ref.WeakReference;
234import java.nio.charset.StandardCharsets;
235import java.util.ArrayList;
236import java.util.Arrays;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.HashMap;
240import java.util.HashSet;
241import java.util.Iterator;
242import java.util.List;
243import java.util.Locale;
244import java.util.Map;
245import java.util.Objects;
246import java.util.Set;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicLong;
249
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
268import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
270import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
271import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
272import static android.content.pm.PackageManager.GET_PROVIDERS;
273import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
274import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
275import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
276import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
277import static android.content.pm.PackageManager.PERMISSION_GRANTED;
278import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
279import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
280import static android.provider.Settings.Global.DEBUG_APP;
281import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
282import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
284import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
285import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
286import static android.provider.Settings.System.FONT_SCALE;
287import static com.android.internal.util.XmlUtils.readBooleanAttribute;
288import static com.android.internal.util.XmlUtils.readIntAttribute;
289import static com.android.internal.util.XmlUtils.readLongAttribute;
290import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
291import static com.android.internal.util.XmlUtils.writeIntAttribute;
292import static com.android.internal.util.XmlUtils.writeLongAttribute;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
350import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
352import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
353import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
354import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
355import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
356import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
357import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
358import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
359import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
360import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
363import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
365import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
368import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
369import static org.xmlpull.v1.XmlPullParser.START_TAG;
370
371public final class ActivityManagerService extends ActivityManagerNative
372        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
373
374    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
375    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
376    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
377    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
378    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
379    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
380    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
381    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
382    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
383    private static final String TAG_LRU = TAG + POSTFIX_LRU;
384    private static final String TAG_MU = TAG + POSTFIX_MU;
385    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
386    private static final String TAG_POWER = TAG + POSTFIX_POWER;
387    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
388    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
389    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
390    private static final String TAG_PSS = TAG + POSTFIX_PSS;
391    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
392    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
393    private static final String TAG_STACK = TAG + POSTFIX_STACK;
394    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
395    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
396    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
397    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
398    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
399
400    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
401    // here so that while the job scheduler can depend on AMS, the other way around
402    // need not be the case.
403    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
404
405    /** Control over CPU and battery monitoring */
406    // write battery stats every 30 minutes.
407    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
408    static final boolean MONITOR_CPU_USAGE = true;
409    // don't sample cpu less than every 5 seconds.
410    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
411    // wait possibly forever for next cpu sample.
412    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
413    static final boolean MONITOR_THREAD_CPU_USAGE = false;
414
415    // The flags that are set for all calls we make to the package manager.
416    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
417
418    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
419
420    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
421
422    // Amount of time after a call to stopAppSwitches() during which we will
423    // prevent further untrusted switches from happening.
424    static final long APP_SWITCH_DELAY_TIME = 5*1000;
425
426    // How long we wait for a launched process to attach to the activity manager
427    // before we decide it's never going to come up for real.
428    static final int PROC_START_TIMEOUT = 10*1000;
429    // How long we wait for an attached process to publish its content providers
430    // before we decide it must be hung.
431    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
432
433    // How long we will retain processes hosting content providers in the "last activity"
434    // state before allowing them to drop down to the regular cached LRU list.  This is
435    // to avoid thrashing of provider processes under low memory situations.
436    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
437
438    // How long we wait for a launched process to attach to the activity manager
439    // before we decide it's never going to come up for real, when the process was
440    // started with a wrapper for instrumentation (such as Valgrind) because it
441    // could take much longer than usual.
442    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
443
444    // How long to wait after going idle before forcing apps to GC.
445    static final int GC_TIMEOUT = 5*1000;
446
447    // The minimum amount of time between successive GC requests for a process.
448    static final int GC_MIN_INTERVAL = 60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process.
451    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
452
453    // The minimum amount of time between successive PSS requests for a process
454    // when the request is due to the memory state being lowered.
455    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
456
457    // The rate at which we check for apps using excessive power -- 15 mins.
458    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
459
460    // The minimum sample duration we will allow before deciding we have
461    // enough data on wake locks to start killing things.
462    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
463
464    // The minimum sample duration we will allow before deciding we have
465    // enough data on CPU usage to start killing things.
466    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467
468    // How long we allow a receiver to run before giving up on it.
469    static final int BROADCAST_FG_TIMEOUT = 10*1000;
470    static final int BROADCAST_BG_TIMEOUT = 60*1000;
471
472    // How long we wait until we timeout on key dispatching.
473    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
474
475    // How long we wait until we timeout on key dispatching during instrumentation.
476    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
477
478    // This is the amount of time an app needs to be running a foreground service before
479    // we will consider it to be doing interaction for usage stats.
480    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
481
482    // Maximum amount of time we will allow to elapse before re-reporting usage stats
483    // interaction with foreground processes.
484    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
485
486    // This is the amount of time we allow an app to settle after it goes into the background,
487    // before we start restricting what it can do.
488    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
489
490    // How long to wait in getAssistContextExtras for the activity and foreground services
491    // to respond with the result.
492    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
493
494    // How long top wait when going through the modern assist (which doesn't need to block
495    // on getting this result before starting to launch its UI).
496    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
497
498    // Maximum number of persisted Uri grants a package is allowed
499    static final int MAX_PERSISTED_URI_GRANTS = 128;
500
501    static final int MY_PID = Process.myPid();
502
503    static final String[] EMPTY_STRING_ARRAY = new String[0];
504
505    // How many bytes to write into the dropbox log before truncating
506    static final int DROPBOX_MAX_SIZE = 256 * 1024;
507
508    // Access modes for handleIncomingUser.
509    static final int ALLOW_NON_FULL = 0;
510    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
511    static final int ALLOW_FULL_ONLY = 2;
512
513    // Delay in notifying task stack change listeners (in millis)
514    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
515
516    // Necessary ApplicationInfo flags to mark an app as persistent
517    private static final int PERSISTENT_MASK =
518            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
519
520    // Intent sent when remote bugreport collection has been completed
521    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
522            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
523
524    // Delay to disable app launch boost
525    static final int APP_BOOST_MESSAGE_DELAY = 3000;
526    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
527    static final int APP_BOOST_TIMEOUT = 2500;
528
529    // Used to indicate that a task is removed it should also be removed from recents.
530    private static final boolean REMOVE_FROM_RECENTS = true;
531    // Used to indicate that an app transition should be animated.
532    static final boolean ANIMATE = true;
533
534    // Determines whether to take full screen screenshots
535    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
536    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
537
538    private static native int nativeMigrateToBoost();
539    private static native int nativeMigrateFromBoost();
540    private boolean mIsBoosted = false;
541    private long mBoostStartTime = 0;
542
543    /** All system services */
544    SystemServiceManager mSystemServiceManager;
545
546    private Installer mInstaller;
547
548    /** Run all ActivityStacks through this */
549    final ActivityStackSupervisor mStackSupervisor;
550
551    final ActivityStarter mActivityStarter;
552
553    /** Task stack change listeners. */
554    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
555            new RemoteCallbackList<ITaskStackListener>();
556
557    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559    public IntentFirewall mIntentFirewall;
560
561    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562    // default actuion automatically.  Important for devices without direct input
563    // devices.
564    private boolean mShowDialogs = true;
565    private boolean mInVrMode = false;
566
567    BroadcastQueue mFgBroadcastQueue;
568    BroadcastQueue mBgBroadcastQueue;
569    // Convenient for easy iteration over the queues. Foreground is first
570    // so that dispatch of foreground broadcasts gets precedence.
571    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
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, userId));
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) {
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, userHandle);
7833            } catch (RemoteException ex) {
7834            }
7835        }
7836        return pi;
7837    }
7838
7839    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7840        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7841        if (targetUris != null) {
7842            return targetUris.get(grantUri);
7843        }
7844        return null;
7845    }
7846
7847    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7848            String targetPkg, int targetUid, GrantUri grantUri) {
7849        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7850        if (targetUris == null) {
7851            targetUris = Maps.newArrayMap();
7852            mGrantedUriPermissions.put(targetUid, targetUris);
7853        }
7854
7855        UriPermission perm = targetUris.get(grantUri);
7856        if (perm == null) {
7857            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7858            targetUris.put(grantUri, perm);
7859        }
7860
7861        return perm;
7862    }
7863
7864    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7865            final int modeFlags) {
7866        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7867        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7868                : UriPermission.STRENGTH_OWNED;
7869
7870        // Root gets to do everything.
7871        if (uid == 0) {
7872            return true;
7873        }
7874
7875        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7876        if (perms == null) return false;
7877
7878        // First look for exact match
7879        final UriPermission exactPerm = perms.get(grantUri);
7880        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7881            return true;
7882        }
7883
7884        // No exact match, look for prefixes
7885        final int N = perms.size();
7886        for (int i = 0; i < N; i++) {
7887            final UriPermission perm = perms.valueAt(i);
7888            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7889                    && perm.getStrength(modeFlags) >= minStrength) {
7890                return true;
7891            }
7892        }
7893
7894        return false;
7895    }
7896
7897    /**
7898     * @param uri This uri must NOT contain an embedded userId.
7899     * @param userId The userId in which the uri is to be resolved.
7900     */
7901    @Override
7902    public int checkUriPermission(Uri uri, int pid, int uid,
7903            final int modeFlags, int userId, IBinder callerToken) {
7904        enforceNotIsolatedCaller("checkUriPermission");
7905
7906        // Another redirected-binder-call permissions check as in
7907        // {@link checkPermissionWithToken}.
7908        Identity tlsIdentity = sCallerIdentity.get();
7909        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7910            uid = tlsIdentity.uid;
7911            pid = tlsIdentity.pid;
7912        }
7913
7914        // Our own process gets to do everything.
7915        if (pid == MY_PID) {
7916            return PackageManager.PERMISSION_GRANTED;
7917        }
7918        synchronized (this) {
7919            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7920                    ? PackageManager.PERMISSION_GRANTED
7921                    : PackageManager.PERMISSION_DENIED;
7922        }
7923    }
7924
7925    /**
7926     * Check if the targetPkg can be granted permission to access uri by
7927     * the callingUid using the given modeFlags.  Throws a security exception
7928     * if callingUid is not allowed to do this.  Returns the uid of the target
7929     * if the URI permission grant should be performed; returns -1 if it is not
7930     * needed (for example targetPkg already has permission to access the URI).
7931     * If you already know the uid of the target, you can supply it in
7932     * lastTargetUid else set that to -1.
7933     */
7934    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7935            final int modeFlags, int lastTargetUid) {
7936        if (!Intent.isAccessUriMode(modeFlags)) {
7937            return -1;
7938        }
7939
7940        if (targetPkg != null) {
7941            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7942                    "Checking grant " + targetPkg + " permission to " + grantUri);
7943        }
7944
7945        final IPackageManager pm = AppGlobals.getPackageManager();
7946
7947        // If this is not a content: uri, we can't do anything with it.
7948        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7949            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                    "Can't grant URI permission for non-content URI: " + grantUri);
7951            return -1;
7952        }
7953
7954        final String authority = grantUri.uri.getAuthority();
7955        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7956        if (pi == null) {
7957            Slog.w(TAG, "No content provider found for permission check: " +
7958                    grantUri.uri.toSafeString());
7959            return -1;
7960        }
7961
7962        int targetUid = lastTargetUid;
7963        if (targetUid < 0 && targetPkg != null) {
7964            try {
7965                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7966                        UserHandle.getUserId(callingUid));
7967                if (targetUid < 0) {
7968                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7969                            "Can't grant URI permission no uid for: " + targetPkg);
7970                    return -1;
7971                }
7972            } catch (RemoteException ex) {
7973                return -1;
7974            }
7975        }
7976
7977        if (targetUid >= 0) {
7978            // First...  does the target actually need this permission?
7979            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7980                // No need to grant the target this permission.
7981                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                        "Target " + targetPkg + " already has full permission to " + grantUri);
7983                return -1;
7984            }
7985        } else {
7986            // First...  there is no target package, so can anyone access it?
7987            boolean allowed = pi.exported;
7988            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7989                if (pi.readPermission != null) {
7990                    allowed = false;
7991                }
7992            }
7993            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7994                if (pi.writePermission != null) {
7995                    allowed = false;
7996                }
7997            }
7998            if (allowed) {
7999                return -1;
8000            }
8001        }
8002
8003        /* There is a special cross user grant if:
8004         * - The target is on another user.
8005         * - Apps on the current user can access the uri without any uid permissions.
8006         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8007         * grant uri permissions.
8008         */
8009        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8010                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8011                modeFlags, false /*without considering the uid permissions*/);
8012
8013        // Second...  is the provider allowing granting of URI permissions?
8014        if (!specialCrossUserGrant) {
8015            if (!pi.grantUriPermissions) {
8016                throw new SecurityException("Provider " + pi.packageName
8017                        + "/" + pi.name
8018                        + " does not allow granting of Uri permissions (uri "
8019                        + grantUri + ")");
8020            }
8021            if (pi.uriPermissionPatterns != null) {
8022                final int N = pi.uriPermissionPatterns.length;
8023                boolean allowed = false;
8024                for (int i=0; i<N; i++) {
8025                    if (pi.uriPermissionPatterns[i] != null
8026                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8027                        allowed = true;
8028                        break;
8029                    }
8030                }
8031                if (!allowed) {
8032                    throw new SecurityException("Provider " + pi.packageName
8033                            + "/" + pi.name
8034                            + " does not allow granting of permission to path of Uri "
8035                            + grantUri);
8036                }
8037            }
8038        }
8039
8040        // Third...  does the caller itself have permission to access
8041        // this uri?
8042        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8043            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8044                // Require they hold a strong enough Uri permission
8045                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8046                    throw new SecurityException("Uid " + callingUid
8047                            + " does not have permission to uri " + grantUri);
8048                }
8049            }
8050        }
8051        return targetUid;
8052    }
8053
8054    /**
8055     * @param uri This uri must NOT contain an embedded userId.
8056     * @param userId The userId in which the uri is to be resolved.
8057     */
8058    @Override
8059    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8060            final int modeFlags, int userId) {
8061        enforceNotIsolatedCaller("checkGrantUriPermission");
8062        synchronized(this) {
8063            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8064                    new GrantUri(userId, uri, false), modeFlags, -1);
8065        }
8066    }
8067
8068    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8069            final int modeFlags, UriPermissionOwner owner) {
8070        if (!Intent.isAccessUriMode(modeFlags)) {
8071            return;
8072        }
8073
8074        // So here we are: the caller has the assumed permission
8075        // to the uri, and the target doesn't.  Let's now give this to
8076        // the target.
8077
8078        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8080
8081        final String authority = grantUri.uri.getAuthority();
8082        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8083        if (pi == null) {
8084            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8085            return;
8086        }
8087
8088        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8089            grantUri.prefix = true;
8090        }
8091        final UriPermission perm = findOrCreateUriPermissionLocked(
8092                pi.packageName, targetPkg, targetUid, grantUri);
8093        perm.grantModes(modeFlags, owner);
8094    }
8095
8096    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8097            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8098        if (targetPkg == null) {
8099            throw new NullPointerException("targetPkg");
8100        }
8101        int targetUid;
8102        final IPackageManager pm = AppGlobals.getPackageManager();
8103        try {
8104            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8105        } catch (RemoteException ex) {
8106            return;
8107        }
8108
8109        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8110                targetUid);
8111        if (targetUid < 0) {
8112            return;
8113        }
8114
8115        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8116                owner);
8117    }
8118
8119    static class NeededUriGrants extends ArrayList<GrantUri> {
8120        final String targetPkg;
8121        final int targetUid;
8122        final int flags;
8123
8124        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8125            this.targetPkg = targetPkg;
8126            this.targetUid = targetUid;
8127            this.flags = flags;
8128        }
8129    }
8130
8131    /**
8132     * Like checkGrantUriPermissionLocked, but takes an Intent.
8133     */
8134    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8135            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8136        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8138                + " clip=" + (intent != null ? intent.getClipData() : null)
8139                + " from " + intent + "; flags=0x"
8140                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8141
8142        if (targetPkg == null) {
8143            throw new NullPointerException("targetPkg");
8144        }
8145
8146        if (intent == null) {
8147            return null;
8148        }
8149        Uri data = intent.getData();
8150        ClipData clip = intent.getClipData();
8151        if (data == null && clip == null) {
8152            return null;
8153        }
8154        // Default userId for uris in the intent (if they don't specify it themselves)
8155        int contentUserHint = intent.getContentUserHint();
8156        if (contentUserHint == UserHandle.USER_CURRENT) {
8157            contentUserHint = UserHandle.getUserId(callingUid);
8158        }
8159        final IPackageManager pm = AppGlobals.getPackageManager();
8160        int targetUid;
8161        if (needed != null) {
8162            targetUid = needed.targetUid;
8163        } else {
8164            try {
8165                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8166                        targetUserId);
8167            } catch (RemoteException ex) {
8168                return null;
8169            }
8170            if (targetUid < 0) {
8171                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                        "Can't grant URI permission no uid for: " + targetPkg
8173                        + " on user " + targetUserId);
8174                return null;
8175            }
8176        }
8177        if (data != null) {
8178            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8179            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8180                    targetUid);
8181            if (targetUid > 0) {
8182                if (needed == null) {
8183                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8184                }
8185                needed.add(grantUri);
8186            }
8187        }
8188        if (clip != null) {
8189            for (int i=0; i<clip.getItemCount(); i++) {
8190                Uri uri = clip.getItemAt(i).getUri();
8191                if (uri != null) {
8192                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8193                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8194                            targetUid);
8195                    if (targetUid > 0) {
8196                        if (needed == null) {
8197                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8198                        }
8199                        needed.add(grantUri);
8200                    }
8201                } else {
8202                    Intent clipIntent = clip.getItemAt(i).getIntent();
8203                    if (clipIntent != null) {
8204                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8205                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8206                        if (newNeeded != null) {
8207                            needed = newNeeded;
8208                        }
8209                    }
8210                }
8211            }
8212        }
8213
8214        return needed;
8215    }
8216
8217    /**
8218     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8219     */
8220    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8221            UriPermissionOwner owner) {
8222        if (needed != null) {
8223            for (int i=0; i<needed.size(); i++) {
8224                GrantUri grantUri = needed.get(i);
8225                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8226                        grantUri, needed.flags, owner);
8227            }
8228        }
8229    }
8230
8231    void grantUriPermissionFromIntentLocked(int callingUid,
8232            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8233        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8234                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8235        if (needed == null) {
8236            return;
8237        }
8238
8239        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8240    }
8241
8242    /**
8243     * @param uri This uri must NOT contain an embedded userId.
8244     * @param userId The userId in which the uri is to be resolved.
8245     */
8246    @Override
8247    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8248            final int modeFlags, int userId) {
8249        enforceNotIsolatedCaller("grantUriPermission");
8250        GrantUri grantUri = new GrantUri(userId, uri, false);
8251        synchronized(this) {
8252            final ProcessRecord r = getRecordForAppLocked(caller);
8253            if (r == null) {
8254                throw new SecurityException("Unable to find app for caller "
8255                        + caller
8256                        + " when granting permission to uri " + grantUri);
8257            }
8258            if (targetPkg == null) {
8259                throw new IllegalArgumentException("null target");
8260            }
8261            if (grantUri == null) {
8262                throw new IllegalArgumentException("null uri");
8263            }
8264
8265            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8266                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8267                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8268                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8269
8270            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8271                    UserHandle.getUserId(r.uid));
8272        }
8273    }
8274
8275    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8276        if (perm.modeFlags == 0) {
8277            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8278                    perm.targetUid);
8279            if (perms != null) {
8280                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8282
8283                perms.remove(perm.uri);
8284                if (perms.isEmpty()) {
8285                    mGrantedUriPermissions.remove(perm.targetUid);
8286                }
8287            }
8288        }
8289    }
8290
8291    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8292        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293                "Revoking all granted permissions to " + grantUri);
8294
8295        final IPackageManager pm = AppGlobals.getPackageManager();
8296        final String authority = grantUri.uri.getAuthority();
8297        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8298        if (pi == null) {
8299            Slog.w(TAG, "No content provider found for permission revoke: "
8300                    + grantUri.toSafeString());
8301            return;
8302        }
8303
8304        // Does the caller have this permission on the URI?
8305        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8306            // If they don't have direct access to the URI, then revoke any
8307            // ownerless URI permissions that have been granted to them.
8308            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8309            if (perms != null) {
8310                boolean persistChanged = false;
8311                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8312                    final UriPermission perm = it.next();
8313                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8314                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8315                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316                                "Revoking non-owned " + perm.targetUid
8317                                + " permission to " + perm.uri);
8318                        persistChanged |= perm.revokeModes(
8319                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8320                        if (perm.modeFlags == 0) {
8321                            it.remove();
8322                        }
8323                    }
8324                }
8325                if (perms.isEmpty()) {
8326                    mGrantedUriPermissions.remove(callingUid);
8327                }
8328                if (persistChanged) {
8329                    schedulePersistUriGrants();
8330                }
8331            }
8332            return;
8333        }
8334
8335        boolean persistChanged = false;
8336
8337        // Go through all of the permissions and remove any that match.
8338        int N = mGrantedUriPermissions.size();
8339        for (int i = 0; i < N; i++) {
8340            final int targetUid = mGrantedUriPermissions.keyAt(i);
8341            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8342
8343            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8344                final UriPermission perm = it.next();
8345                if (perm.uri.sourceUserId == grantUri.sourceUserId
8346                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8347                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8349                    persistChanged |= perm.revokeModes(
8350                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8351                    if (perm.modeFlags == 0) {
8352                        it.remove();
8353                    }
8354                }
8355            }
8356
8357            if (perms.isEmpty()) {
8358                mGrantedUriPermissions.remove(targetUid);
8359                N--;
8360                i--;
8361            }
8362        }
8363
8364        if (persistChanged) {
8365            schedulePersistUriGrants();
8366        }
8367    }
8368
8369    /**
8370     * @param uri This uri must NOT contain an embedded userId.
8371     * @param userId The userId in which the uri is to be resolved.
8372     */
8373    @Override
8374    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8375            int userId) {
8376        enforceNotIsolatedCaller("revokeUriPermission");
8377        synchronized(this) {
8378            final ProcessRecord r = getRecordForAppLocked(caller);
8379            if (r == null) {
8380                throw new SecurityException("Unable to find app for caller "
8381                        + caller
8382                        + " when revoking permission to uri " + uri);
8383            }
8384            if (uri == null) {
8385                Slog.w(TAG, "revokeUriPermission: null uri");
8386                return;
8387            }
8388
8389            if (!Intent.isAccessUriMode(modeFlags)) {
8390                return;
8391            }
8392
8393            final String authority = uri.getAuthority();
8394            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8395            if (pi == null) {
8396                Slog.w(TAG, "No content provider found for permission revoke: "
8397                        + uri.toSafeString());
8398                return;
8399            }
8400
8401            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8402        }
8403    }
8404
8405    /**
8406     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8407     * given package.
8408     *
8409     * @param packageName Package name to match, or {@code null} to apply to all
8410     *            packages.
8411     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8412     *            to all users.
8413     * @param persistable If persistable grants should be removed.
8414     */
8415    private void removeUriPermissionsForPackageLocked(
8416            String packageName, int userHandle, boolean persistable) {
8417        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8418            throw new IllegalArgumentException("Must narrow by either package or user");
8419        }
8420
8421        boolean persistChanged = false;
8422
8423        int N = mGrantedUriPermissions.size();
8424        for (int i = 0; i < N; i++) {
8425            final int targetUid = mGrantedUriPermissions.keyAt(i);
8426            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8427
8428            // Only inspect grants matching user
8429            if (userHandle == UserHandle.USER_ALL
8430                    || userHandle == UserHandle.getUserId(targetUid)) {
8431                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8432                    final UriPermission perm = it.next();
8433
8434                    // Only inspect grants matching package
8435                    if (packageName == null || perm.sourcePkg.equals(packageName)
8436                            || perm.targetPkg.equals(packageName)) {
8437                        persistChanged |= perm.revokeModes(persistable
8438                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8439
8440                        // Only remove when no modes remain; any persisted grants
8441                        // will keep this alive.
8442                        if (perm.modeFlags == 0) {
8443                            it.remove();
8444                        }
8445                    }
8446                }
8447
8448                if (perms.isEmpty()) {
8449                    mGrantedUriPermissions.remove(targetUid);
8450                    N--;
8451                    i--;
8452                }
8453            }
8454        }
8455
8456        if (persistChanged) {
8457            schedulePersistUriGrants();
8458        }
8459    }
8460
8461    @Override
8462    public IBinder newUriPermissionOwner(String name) {
8463        enforceNotIsolatedCaller("newUriPermissionOwner");
8464        synchronized(this) {
8465            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8466            return owner.getExternalTokenLocked();
8467        }
8468    }
8469
8470    @Override
8471    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8472        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8473        synchronized(this) {
8474            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8475            if (r == null) {
8476                throw new IllegalArgumentException("Activity does not exist; token="
8477                        + activityToken);
8478            }
8479            return r.getUriPermissionsLocked().getExternalTokenLocked();
8480        }
8481    }
8482    /**
8483     * @param uri This uri must NOT contain an embedded userId.
8484     * @param sourceUserId The userId in which the uri is to be resolved.
8485     * @param targetUserId The userId of the app that receives the grant.
8486     */
8487    @Override
8488    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8489            final int modeFlags, int sourceUserId, int targetUserId) {
8490        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8491                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8492                "grantUriPermissionFromOwner", null);
8493        synchronized(this) {
8494            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8495            if (owner == null) {
8496                throw new IllegalArgumentException("Unknown owner: " + token);
8497            }
8498            if (fromUid != Binder.getCallingUid()) {
8499                if (Binder.getCallingUid() != Process.myUid()) {
8500                    // Only system code can grant URI permissions on behalf
8501                    // of other users.
8502                    throw new SecurityException("nice try");
8503                }
8504            }
8505            if (targetPkg == null) {
8506                throw new IllegalArgumentException("null target");
8507            }
8508            if (uri == null) {
8509                throw new IllegalArgumentException("null uri");
8510            }
8511
8512            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8513                    modeFlags, owner, targetUserId);
8514        }
8515    }
8516
8517    /**
8518     * @param uri This uri must NOT contain an embedded userId.
8519     * @param userId The userId in which the uri is to be resolved.
8520     */
8521    @Override
8522    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8523        synchronized(this) {
8524            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8525            if (owner == null) {
8526                throw new IllegalArgumentException("Unknown owner: " + token);
8527            }
8528
8529            if (uri == null) {
8530                owner.removeUriPermissionsLocked(mode);
8531            } else {
8532                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8533            }
8534        }
8535    }
8536
8537    private void schedulePersistUriGrants() {
8538        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8539            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8540                    10 * DateUtils.SECOND_IN_MILLIS);
8541        }
8542    }
8543
8544    private void writeGrantedUriPermissions() {
8545        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8546
8547        // Snapshot permissions so we can persist without lock
8548        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8549        synchronized (this) {
8550            final int size = mGrantedUriPermissions.size();
8551            for (int i = 0; i < size; i++) {
8552                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8553                for (UriPermission perm : perms.values()) {
8554                    if (perm.persistedModeFlags != 0) {
8555                        persist.add(perm.snapshot());
8556                    }
8557                }
8558            }
8559        }
8560
8561        FileOutputStream fos = null;
8562        try {
8563            fos = mGrantFile.startWrite();
8564
8565            XmlSerializer out = new FastXmlSerializer();
8566            out.setOutput(fos, StandardCharsets.UTF_8.name());
8567            out.startDocument(null, true);
8568            out.startTag(null, TAG_URI_GRANTS);
8569            for (UriPermission.Snapshot perm : persist) {
8570                out.startTag(null, TAG_URI_GRANT);
8571                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8572                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8573                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8574                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8575                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8576                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8577                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8578                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8579                out.endTag(null, TAG_URI_GRANT);
8580            }
8581            out.endTag(null, TAG_URI_GRANTS);
8582            out.endDocument();
8583
8584            mGrantFile.finishWrite(fos);
8585        } catch (IOException e) {
8586            if (fos != null) {
8587                mGrantFile.failWrite(fos);
8588            }
8589        }
8590    }
8591
8592    private void readGrantedUriPermissionsLocked() {
8593        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8594
8595        final long now = System.currentTimeMillis();
8596
8597        FileInputStream fis = null;
8598        try {
8599            fis = mGrantFile.openRead();
8600            final XmlPullParser in = Xml.newPullParser();
8601            in.setInput(fis, StandardCharsets.UTF_8.name());
8602
8603            int type;
8604            while ((type = in.next()) != END_DOCUMENT) {
8605                final String tag = in.getName();
8606                if (type == START_TAG) {
8607                    if (TAG_URI_GRANT.equals(tag)) {
8608                        final int sourceUserId;
8609                        final int targetUserId;
8610                        final int userHandle = readIntAttribute(in,
8611                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8612                        if (userHandle != UserHandle.USER_NULL) {
8613                            // For backwards compatibility.
8614                            sourceUserId = userHandle;
8615                            targetUserId = userHandle;
8616                        } else {
8617                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8618                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8619                        }
8620                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8621                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8622                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8623                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8624                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8625                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8626
8627                        // Sanity check that provider still belongs to source package
8628                        final ProviderInfo pi = getProviderInfoLocked(
8629                                uri.getAuthority(), sourceUserId);
8630                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8631                            int targetUid = -1;
8632                            try {
8633                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8634                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8635                            } catch (RemoteException e) {
8636                            }
8637                            if (targetUid != -1) {
8638                                final UriPermission perm = findOrCreateUriPermissionLocked(
8639                                        sourcePkg, targetPkg, targetUid,
8640                                        new GrantUri(sourceUserId, uri, prefix));
8641                                perm.initPersistedModes(modeFlags, createdTime);
8642                            }
8643                        } else {
8644                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8645                                    + " but instead found " + pi);
8646                        }
8647                    }
8648                }
8649            }
8650        } catch (FileNotFoundException e) {
8651            // Missing grants is okay
8652        } catch (IOException e) {
8653            Slog.wtf(TAG, "Failed reading Uri grants", e);
8654        } catch (XmlPullParserException e) {
8655            Slog.wtf(TAG, "Failed reading Uri grants", e);
8656        } finally {
8657            IoUtils.closeQuietly(fis);
8658        }
8659    }
8660
8661    /**
8662     * @param uri This uri must NOT contain an embedded userId.
8663     * @param userId The userId in which the uri is to be resolved.
8664     */
8665    @Override
8666    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8667        enforceNotIsolatedCaller("takePersistableUriPermission");
8668
8669        Preconditions.checkFlagsArgument(modeFlags,
8670                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8671
8672        synchronized (this) {
8673            final int callingUid = Binder.getCallingUid();
8674            boolean persistChanged = false;
8675            GrantUri grantUri = new GrantUri(userId, uri, false);
8676
8677            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8678                    new GrantUri(userId, uri, false));
8679            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8680                    new GrantUri(userId, uri, true));
8681
8682            final boolean exactValid = (exactPerm != null)
8683                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8684            final boolean prefixValid = (prefixPerm != null)
8685                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8686
8687            if (!(exactValid || prefixValid)) {
8688                throw new SecurityException("No persistable permission grants found for UID "
8689                        + callingUid + " and Uri " + grantUri.toSafeString());
8690            }
8691
8692            if (exactValid) {
8693                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8694            }
8695            if (prefixValid) {
8696                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8697            }
8698
8699            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8700
8701            if (persistChanged) {
8702                schedulePersistUriGrants();
8703            }
8704        }
8705    }
8706
8707    /**
8708     * @param uri This uri must NOT contain an embedded userId.
8709     * @param userId The userId in which the uri is to be resolved.
8710     */
8711    @Override
8712    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8713        enforceNotIsolatedCaller("releasePersistableUriPermission");
8714
8715        Preconditions.checkFlagsArgument(modeFlags,
8716                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8717
8718        synchronized (this) {
8719            final int callingUid = Binder.getCallingUid();
8720            boolean persistChanged = false;
8721
8722            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8723                    new GrantUri(userId, uri, false));
8724            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8725                    new GrantUri(userId, uri, true));
8726            if (exactPerm == null && prefixPerm == null) {
8727                throw new SecurityException("No permission grants found for UID " + callingUid
8728                        + " and Uri " + uri.toSafeString());
8729            }
8730
8731            if (exactPerm != null) {
8732                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8733                removeUriPermissionIfNeededLocked(exactPerm);
8734            }
8735            if (prefixPerm != null) {
8736                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8737                removeUriPermissionIfNeededLocked(prefixPerm);
8738            }
8739
8740            if (persistChanged) {
8741                schedulePersistUriGrants();
8742            }
8743        }
8744    }
8745
8746    /**
8747     * Prune any older {@link UriPermission} for the given UID until outstanding
8748     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8749     *
8750     * @return if any mutations occured that require persisting.
8751     */
8752    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8753        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8754        if (perms == null) return false;
8755        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8756
8757        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8758        for (UriPermission perm : perms.values()) {
8759            if (perm.persistedModeFlags != 0) {
8760                persisted.add(perm);
8761            }
8762        }
8763
8764        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8765        if (trimCount <= 0) return false;
8766
8767        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8768        for (int i = 0; i < trimCount; i++) {
8769            final UriPermission perm = persisted.get(i);
8770
8771            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8772                    "Trimming grant created at " + perm.persistedCreateTime);
8773
8774            perm.releasePersistableModes(~0);
8775            removeUriPermissionIfNeededLocked(perm);
8776        }
8777
8778        return true;
8779    }
8780
8781    @Override
8782    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8783            String packageName, boolean incoming) {
8784        enforceNotIsolatedCaller("getPersistedUriPermissions");
8785        Preconditions.checkNotNull(packageName, "packageName");
8786
8787        final int callingUid = Binder.getCallingUid();
8788        final IPackageManager pm = AppGlobals.getPackageManager();
8789        try {
8790            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8791                    UserHandle.getUserId(callingUid));
8792            if (packageUid != callingUid) {
8793                throw new SecurityException(
8794                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8795            }
8796        } catch (RemoteException e) {
8797            throw new SecurityException("Failed to verify package name ownership");
8798        }
8799
8800        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8801        synchronized (this) {
8802            if (incoming) {
8803                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8804                        callingUid);
8805                if (perms == null) {
8806                    Slog.w(TAG, "No permission grants found for " + packageName);
8807                } else {
8808                    for (UriPermission perm : perms.values()) {
8809                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8810                            result.add(perm.buildPersistedPublicApiObject());
8811                        }
8812                    }
8813                }
8814            } else {
8815                final int size = mGrantedUriPermissions.size();
8816                for (int i = 0; i < size; i++) {
8817                    final ArrayMap<GrantUri, UriPermission> perms =
8818                            mGrantedUriPermissions.valueAt(i);
8819                    for (UriPermission perm : perms.values()) {
8820                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8821                            result.add(perm.buildPersistedPublicApiObject());
8822                        }
8823                    }
8824                }
8825            }
8826        }
8827        return new ParceledListSlice<android.content.UriPermission>(result);
8828    }
8829
8830    @Override
8831    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8832            String packageName, int userId) {
8833        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8834                "getGrantedUriPermissions");
8835
8836        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8837        synchronized (this) {
8838            final int size = mGrantedUriPermissions.size();
8839            for (int i = 0; i < size; i++) {
8840                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8841                for (UriPermission perm : perms.values()) {
8842                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8843                            && perm.persistedModeFlags != 0) {
8844                        result.add(perm.buildPersistedPublicApiObject());
8845                    }
8846                }
8847            }
8848        }
8849        return new ParceledListSlice<android.content.UriPermission>(result);
8850    }
8851
8852    @Override
8853    public void clearGrantedUriPermissions(String packageName, int userId) {
8854        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8855                "clearGrantedUriPermissions");
8856        removeUriPermissionsForPackageLocked(packageName, userId, true);
8857    }
8858
8859    @Override
8860    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8861        synchronized (this) {
8862            ProcessRecord app =
8863                who != null ? getRecordForAppLocked(who) : null;
8864            if (app == null) return;
8865
8866            Message msg = Message.obtain();
8867            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8868            msg.obj = app;
8869            msg.arg1 = waiting ? 1 : 0;
8870            mUiHandler.sendMessage(msg);
8871        }
8872    }
8873
8874    @Override
8875    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8876        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8877        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8878        outInfo.availMem = Process.getFreeMemory();
8879        outInfo.totalMem = Process.getTotalMemory();
8880        outInfo.threshold = homeAppMem;
8881        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8882        outInfo.hiddenAppThreshold = cachedAppMem;
8883        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8884                ProcessList.SERVICE_ADJ);
8885        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8886                ProcessList.VISIBLE_APP_ADJ);
8887        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8888                ProcessList.FOREGROUND_APP_ADJ);
8889    }
8890
8891    // =========================================================
8892    // TASK MANAGEMENT
8893    // =========================================================
8894
8895    @Override
8896    public List<IAppTask> getAppTasks(String callingPackage) {
8897        int callingUid = Binder.getCallingUid();
8898        long ident = Binder.clearCallingIdentity();
8899
8900        synchronized(this) {
8901            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8902            try {
8903                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8904
8905                final int N = mRecentTasks.size();
8906                for (int i = 0; i < N; i++) {
8907                    TaskRecord tr = mRecentTasks.get(i);
8908                    // Skip tasks that do not match the caller.  We don't need to verify
8909                    // callingPackage, because we are also limiting to callingUid and know
8910                    // that will limit to the correct security sandbox.
8911                    if (tr.effectiveUid != callingUid) {
8912                        continue;
8913                    }
8914                    Intent intent = tr.getBaseIntent();
8915                    if (intent == null ||
8916                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8917                        continue;
8918                    }
8919                    ActivityManager.RecentTaskInfo taskInfo =
8920                            createRecentTaskInfoFromTaskRecord(tr);
8921                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8922                    list.add(taskImpl);
8923                }
8924            } finally {
8925                Binder.restoreCallingIdentity(ident);
8926            }
8927            return list;
8928        }
8929    }
8930
8931    @Override
8932    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8933        final int callingUid = Binder.getCallingUid();
8934        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8935
8936        synchronized(this) {
8937            if (DEBUG_ALL) Slog.v(
8938                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8939
8940            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8941                    callingUid);
8942
8943            // TODO: Improve with MRU list from all ActivityStacks.
8944            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8945        }
8946
8947        return list;
8948    }
8949
8950    /**
8951     * Creates a new RecentTaskInfo from a TaskRecord.
8952     */
8953    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8954        // Update the task description to reflect any changes in the task stack
8955        tr.updateTaskDescription();
8956
8957        // Compose the recent task info
8958        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8959        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8960        rti.persistentId = tr.taskId;
8961        rti.baseIntent = new Intent(tr.getBaseIntent());
8962        rti.origActivity = tr.origActivity;
8963        rti.realActivity = tr.realActivity;
8964        rti.description = tr.lastDescription;
8965        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8966        rti.userId = tr.userId;
8967        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8968        rti.firstActiveTime = tr.firstActiveTime;
8969        rti.lastActiveTime = tr.lastActiveTime;
8970        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8971        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8972        rti.numActivities = 0;
8973        if (tr.mBounds != null) {
8974            rti.bounds = new Rect(tr.mBounds);
8975        }
8976        rti.isDockable = tr.canGoInDockedStack();
8977        rti.resizeMode = tr.mResizeMode;
8978
8979        ActivityRecord base = null;
8980        ActivityRecord top = null;
8981        ActivityRecord tmp;
8982
8983        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8984            tmp = tr.mActivities.get(i);
8985            if (tmp.finishing) {
8986                continue;
8987            }
8988            base = tmp;
8989            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8990                top = base;
8991            }
8992            rti.numActivities++;
8993        }
8994
8995        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8996        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8997
8998        return rti;
8999    }
9000
9001    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9002        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9003                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9004        if (!allowed) {
9005            if (checkPermission(android.Manifest.permission.GET_TASKS,
9006                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9007                // Temporary compatibility: some existing apps on the system image may
9008                // still be requesting the old permission and not switched to the new
9009                // one; if so, we'll still allow them full access.  This means we need
9010                // to see if they are holding the old permission and are a system app.
9011                try {
9012                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9013                        allowed = true;
9014                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9015                                + " is using old GET_TASKS but privileged; allowing");
9016                    }
9017                } catch (RemoteException e) {
9018                }
9019            }
9020        }
9021        if (!allowed) {
9022            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9023                    + " does not hold REAL_GET_TASKS; limiting output");
9024        }
9025        return allowed;
9026    }
9027
9028    @Override
9029    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9030        final int callingUid = Binder.getCallingUid();
9031        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9032                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9033
9034        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9035        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9036        synchronized (this) {
9037            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9038                    callingUid);
9039            final boolean detailed = checkCallingPermission(
9040                    android.Manifest.permission.GET_DETAILED_TASKS)
9041                    == PackageManager.PERMISSION_GRANTED;
9042
9043            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9044                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9045                return Collections.emptyList();
9046            }
9047            mRecentTasks.loadUserRecentsLocked(userId);
9048
9049            final int recentsCount = mRecentTasks.size();
9050            ArrayList<ActivityManager.RecentTaskInfo> res =
9051                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9052
9053            final Set<Integer> includedUsers;
9054            if (includeProfiles) {
9055                includedUsers = mUserController.getProfileIds(userId);
9056            } else {
9057                includedUsers = new HashSet<>();
9058            }
9059            includedUsers.add(Integer.valueOf(userId));
9060
9061            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9062                TaskRecord tr = mRecentTasks.get(i);
9063                // Only add calling user or related users recent tasks
9064                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9065                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9066                    continue;
9067                }
9068
9069                if (tr.realActivitySuspended) {
9070                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9071                    continue;
9072                }
9073
9074                // Return the entry if desired by the caller.  We always return
9075                // the first entry, because callers always expect this to be the
9076                // foreground app.  We may filter others if the caller has
9077                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9078                // we should exclude the entry.
9079
9080                if (i == 0
9081                        || withExcluded
9082                        || (tr.intent == null)
9083                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9084                                == 0)) {
9085                    if (!allowed) {
9086                        // If the caller doesn't have the GET_TASKS permission, then only
9087                        // allow them to see a small subset of tasks -- their own and home.
9088                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9089                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9090                            continue;
9091                        }
9092                    }
9093                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9094                        if (tr.stack != null && tr.stack.isHomeStack()) {
9095                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9096                                    "Skipping, home stack task: " + tr);
9097                            continue;
9098                        }
9099                    }
9100                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9101                        final ActivityStack stack = tr.stack;
9102                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9103                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9104                                    "Skipping, top task in docked stack: " + tr);
9105                            continue;
9106                        }
9107                    }
9108                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9109                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9110                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9111                                    "Skipping, pinned stack task: " + tr);
9112                            continue;
9113                        }
9114                    }
9115                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9116                        // Don't include auto remove tasks that are finished or finishing.
9117                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9118                                "Skipping, auto-remove without activity: " + tr);
9119                        continue;
9120                    }
9121                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9122                            && !tr.isAvailable) {
9123                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9124                                "Skipping, unavail real act: " + tr);
9125                        continue;
9126                    }
9127
9128                    if (!tr.mUserSetupComplete) {
9129                        // Don't include task launched while user is not done setting-up.
9130                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9131                                "Skipping, user setup not complete: " + tr);
9132                        continue;
9133                    }
9134
9135                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9136                    if (!detailed) {
9137                        rti.baseIntent.replaceExtras((Bundle)null);
9138                    }
9139
9140                    res.add(rti);
9141                    maxNum--;
9142                }
9143            }
9144            return res;
9145        }
9146    }
9147
9148    @Override
9149    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9150        synchronized (this) {
9151            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9152                    "getTaskThumbnail()");
9153            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9154                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9155            if (tr != null) {
9156                return tr.getTaskThumbnailLocked();
9157            }
9158        }
9159        return null;
9160    }
9161
9162    @Override
9163    public int addAppTask(IBinder activityToken, Intent intent,
9164            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9165        final int callingUid = Binder.getCallingUid();
9166        final long callingIdent = Binder.clearCallingIdentity();
9167
9168        try {
9169            synchronized (this) {
9170                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9171                if (r == null) {
9172                    throw new IllegalArgumentException("Activity does not exist; token="
9173                            + activityToken);
9174                }
9175                ComponentName comp = intent.getComponent();
9176                if (comp == null) {
9177                    throw new IllegalArgumentException("Intent " + intent
9178                            + " must specify explicit component");
9179                }
9180                if (thumbnail.getWidth() != mThumbnailWidth
9181                        || thumbnail.getHeight() != mThumbnailHeight) {
9182                    throw new IllegalArgumentException("Bad thumbnail size: got "
9183                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9184                            + mThumbnailWidth + "x" + mThumbnailHeight);
9185                }
9186                if (intent.getSelector() != null) {
9187                    intent.setSelector(null);
9188                }
9189                if (intent.getSourceBounds() != null) {
9190                    intent.setSourceBounds(null);
9191                }
9192                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9193                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9194                        // The caller has added this as an auto-remove task...  that makes no
9195                        // sense, so turn off auto-remove.
9196                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9197                    }
9198                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9199                    // Must be a new task.
9200                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9201                }
9202                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9203                    mLastAddedTaskActivity = null;
9204                }
9205                ActivityInfo ainfo = mLastAddedTaskActivity;
9206                if (ainfo == null) {
9207                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9208                            comp, 0, UserHandle.getUserId(callingUid));
9209                    if (ainfo.applicationInfo.uid != callingUid) {
9210                        throw new SecurityException(
9211                                "Can't add task for another application: target uid="
9212                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9213                    }
9214                }
9215
9216                // Use the full screen as the context for the task thumbnail
9217                final Point displaySize = new Point();
9218                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9219                r.task.stack.getDisplaySize(displaySize);
9220                thumbnailInfo.taskWidth = displaySize.x;
9221                thumbnailInfo.taskHeight = displaySize.y;
9222                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9223
9224                TaskRecord task = new TaskRecord(this,
9225                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9226                        ainfo, intent, description, thumbnailInfo);
9227
9228                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9229                if (trimIdx >= 0) {
9230                    // If this would have caused a trim, then we'll abort because that
9231                    // means it would be added at the end of the list but then just removed.
9232                    return INVALID_TASK_ID;
9233                }
9234
9235                final int N = mRecentTasks.size();
9236                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9237                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9238                    tr.removedFromRecents();
9239                }
9240
9241                task.inRecents = true;
9242                mRecentTasks.add(task);
9243                r.task.stack.addTask(task, false, "addAppTask");
9244
9245                task.setLastThumbnailLocked(thumbnail);
9246                task.freeLastThumbnail();
9247
9248                return task.taskId;
9249            }
9250        } finally {
9251            Binder.restoreCallingIdentity(callingIdent);
9252        }
9253    }
9254
9255    @Override
9256    public Point getAppTaskThumbnailSize() {
9257        synchronized (this) {
9258            return new Point(mThumbnailWidth,  mThumbnailHeight);
9259        }
9260    }
9261
9262    @Override
9263    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9264        synchronized (this) {
9265            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9266            if (r != null) {
9267                r.setTaskDescription(td);
9268                r.task.updateTaskDescription();
9269            }
9270        }
9271    }
9272
9273    @Override
9274    public void setTaskResizeable(int taskId, int resizeableMode) {
9275        synchronized (this) {
9276            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9277                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9278            if (task == null) {
9279                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9280                return;
9281            }
9282            if (task.mResizeMode != resizeableMode) {
9283                task.mResizeMode = resizeableMode;
9284                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9285                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9286                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9287            }
9288        }
9289    }
9290
9291    @Override
9292    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9293        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9294        long ident = Binder.clearCallingIdentity();
9295        try {
9296            synchronized (this) {
9297                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9298                if (task == null) {
9299                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9300                    return;
9301                }
9302                int stackId = task.stack.mStackId;
9303                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9304                // in crop windows resize mode or if the task size is affected by the docked stack
9305                // changing size. No need to update configuration.
9306                if (bounds != null && task.inCropWindowsResizeMode()
9307                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9308                    mWindowManager.scrollTask(task.taskId, bounds);
9309                    return;
9310                }
9311
9312                // Place the task in the right stack if it isn't there already based on
9313                // the requested bounds.
9314                // The stack transition logic is:
9315                // - a null bounds on a freeform task moves that task to fullscreen
9316                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9317                //   that task to freeform
9318                // - otherwise the task is not moved
9319                if (!StackId.isTaskResizeAllowed(stackId)) {
9320                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9321                }
9322                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9323                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9324                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9325                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9326                }
9327                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9328                if (stackId != task.stack.mStackId) {
9329                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9330                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9331                    preserveWindow = false;
9332                }
9333
9334                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9335                        false /* deferResume */);
9336            }
9337        } finally {
9338            Binder.restoreCallingIdentity(ident);
9339        }
9340    }
9341
9342    @Override
9343    public Rect getTaskBounds(int taskId) {
9344        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9345        long ident = Binder.clearCallingIdentity();
9346        Rect rect = new Rect();
9347        try {
9348            synchronized (this) {
9349                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351                if (task == null) {
9352                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9353                    return rect;
9354                }
9355                if (task.stack != null) {
9356                    // Return the bounds from window manager since it will be adjusted for various
9357                    // things like the presense of a docked stack for tasks that aren't resizeable.
9358                    mWindowManager.getTaskBounds(task.taskId, rect);
9359                } else {
9360                    // Task isn't in window manager yet since it isn't associated with a stack.
9361                    // Return the persist value from activity manager
9362                    if (task.mBounds != null) {
9363                        rect.set(task.mBounds);
9364                    } else if (task.mLastNonFullscreenBounds != null) {
9365                        rect.set(task.mLastNonFullscreenBounds);
9366                    }
9367                }
9368            }
9369        } finally {
9370            Binder.restoreCallingIdentity(ident);
9371        }
9372        return rect;
9373    }
9374
9375    @Override
9376    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9377        if (userId != UserHandle.getCallingUserId()) {
9378            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9379                    "getTaskDescriptionIcon");
9380        }
9381        final File passedIconFile = new File(filePath);
9382        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9383                passedIconFile.getName());
9384        if (!legitIconFile.getPath().equals(filePath)
9385                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9386            throw new IllegalArgumentException("Bad file path: " + filePath
9387                    + " passed for userId " + userId);
9388        }
9389        return mRecentTasks.getTaskDescriptionIcon(filePath);
9390    }
9391
9392    @Override
9393    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9394            throws RemoteException {
9395        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9396                opts.getCustomInPlaceResId() == 0) {
9397            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9398                    "with valid animation");
9399        }
9400        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9401        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9402                opts.getCustomInPlaceResId());
9403        mWindowManager.executeAppTransition();
9404    }
9405
9406    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9407            boolean removeFromRecents) {
9408        if (removeFromRecents) {
9409            mRecentTasks.remove(tr);
9410            tr.removedFromRecents();
9411        }
9412        ComponentName component = tr.getBaseIntent().getComponent();
9413        if (component == null) {
9414            Slog.w(TAG, "No component for base intent of task: " + tr);
9415            return;
9416        }
9417
9418        // Find any running services associated with this app and stop if needed.
9419        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9420
9421        if (!killProcess) {
9422            return;
9423        }
9424
9425        // Determine if the process(es) for this task should be killed.
9426        final String pkg = component.getPackageName();
9427        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9428        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9429        for (int i = 0; i < pmap.size(); i++) {
9430
9431            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9432            for (int j = 0; j < uids.size(); j++) {
9433                ProcessRecord proc = uids.valueAt(j);
9434                if (proc.userId != tr.userId) {
9435                    // Don't kill process for a different user.
9436                    continue;
9437                }
9438                if (proc == mHomeProcess) {
9439                    // Don't kill the home process along with tasks from the same package.
9440                    continue;
9441                }
9442                if (!proc.pkgList.containsKey(pkg)) {
9443                    // Don't kill process that is not associated with this task.
9444                    continue;
9445                }
9446
9447                for (int k = 0; k < proc.activities.size(); k++) {
9448                    TaskRecord otherTask = proc.activities.get(k).task;
9449                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9450                        // Don't kill process(es) that has an activity in a different task that is
9451                        // also in recents.
9452                        return;
9453                    }
9454                }
9455
9456                if (proc.foregroundServices) {
9457                    // Don't kill process(es) with foreground service.
9458                    return;
9459                }
9460
9461                // Add process to kill list.
9462                procsToKill.add(proc);
9463            }
9464        }
9465
9466        // Kill the running processes.
9467        for (int i = 0; i < procsToKill.size(); i++) {
9468            ProcessRecord pr = procsToKill.get(i);
9469            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9470                    && pr.curReceiver == null) {
9471                pr.kill("remove task", true);
9472            } else {
9473                // We delay killing processes that are not in the background or running a receiver.
9474                pr.waitingToKill = "remove task";
9475            }
9476        }
9477    }
9478
9479    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9480        // Remove all tasks with activities in the specified package from the list of recent tasks
9481        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9482            TaskRecord tr = mRecentTasks.get(i);
9483            if (tr.userId != userId) continue;
9484
9485            ComponentName cn = tr.intent.getComponent();
9486            if (cn != null && cn.getPackageName().equals(packageName)) {
9487                // If the package name matches, remove the task.
9488                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9489            }
9490        }
9491    }
9492
9493    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9494            int userId) {
9495
9496        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9497            TaskRecord tr = mRecentTasks.get(i);
9498            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9499                continue;
9500            }
9501
9502            ComponentName cn = tr.intent.getComponent();
9503            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9504                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9505            if (sameComponent) {
9506                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9507            }
9508        }
9509    }
9510
9511    /**
9512     * Removes the task with the specified task id.
9513     *
9514     * @param taskId Identifier of the task to be removed.
9515     * @param killProcess Kill any process associated with the task if possible.
9516     * @param removeFromRecents Whether to also remove the task from recents.
9517     * @return Returns true if the given task was found and removed.
9518     */
9519    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9520            boolean removeFromRecents) {
9521        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9522                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9523        if (tr != null) {
9524            tr.removeTaskActivitiesLocked();
9525            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9526            if (tr.isPersistable) {
9527                notifyTaskPersisterLocked(null, true);
9528            }
9529            return true;
9530        }
9531        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9532        return false;
9533    }
9534
9535    @Override
9536    public void removeStack(int stackId) {
9537        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9538        if (stackId == HOME_STACK_ID) {
9539            throw new IllegalArgumentException("Removing home stack is not allowed.");
9540        }
9541
9542        synchronized (this) {
9543            final long ident = Binder.clearCallingIdentity();
9544            try {
9545                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9546                if (stack == null) {
9547                    return;
9548                }
9549                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9550                for (int i = tasks.size() - 1; i >= 0; i--) {
9551                    removeTaskByIdLocked(
9552                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9553                }
9554            } finally {
9555                Binder.restoreCallingIdentity(ident);
9556            }
9557        }
9558    }
9559
9560    @Override
9561    public boolean removeTask(int taskId) {
9562        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9563        synchronized (this) {
9564            final long ident = Binder.clearCallingIdentity();
9565            try {
9566                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9567            } finally {
9568                Binder.restoreCallingIdentity(ident);
9569            }
9570        }
9571    }
9572
9573    /**
9574     * TODO: Add mController hook
9575     */
9576    @Override
9577    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9578        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9579
9580        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9581        synchronized(this) {
9582            moveTaskToFrontLocked(taskId, flags, bOptions);
9583        }
9584    }
9585
9586    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9587        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9588
9589        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9590                Binder.getCallingUid(), -1, -1, "Task to front")) {
9591            ActivityOptions.abort(options);
9592            return;
9593        }
9594        final long origId = Binder.clearCallingIdentity();
9595        try {
9596            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9597            if (task == null) {
9598                Slog.d(TAG, "Could not find task for id: "+ taskId);
9599                return;
9600            }
9601            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9602                mStackSupervisor.showLockTaskToast();
9603                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9604                return;
9605            }
9606            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9607            if (prev != null && prev.isRecentsActivity()) {
9608                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9609            }
9610            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9611                    false /* forceNonResizable */);
9612        } finally {
9613            Binder.restoreCallingIdentity(origId);
9614        }
9615        ActivityOptions.abort(options);
9616    }
9617
9618    /**
9619     * Moves an activity, and all of the other activities within the same task, to the bottom
9620     * of the history stack.  The activity's order within the task is unchanged.
9621     *
9622     * @param token A reference to the activity we wish to move
9623     * @param nonRoot If false then this only works if the activity is the root
9624     *                of a task; if true it will work for any activity in a task.
9625     * @return Returns true if the move completed, false if not.
9626     */
9627    @Override
9628    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9629        enforceNotIsolatedCaller("moveActivityTaskToBack");
9630        synchronized(this) {
9631            final long origId = Binder.clearCallingIdentity();
9632            try {
9633                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9634                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9635                if (task != null) {
9636                    if (mStackSupervisor.isLockedTask(task)) {
9637                        mStackSupervisor.showLockTaskToast();
9638                        return false;
9639                    }
9640                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9641                }
9642            } finally {
9643                Binder.restoreCallingIdentity(origId);
9644            }
9645        }
9646        return false;
9647    }
9648
9649    @Override
9650    public void moveTaskBackwards(int task) {
9651        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9652                "moveTaskBackwards()");
9653
9654        synchronized(this) {
9655            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9656                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9657                return;
9658            }
9659            final long origId = Binder.clearCallingIdentity();
9660            moveTaskBackwardsLocked(task);
9661            Binder.restoreCallingIdentity(origId);
9662        }
9663    }
9664
9665    private final void moveTaskBackwardsLocked(int task) {
9666        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9667    }
9668
9669    @Override
9670    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9671            IActivityContainerCallback callback) throws RemoteException {
9672        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9673        synchronized (this) {
9674            if (parentActivityToken == null) {
9675                throw new IllegalArgumentException("parent token must not be null");
9676            }
9677            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9678            if (r == null) {
9679                return null;
9680            }
9681            if (callback == null) {
9682                throw new IllegalArgumentException("callback must not be null");
9683            }
9684            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9685        }
9686    }
9687
9688    @Override
9689    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9690        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9691        synchronized (this) {
9692            mStackSupervisor.deleteActivityContainer(container);
9693        }
9694    }
9695
9696    @Override
9697    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9698        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9699        synchronized (this) {
9700            final int stackId = mStackSupervisor.getNextStackId();
9701            final ActivityStack stack =
9702                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9703            if (stack == null) {
9704                return null;
9705            }
9706            return stack.mActivityContainer;
9707        }
9708    }
9709
9710    @Override
9711    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9712        synchronized (this) {
9713            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9714            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9715                return stack.mActivityContainer.getDisplayId();
9716            }
9717            return Display.DEFAULT_DISPLAY;
9718        }
9719    }
9720
9721    @Override
9722    public int getActivityStackId(IBinder token) throws RemoteException {
9723        synchronized (this) {
9724            ActivityStack stack = ActivityRecord.getStackLocked(token);
9725            if (stack == null) {
9726                return INVALID_STACK_ID;
9727            }
9728            return stack.mStackId;
9729        }
9730    }
9731
9732    @Override
9733    public void exitFreeformMode(IBinder token) throws RemoteException {
9734        synchronized (this) {
9735            long ident = Binder.clearCallingIdentity();
9736            try {
9737                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9738                if (r == null) {
9739                    throw new IllegalArgumentException(
9740                            "exitFreeformMode: No activity record matching token=" + token);
9741                }
9742                final ActivityStack stack = r.getStackLocked(token);
9743                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9744                    throw new IllegalStateException(
9745                            "exitFreeformMode: You can only go fullscreen from freeform.");
9746                }
9747                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9748                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9749                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9750            } finally {
9751                Binder.restoreCallingIdentity(ident);
9752            }
9753        }
9754    }
9755
9756    @Override
9757    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9758        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9759        if (stackId == HOME_STACK_ID) {
9760            throw new IllegalArgumentException(
9761                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9762        }
9763        synchronized (this) {
9764            long ident = Binder.clearCallingIdentity();
9765            try {
9766                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9767                        + " to stackId=" + stackId + " toTop=" + toTop);
9768                if (stackId == DOCKED_STACK_ID) {
9769                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9770                            null /* initialBounds */);
9771                }
9772                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9773                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9774                if (result && stackId == DOCKED_STACK_ID) {
9775                    // If task moved to docked stack - show recents if needed.
9776                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9777                            "moveTaskToDockedStack");
9778                }
9779            } finally {
9780                Binder.restoreCallingIdentity(ident);
9781            }
9782        }
9783    }
9784
9785    @Override
9786    public void swapDockedAndFullscreenStack() throws RemoteException {
9787        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9788        synchronized (this) {
9789            long ident = Binder.clearCallingIdentity();
9790            try {
9791                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9792                        FULLSCREEN_WORKSPACE_STACK_ID);
9793                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9794                        : null;
9795                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9796                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9797                        : null;
9798                if (topTask == null || tasks == null || tasks.size() == 0) {
9799                    Slog.w(TAG,
9800                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9801                    return;
9802                }
9803
9804                // TODO: App transition
9805                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9806
9807                // Defer the resume so resume/pausing while moving stacks is dangerous.
9808                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9809                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9810                        ANIMATE, true /* deferResume */);
9811                final int size = tasks.size();
9812                for (int i = 0; i < size; i++) {
9813                    final int id = tasks.get(i).taskId;
9814                    if (id == topTask.taskId) {
9815                        continue;
9816                    }
9817                    mStackSupervisor.moveTaskToStackLocked(id,
9818                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9819                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9820                }
9821
9822                // Because we deferred the resume, to avoid conflicts with stack switches while
9823                // resuming, we need to do it after all the tasks are moved.
9824                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9825                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9826
9827                mWindowManager.executeAppTransition();
9828            } finally {
9829                Binder.restoreCallingIdentity(ident);
9830            }
9831        }
9832    }
9833
9834    /**
9835     * Moves the input task to the docked stack.
9836     *
9837     * @param taskId Id of task to move.
9838     * @param createMode The mode the docked stack should be created in if it doesn't exist
9839     *                   already. See
9840     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9841     *                   and
9842     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9843     * @param toTop If the task and stack should be moved to the top.
9844     * @param animate Whether we should play an animation for the moving the task
9845     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9846     *                      docked stack. Pass {@code null} to use default bounds.
9847     */
9848    @Override
9849    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9850            Rect initialBounds, boolean moveHomeStackFront) {
9851        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9852        synchronized (this) {
9853            long ident = Binder.clearCallingIdentity();
9854            try {
9855                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9856                        + " to createMode=" + createMode + " toTop=" + toTop);
9857                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9858                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9859                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9860                        animate, DEFER_RESUME);
9861                if (moved) {
9862                    if (moveHomeStackFront) {
9863                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9864                    }
9865                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9866                }
9867                return moved;
9868            } finally {
9869                Binder.restoreCallingIdentity(ident);
9870            }
9871        }
9872    }
9873
9874    /**
9875     * Moves the top activity in the input stackId to the pinned stack.
9876     *
9877     * @param stackId Id of stack to move the top activity to pinned stack.
9878     * @param bounds Bounds to use for pinned stack.
9879     *
9880     * @return True if the top activity of the input stack was successfully moved to the pinned
9881     *          stack.
9882     */
9883    @Override
9884    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9885        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9886        synchronized (this) {
9887            if (!mSupportsPictureInPicture) {
9888                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9889                        + "Device doesn't support picture-in-pciture mode");
9890            }
9891
9892            long ident = Binder.clearCallingIdentity();
9893            try {
9894                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899    }
9900
9901    @Override
9902    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9903            boolean preserveWindows, boolean animate, int animationDuration) {
9904        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9905        long ident = Binder.clearCallingIdentity();
9906        try {
9907            synchronized (this) {
9908                if (animate) {
9909                    if (stackId == PINNED_STACK_ID) {
9910                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9911                    } else {
9912                        throw new IllegalArgumentException("Stack: " + stackId
9913                                + " doesn't support animated resize.");
9914                    }
9915                } else {
9916                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9917                            null /* tempTaskInsetBounds */, preserveWindows,
9918                            allowResizeInDockedMode, !DEFER_RESUME);
9919                }
9920            }
9921        } finally {
9922            Binder.restoreCallingIdentity(ident);
9923        }
9924    }
9925
9926    @Override
9927    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9928            Rect tempDockedTaskInsetBounds,
9929            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9930        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9931                "resizeDockedStack()");
9932        long ident = Binder.clearCallingIdentity();
9933        try {
9934            synchronized (this) {
9935                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9936                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9937                        PRESERVE_WINDOWS);
9938            }
9939        } finally {
9940            Binder.restoreCallingIdentity(ident);
9941        }
9942    }
9943
9944    @Override
9945    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9946        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9947                "resizePinnedStack()");
9948        final long ident = Binder.clearCallingIdentity();
9949        try {
9950            synchronized (this) {
9951                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9952            }
9953        } finally {
9954            Binder.restoreCallingIdentity(ident);
9955        }
9956    }
9957
9958    @Override
9959    public void positionTaskInStack(int taskId, int stackId, int position) {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9961        if (stackId == HOME_STACK_ID) {
9962            throw new IllegalArgumentException(
9963                    "positionTaskInStack: Attempt to change the position of task "
9964                    + taskId + " in/to home stack");
9965        }
9966        synchronized (this) {
9967            long ident = Binder.clearCallingIdentity();
9968            try {
9969                if (DEBUG_STACK) Slog.d(TAG_STACK,
9970                        "positionTaskInStack: positioning task=" + taskId
9971                        + " in stackId=" + stackId + " at position=" + position);
9972                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9973            } finally {
9974                Binder.restoreCallingIdentity(ident);
9975            }
9976        }
9977    }
9978
9979    @Override
9980    public List<StackInfo> getAllStackInfos() {
9981        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9982        long ident = Binder.clearCallingIdentity();
9983        try {
9984            synchronized (this) {
9985                return mStackSupervisor.getAllStackInfosLocked();
9986            }
9987        } finally {
9988            Binder.restoreCallingIdentity(ident);
9989        }
9990    }
9991
9992    @Override
9993    public StackInfo getStackInfo(int stackId) {
9994        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9995        long ident = Binder.clearCallingIdentity();
9996        try {
9997            synchronized (this) {
9998                return mStackSupervisor.getStackInfoLocked(stackId);
9999            }
10000        } finally {
10001            Binder.restoreCallingIdentity(ident);
10002        }
10003    }
10004
10005    @Override
10006    public boolean isInHomeStack(int taskId) {
10007        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10008        long ident = Binder.clearCallingIdentity();
10009        try {
10010            synchronized (this) {
10011                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10012                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10013                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10014            }
10015        } finally {
10016            Binder.restoreCallingIdentity(ident);
10017        }
10018    }
10019
10020    @Override
10021    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10022        synchronized(this) {
10023            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10024        }
10025    }
10026
10027    @Override
10028    public void updateDeviceOwner(String packageName) {
10029        final int callingUid = Binder.getCallingUid();
10030        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10031            throw new SecurityException("updateDeviceOwner called from non-system process");
10032        }
10033        synchronized (this) {
10034            mDeviceOwnerName = packageName;
10035        }
10036    }
10037
10038    @Override
10039    public void updateLockTaskPackages(int userId, String[] packages) {
10040        final int callingUid = Binder.getCallingUid();
10041        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10042            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10043                    "updateLockTaskPackages()");
10044        }
10045        synchronized (this) {
10046            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10047                    Arrays.toString(packages));
10048            mLockTaskPackages.put(userId, packages);
10049            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10050        }
10051    }
10052
10053
10054    void startLockTaskModeLocked(TaskRecord task) {
10055        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10056        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10057            return;
10058        }
10059
10060        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10061        // is initiated by system after the pinning request was shown and locked mode is initiated
10062        // by an authorized app directly
10063        final int callingUid = Binder.getCallingUid();
10064        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10065        long ident = Binder.clearCallingIdentity();
10066        try {
10067            if (!isSystemInitiated) {
10068                task.mLockTaskUid = callingUid;
10069                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10070                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10071                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10072                    StatusBarManagerInternal statusBarManager =
10073                            LocalServices.getService(StatusBarManagerInternal.class);
10074                    if (statusBarManager != null) {
10075                        statusBarManager.showScreenPinningRequest(task.taskId);
10076                    }
10077                    return;
10078                }
10079
10080                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10081                if (stack == null || task != stack.topTask()) {
10082                    throw new IllegalArgumentException("Invalid task, not in foreground");
10083                }
10084            }
10085            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10086                    "Locking fully");
10087            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10088                    ActivityManager.LOCK_TASK_MODE_PINNED :
10089                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10090                    "startLockTask", true);
10091        } finally {
10092            Binder.restoreCallingIdentity(ident);
10093        }
10094    }
10095
10096    @Override
10097    public void startLockTaskMode(int taskId) {
10098        synchronized (this) {
10099            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10100            if (task != null) {
10101                startLockTaskModeLocked(task);
10102            }
10103        }
10104    }
10105
10106    @Override
10107    public void startLockTaskMode(IBinder token) {
10108        synchronized (this) {
10109            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10110            if (r == null) {
10111                return;
10112            }
10113            final TaskRecord task = r.task;
10114            if (task != null) {
10115                startLockTaskModeLocked(task);
10116            }
10117        }
10118    }
10119
10120    @Override
10121    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10122        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10123        // This makes inner call to look as if it was initiated by system.
10124        long ident = Binder.clearCallingIdentity();
10125        try {
10126            synchronized (this) {
10127                startLockTaskMode(taskId);
10128            }
10129        } finally {
10130            Binder.restoreCallingIdentity(ident);
10131        }
10132    }
10133
10134    @Override
10135    public void stopLockTaskMode() {
10136        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10137        if (lockTask == null) {
10138            // Our work here is done.
10139            return;
10140        }
10141
10142        final int callingUid = Binder.getCallingUid();
10143        final int lockTaskUid = lockTask.mLockTaskUid;
10144        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10145        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10146            // Done.
10147            return;
10148        } else {
10149            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10150            // It is possible lockTaskMode was started by the system process because
10151            // android:lockTaskMode is set to a locking value in the application manifest
10152            // instead of the app calling startLockTaskMode. In this case
10153            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10154            // {@link TaskRecord.effectiveUid} instead. Also caller with
10155            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10156            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10157                    && callingUid != lockTaskUid
10158                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10159                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10160                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10161            }
10162        }
10163        long ident = Binder.clearCallingIdentity();
10164        try {
10165            Log.d(TAG, "stopLockTaskMode");
10166            // Stop lock task
10167            synchronized (this) {
10168                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10169                        "stopLockTask", true);
10170            }
10171            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10172            if (tm != null) {
10173                tm.showInCallScreen(false);
10174            }
10175        } finally {
10176            Binder.restoreCallingIdentity(ident);
10177        }
10178    }
10179
10180    /**
10181     * This API should be called by SystemUI only when user perform certain action to dismiss
10182     * lock task mode. We should only dismiss pinned lock task mode in this case.
10183     */
10184    @Override
10185    public void stopSystemLockTaskMode() throws RemoteException {
10186        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10187            stopLockTaskMode();
10188        } else {
10189            mStackSupervisor.showLockTaskToast();
10190        }
10191    }
10192
10193    @Override
10194    public boolean isInLockTaskMode() {
10195        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10196    }
10197
10198    @Override
10199    public int getLockTaskModeState() {
10200        synchronized (this) {
10201            return mStackSupervisor.getLockTaskModeState();
10202        }
10203    }
10204
10205    @Override
10206    public void showLockTaskEscapeMessage(IBinder token) {
10207        synchronized (this) {
10208            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10209            if (r == null) {
10210                return;
10211            }
10212            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10213        }
10214    }
10215
10216    // =========================================================
10217    // CONTENT PROVIDERS
10218    // =========================================================
10219
10220    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10221        List<ProviderInfo> providers = null;
10222        try {
10223            providers = AppGlobals.getPackageManager()
10224                    .queryContentProviders(app.processName, app.uid,
10225                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10226                                    | MATCH_DEBUG_TRIAGED_MISSING)
10227                    .getList();
10228        } catch (RemoteException ex) {
10229        }
10230        if (DEBUG_MU) Slog.v(TAG_MU,
10231                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10232        int userId = app.userId;
10233        if (providers != null) {
10234            int N = providers.size();
10235            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10236            for (int i=0; i<N; i++) {
10237                // TODO: keep logic in sync with installEncryptionUnawareProviders
10238                ProviderInfo cpi =
10239                    (ProviderInfo)providers.get(i);
10240                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10241                        cpi.name, cpi.flags);
10242                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10243                    // This is a singleton provider, but a user besides the
10244                    // default user is asking to initialize a process it runs
10245                    // in...  well, no, it doesn't actually run in this process,
10246                    // it runs in the process of the default user.  Get rid of it.
10247                    providers.remove(i);
10248                    N--;
10249                    i--;
10250                    continue;
10251                }
10252
10253                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10254                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10255                if (cpr == null) {
10256                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10257                    mProviderMap.putProviderByClass(comp, cpr);
10258                }
10259                if (DEBUG_MU) Slog.v(TAG_MU,
10260                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10261                app.pubProviders.put(cpi.name, cpr);
10262                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10263                    // Don't add this if it is a platform component that is marked
10264                    // to run in multiple processes, because this is actually
10265                    // part of the framework so doesn't make sense to track as a
10266                    // separate apk in the process.
10267                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10268                            mProcessStats);
10269                }
10270                notifyPackageUse(cpi.applicationInfo.packageName,
10271                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10272            }
10273        }
10274        return providers;
10275    }
10276
10277    /**
10278     * Check if {@link ProcessRecord} has a possible chance at accessing the
10279     * given {@link ProviderInfo}. Final permission checking is always done
10280     * in {@link ContentProvider}.
10281     */
10282    private final String checkContentProviderPermissionLocked(
10283            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10284        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10285        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10286        boolean checkedGrants = false;
10287        if (checkUser) {
10288            // Looking for cross-user grants before enforcing the typical cross-users permissions
10289            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10290            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10291                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10292                    return null;
10293                }
10294                checkedGrants = true;
10295            }
10296            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10297                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10298            if (userId != tmpTargetUserId) {
10299                // When we actually went to determine the final targer user ID, this ended
10300                // up different than our initial check for the authority.  This is because
10301                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10302                // SELF.  So we need to re-check the grants again.
10303                checkedGrants = false;
10304            }
10305        }
10306        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10307                cpi.applicationInfo.uid, cpi.exported)
10308                == PackageManager.PERMISSION_GRANTED) {
10309            return null;
10310        }
10311        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10312                cpi.applicationInfo.uid, cpi.exported)
10313                == PackageManager.PERMISSION_GRANTED) {
10314            return null;
10315        }
10316
10317        PathPermission[] pps = cpi.pathPermissions;
10318        if (pps != null) {
10319            int i = pps.length;
10320            while (i > 0) {
10321                i--;
10322                PathPermission pp = pps[i];
10323                String pprperm = pp.getReadPermission();
10324                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10325                        cpi.applicationInfo.uid, cpi.exported)
10326                        == PackageManager.PERMISSION_GRANTED) {
10327                    return null;
10328                }
10329                String ppwperm = pp.getWritePermission();
10330                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10331                        cpi.applicationInfo.uid, cpi.exported)
10332                        == PackageManager.PERMISSION_GRANTED) {
10333                    return null;
10334                }
10335            }
10336        }
10337        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10338            return null;
10339        }
10340
10341        String msg;
10342        if (!cpi.exported) {
10343            msg = "Permission Denial: opening provider " + cpi.name
10344                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10345                    + ", uid=" + callingUid + ") that is not exported from uid "
10346                    + cpi.applicationInfo.uid;
10347        } else {
10348            msg = "Permission Denial: opening provider " + cpi.name
10349                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10350                    + ", uid=" + callingUid + ") requires "
10351                    + cpi.readPermission + " or " + cpi.writePermission;
10352        }
10353        Slog.w(TAG, msg);
10354        return msg;
10355    }
10356
10357    /**
10358     * Returns if the ContentProvider has granted a uri to callingUid
10359     */
10360    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10361        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10362        if (perms != null) {
10363            for (int i=perms.size()-1; i>=0; i--) {
10364                GrantUri grantUri = perms.keyAt(i);
10365                if (grantUri.sourceUserId == userId || !checkUser) {
10366                    if (matchesProvider(grantUri.uri, cpi)) {
10367                        return true;
10368                    }
10369                }
10370            }
10371        }
10372        return false;
10373    }
10374
10375    /**
10376     * Returns true if the uri authority is one of the authorities specified in the provider.
10377     */
10378    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10379        String uriAuth = uri.getAuthority();
10380        String cpiAuth = cpi.authority;
10381        if (cpiAuth.indexOf(';') == -1) {
10382            return cpiAuth.equals(uriAuth);
10383        }
10384        String[] cpiAuths = cpiAuth.split(";");
10385        int length = cpiAuths.length;
10386        for (int i = 0; i < length; i++) {
10387            if (cpiAuths[i].equals(uriAuth)) return true;
10388        }
10389        return false;
10390    }
10391
10392    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10393            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10394        if (r != null) {
10395            for (int i=0; i<r.conProviders.size(); i++) {
10396                ContentProviderConnection conn = r.conProviders.get(i);
10397                if (conn.provider == cpr) {
10398                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10399                            "Adding provider requested by "
10400                            + r.processName + " from process "
10401                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10402                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10403                    if (stable) {
10404                        conn.stableCount++;
10405                        conn.numStableIncs++;
10406                    } else {
10407                        conn.unstableCount++;
10408                        conn.numUnstableIncs++;
10409                    }
10410                    return conn;
10411                }
10412            }
10413            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10414            if (stable) {
10415                conn.stableCount = 1;
10416                conn.numStableIncs = 1;
10417            } else {
10418                conn.unstableCount = 1;
10419                conn.numUnstableIncs = 1;
10420            }
10421            cpr.connections.add(conn);
10422            r.conProviders.add(conn);
10423            startAssociationLocked(r.uid, r.processName, r.curProcState,
10424                    cpr.uid, cpr.name, cpr.info.processName);
10425            return conn;
10426        }
10427        cpr.addExternalProcessHandleLocked(externalProcessToken);
10428        return null;
10429    }
10430
10431    boolean decProviderCountLocked(ContentProviderConnection conn,
10432            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433        if (conn != null) {
10434            cpr = conn.provider;
10435            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10436                    "Removing provider requested by "
10437                    + conn.client.processName + " from process "
10438                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10439                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10440            if (stable) {
10441                conn.stableCount--;
10442            } else {
10443                conn.unstableCount--;
10444            }
10445            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10446                cpr.connections.remove(conn);
10447                conn.client.conProviders.remove(conn);
10448                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10449                    // The client is more important than last activity -- note the time this
10450                    // is happening, so we keep the old provider process around a bit as last
10451                    // activity to avoid thrashing it.
10452                    if (cpr.proc != null) {
10453                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10454                    }
10455                }
10456                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10457                return true;
10458            }
10459            return false;
10460        }
10461        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10462        return false;
10463    }
10464
10465    private void checkTime(long startTime, String where) {
10466        long now = SystemClock.uptimeMillis();
10467        if ((now-startTime) > 50) {
10468            // If we are taking more than 50ms, log about it.
10469            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10470        }
10471    }
10472
10473    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10474            String name, IBinder token, boolean stable, int userId) {
10475        ContentProviderRecord cpr;
10476        ContentProviderConnection conn = null;
10477        ProviderInfo cpi = null;
10478
10479        synchronized(this) {
10480            long startTime = SystemClock.uptimeMillis();
10481
10482            ProcessRecord r = null;
10483            if (caller != null) {
10484                r = getRecordForAppLocked(caller);
10485                if (r == null) {
10486                    throw new SecurityException(
10487                            "Unable to find app for caller " + caller
10488                          + " (pid=" + Binder.getCallingPid()
10489                          + ") when getting content provider " + name);
10490                }
10491            }
10492
10493            boolean checkCrossUser = true;
10494
10495            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10496
10497            // First check if this content provider has been published...
10498            cpr = mProviderMap.getProviderByName(name, userId);
10499            // If that didn't work, check if it exists for user 0 and then
10500            // verify that it's a singleton provider before using it.
10501            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10502                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10503                if (cpr != null) {
10504                    cpi = cpr.info;
10505                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10506                            cpi.name, cpi.flags)
10507                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10508                        userId = UserHandle.USER_SYSTEM;
10509                        checkCrossUser = false;
10510                    } else {
10511                        cpr = null;
10512                        cpi = null;
10513                    }
10514                }
10515            }
10516
10517            boolean providerRunning = cpr != null;
10518            if (providerRunning) {
10519                cpi = cpr.info;
10520                String msg;
10521                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10522                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10523                        != null) {
10524                    throw new SecurityException(msg);
10525                }
10526                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10527
10528                if (r != null && cpr.canRunHere(r)) {
10529                    // This provider has been published or is in the process
10530                    // of being published...  but it is also allowed to run
10531                    // in the caller's process, so don't make a connection
10532                    // and just let the caller instantiate its own instance.
10533                    ContentProviderHolder holder = cpr.newHolder(null);
10534                    // don't give caller the provider object, it needs
10535                    // to make its own.
10536                    holder.provider = null;
10537                    return holder;
10538                }
10539
10540                final long origId = Binder.clearCallingIdentity();
10541
10542                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10543
10544                // In this case the provider instance already exists, so we can
10545                // return it right away.
10546                conn = incProviderCountLocked(r, cpr, token, stable);
10547                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10548                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10549                        // If this is a perceptible app accessing the provider,
10550                        // make sure to count it as being accessed and thus
10551                        // back up on the LRU list.  This is good because
10552                        // content providers are often expensive to start.
10553                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10554                        updateLruProcessLocked(cpr.proc, false, null);
10555                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10556                    }
10557                }
10558
10559                if (cpr.proc != null) {
10560                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10561                    boolean success = updateOomAdjLocked(cpr.proc);
10562                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10563                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10564                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10565                    // NOTE: there is still a race here where a signal could be
10566                    // pending on the process even though we managed to update its
10567                    // adj level.  Not sure what to do about this, but at least
10568                    // the race is now smaller.
10569                    if (!success) {
10570                        // Uh oh...  it looks like the provider's process
10571                        // has been killed on us.  We need to wait for a new
10572                        // process to be started, and make sure its death
10573                        // doesn't kill our process.
10574                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10575                                + " is crashing; detaching " + r);
10576                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10577                        checkTime(startTime, "getContentProviderImpl: before appDied");
10578                        appDiedLocked(cpr.proc);
10579                        checkTime(startTime, "getContentProviderImpl: after appDied");
10580                        if (!lastRef) {
10581                            // This wasn't the last ref our process had on
10582                            // the provider...  we have now been killed, bail.
10583                            return null;
10584                        }
10585                        providerRunning = false;
10586                        conn = null;
10587                    }
10588                }
10589
10590                Binder.restoreCallingIdentity(origId);
10591            }
10592
10593            if (!providerRunning) {
10594                try {
10595                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10596                    cpi = AppGlobals.getPackageManager().
10597                        resolveContentProvider(name,
10598                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10599                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10600                } catch (RemoteException ex) {
10601                }
10602                if (cpi == null) {
10603                    return null;
10604                }
10605                // If the provider is a singleton AND
10606                // (it's a call within the same user || the provider is a
10607                // privileged app)
10608                // Then allow connecting to the singleton provider
10609                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10610                        cpi.name, cpi.flags)
10611                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10612                if (singleton) {
10613                    userId = UserHandle.USER_SYSTEM;
10614                }
10615                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10616                checkTime(startTime, "getContentProviderImpl: got app info for user");
10617
10618                String msg;
10619                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10620                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10621                        != null) {
10622                    throw new SecurityException(msg);
10623                }
10624                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10625
10626                if (!mProcessesReady
10627                        && !cpi.processName.equals("system")) {
10628                    // If this content provider does not run in the system
10629                    // process, and the system is not yet ready to run other
10630                    // processes, then fail fast instead of hanging.
10631                    throw new IllegalArgumentException(
10632                            "Attempt to launch content provider before system ready");
10633                }
10634
10635                // Make sure that the user who owns this provider is running.  If not,
10636                // we don't want to allow it to run.
10637                if (!mUserController.isUserRunningLocked(userId, 0)) {
10638                    Slog.w(TAG, "Unable to launch app "
10639                            + cpi.applicationInfo.packageName + "/"
10640                            + cpi.applicationInfo.uid + " for provider "
10641                            + name + ": user " + userId + " is stopped");
10642                    return null;
10643                }
10644
10645                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10646                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10647                cpr = mProviderMap.getProviderByClass(comp, userId);
10648                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10649                final boolean firstClass = cpr == null;
10650                if (firstClass) {
10651                    final long ident = Binder.clearCallingIdentity();
10652
10653                    // If permissions need a review before any of the app components can run,
10654                    // we return no provider and launch a review activity if the calling app
10655                    // is in the foreground.
10656                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10657                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10658                            return null;
10659                        }
10660                    }
10661
10662                    try {
10663                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10664                        ApplicationInfo ai =
10665                            AppGlobals.getPackageManager().
10666                                getApplicationInfo(
10667                                        cpi.applicationInfo.packageName,
10668                                        STOCK_PM_FLAGS, userId);
10669                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10670                        if (ai == null) {
10671                            Slog.w(TAG, "No package info for content provider "
10672                                    + cpi.name);
10673                            return null;
10674                        }
10675                        ai = getAppInfoForUser(ai, userId);
10676                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10677                    } catch (RemoteException ex) {
10678                        // pm is in same process, this will never happen.
10679                    } finally {
10680                        Binder.restoreCallingIdentity(ident);
10681                    }
10682                }
10683
10684                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10685
10686                if (r != null && cpr.canRunHere(r)) {
10687                    // If this is a multiprocess provider, then just return its
10688                    // info and allow the caller to instantiate it.  Only do
10689                    // this if the provider is the same user as the caller's
10690                    // process, or can run as root (so can be in any process).
10691                    return cpr.newHolder(null);
10692                }
10693
10694                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10695                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10696                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10697
10698                // This is single process, and our app is now connecting to it.
10699                // See if we are already in the process of launching this
10700                // provider.
10701                final int N = mLaunchingProviders.size();
10702                int i;
10703                for (i = 0; i < N; i++) {
10704                    if (mLaunchingProviders.get(i) == cpr) {
10705                        break;
10706                    }
10707                }
10708
10709                // If the provider is not already being launched, then get it
10710                // started.
10711                if (i >= N) {
10712                    final long origId = Binder.clearCallingIdentity();
10713
10714                    try {
10715                        // Content provider is now in use, its package can't be stopped.
10716                        try {
10717                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10718                            AppGlobals.getPackageManager().setPackageStoppedState(
10719                                    cpr.appInfo.packageName, false, userId);
10720                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10721                        } catch (RemoteException e) {
10722                        } catch (IllegalArgumentException e) {
10723                            Slog.w(TAG, "Failed trying to unstop package "
10724                                    + cpr.appInfo.packageName + ": " + e);
10725                        }
10726
10727                        // Use existing process if already started
10728                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10729                        ProcessRecord proc = getProcessRecordLocked(
10730                                cpi.processName, cpr.appInfo.uid, false);
10731                        if (proc != null && proc.thread != null) {
10732                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10733                                    "Installing in existing process " + proc);
10734                            if (!proc.pubProviders.containsKey(cpi.name)) {
10735                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10736                                proc.pubProviders.put(cpi.name, cpr);
10737                                try {
10738                                    proc.thread.scheduleInstallProvider(cpi);
10739                                } catch (RemoteException e) {
10740                                }
10741                            }
10742                        } else {
10743                            checkTime(startTime, "getContentProviderImpl: before start process");
10744                            proc = startProcessLocked(cpi.processName,
10745                                    cpr.appInfo, false, 0, "content provider",
10746                                    new ComponentName(cpi.applicationInfo.packageName,
10747                                            cpi.name), false, false, false);
10748                            checkTime(startTime, "getContentProviderImpl: after start process");
10749                            if (proc == null) {
10750                                Slog.w(TAG, "Unable to launch app "
10751                                        + cpi.applicationInfo.packageName + "/"
10752                                        + cpi.applicationInfo.uid + " for provider "
10753                                        + name + ": process is bad");
10754                                return null;
10755                            }
10756                        }
10757                        cpr.launchingApp = proc;
10758                        mLaunchingProviders.add(cpr);
10759                    } finally {
10760                        Binder.restoreCallingIdentity(origId);
10761                    }
10762                }
10763
10764                checkTime(startTime, "getContentProviderImpl: updating data structures");
10765
10766                // Make sure the provider is published (the same provider class
10767                // may be published under multiple names).
10768                if (firstClass) {
10769                    mProviderMap.putProviderByClass(comp, cpr);
10770                }
10771
10772                mProviderMap.putProviderByName(name, cpr);
10773                conn = incProviderCountLocked(r, cpr, token, stable);
10774                if (conn != null) {
10775                    conn.waiting = true;
10776                }
10777            }
10778            checkTime(startTime, "getContentProviderImpl: done!");
10779        }
10780
10781        // Wait for the provider to be published...
10782        synchronized (cpr) {
10783            while (cpr.provider == null) {
10784                if (cpr.launchingApp == null) {
10785                    Slog.w(TAG, "Unable to launch app "
10786                            + cpi.applicationInfo.packageName + "/"
10787                            + cpi.applicationInfo.uid + " for provider "
10788                            + name + ": launching app became null");
10789                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10790                            UserHandle.getUserId(cpi.applicationInfo.uid),
10791                            cpi.applicationInfo.packageName,
10792                            cpi.applicationInfo.uid, name);
10793                    return null;
10794                }
10795                try {
10796                    if (DEBUG_MU) Slog.v(TAG_MU,
10797                            "Waiting to start provider " + cpr
10798                            + " launchingApp=" + cpr.launchingApp);
10799                    if (conn != null) {
10800                        conn.waiting = true;
10801                    }
10802                    cpr.wait();
10803                } catch (InterruptedException ex) {
10804                } finally {
10805                    if (conn != null) {
10806                        conn.waiting = false;
10807                    }
10808                }
10809            }
10810        }
10811        return cpr != null ? cpr.newHolder(conn) : null;
10812    }
10813
10814    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10815            ProcessRecord r, final int userId) {
10816        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10817                cpi.packageName, userId)) {
10818
10819            final boolean callerForeground = r == null || r.setSchedGroup
10820                    != ProcessList.SCHED_GROUP_BACKGROUND;
10821
10822            // Show a permission review UI only for starting from a foreground app
10823            if (!callerForeground) {
10824                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10825                        + cpi.packageName + " requires a permissions review");
10826                return false;
10827            }
10828
10829            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10830            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10831                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10832            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10833
10834            if (DEBUG_PERMISSIONS_REVIEW) {
10835                Slog.i(TAG, "u" + userId + " Launching permission review "
10836                        + "for package " + cpi.packageName);
10837            }
10838
10839            final UserHandle userHandle = new UserHandle(userId);
10840            mHandler.post(new Runnable() {
10841                @Override
10842                public void run() {
10843                    mContext.startActivityAsUser(intent, userHandle);
10844                }
10845            });
10846
10847            return false;
10848        }
10849
10850        return true;
10851    }
10852
10853    PackageManagerInternal getPackageManagerInternalLocked() {
10854        if (mPackageManagerInt == null) {
10855            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10856        }
10857        return mPackageManagerInt;
10858    }
10859
10860    @Override
10861    public final ContentProviderHolder getContentProvider(
10862            IApplicationThread caller, String name, int userId, boolean stable) {
10863        enforceNotIsolatedCaller("getContentProvider");
10864        if (caller == null) {
10865            String msg = "null IApplicationThread when getting content provider "
10866                    + name;
10867            Slog.w(TAG, msg);
10868            throw new SecurityException(msg);
10869        }
10870        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10871        // with cross-user grant.
10872        return getContentProviderImpl(caller, name, null, stable, userId);
10873    }
10874
10875    public ContentProviderHolder getContentProviderExternal(
10876            String name, int userId, IBinder token) {
10877        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10878            "Do not have permission in call getContentProviderExternal()");
10879        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10880                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10881        return getContentProviderExternalUnchecked(name, token, userId);
10882    }
10883
10884    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10885            IBinder token, int userId) {
10886        return getContentProviderImpl(null, name, token, true, userId);
10887    }
10888
10889    /**
10890     * Drop a content provider from a ProcessRecord's bookkeeping
10891     */
10892    public void removeContentProvider(IBinder connection, boolean stable) {
10893        enforceNotIsolatedCaller("removeContentProvider");
10894        long ident = Binder.clearCallingIdentity();
10895        try {
10896            synchronized (this) {
10897                ContentProviderConnection conn;
10898                try {
10899                    conn = (ContentProviderConnection)connection;
10900                } catch (ClassCastException e) {
10901                    String msg ="removeContentProvider: " + connection
10902                            + " not a ContentProviderConnection";
10903                    Slog.w(TAG, msg);
10904                    throw new IllegalArgumentException(msg);
10905                }
10906                if (conn == null) {
10907                    throw new NullPointerException("connection is null");
10908                }
10909                if (decProviderCountLocked(conn, null, null, stable)) {
10910                    updateOomAdjLocked();
10911                }
10912            }
10913        } finally {
10914            Binder.restoreCallingIdentity(ident);
10915        }
10916    }
10917
10918    public void removeContentProviderExternal(String name, IBinder token) {
10919        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10920            "Do not have permission in call removeContentProviderExternal()");
10921        int userId = UserHandle.getCallingUserId();
10922        long ident = Binder.clearCallingIdentity();
10923        try {
10924            removeContentProviderExternalUnchecked(name, token, userId);
10925        } finally {
10926            Binder.restoreCallingIdentity(ident);
10927        }
10928    }
10929
10930    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10931        synchronized (this) {
10932            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10933            if(cpr == null) {
10934                //remove from mProvidersByClass
10935                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10936                return;
10937            }
10938
10939            //update content provider record entry info
10940            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10941            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10942            if (localCpr.hasExternalProcessHandles()) {
10943                if (localCpr.removeExternalProcessHandleLocked(token)) {
10944                    updateOomAdjLocked();
10945                } else {
10946                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10947                            + " with no external reference for token: "
10948                            + token + ".");
10949                }
10950            } else {
10951                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10952                        + " with no external references.");
10953            }
10954        }
10955    }
10956
10957    public final void publishContentProviders(IApplicationThread caller,
10958            List<ContentProviderHolder> providers) {
10959        if (providers == null) {
10960            return;
10961        }
10962
10963        enforceNotIsolatedCaller("publishContentProviders");
10964        synchronized (this) {
10965            final ProcessRecord r = getRecordForAppLocked(caller);
10966            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10967            if (r == null) {
10968                throw new SecurityException(
10969                        "Unable to find app for caller " + caller
10970                      + " (pid=" + Binder.getCallingPid()
10971                      + ") when publishing content providers");
10972            }
10973
10974            final long origId = Binder.clearCallingIdentity();
10975
10976            final int N = providers.size();
10977            for (int i = 0; i < N; i++) {
10978                ContentProviderHolder src = providers.get(i);
10979                if (src == null || src.info == null || src.provider == null) {
10980                    continue;
10981                }
10982                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10983                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10984                if (dst != null) {
10985                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10986                    mProviderMap.putProviderByClass(comp, dst);
10987                    String names[] = dst.info.authority.split(";");
10988                    for (int j = 0; j < names.length; j++) {
10989                        mProviderMap.putProviderByName(names[j], dst);
10990                    }
10991
10992                    int launchingCount = mLaunchingProviders.size();
10993                    int j;
10994                    boolean wasInLaunchingProviders = false;
10995                    for (j = 0; j < launchingCount; j++) {
10996                        if (mLaunchingProviders.get(j) == dst) {
10997                            mLaunchingProviders.remove(j);
10998                            wasInLaunchingProviders = true;
10999                            j--;
11000                            launchingCount--;
11001                        }
11002                    }
11003                    if (wasInLaunchingProviders) {
11004                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11005                    }
11006                    synchronized (dst) {
11007                        dst.provider = src.provider;
11008                        dst.proc = r;
11009                        dst.notifyAll();
11010                    }
11011                    updateOomAdjLocked(r);
11012                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11013                            src.info.authority);
11014                }
11015            }
11016
11017            Binder.restoreCallingIdentity(origId);
11018        }
11019    }
11020
11021    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11022        ContentProviderConnection conn;
11023        try {
11024            conn = (ContentProviderConnection)connection;
11025        } catch (ClassCastException e) {
11026            String msg ="refContentProvider: " + connection
11027                    + " not a ContentProviderConnection";
11028            Slog.w(TAG, msg);
11029            throw new IllegalArgumentException(msg);
11030        }
11031        if (conn == null) {
11032            throw new NullPointerException("connection is null");
11033        }
11034
11035        synchronized (this) {
11036            if (stable > 0) {
11037                conn.numStableIncs += stable;
11038            }
11039            stable = conn.stableCount + stable;
11040            if (stable < 0) {
11041                throw new IllegalStateException("stableCount < 0: " + stable);
11042            }
11043
11044            if (unstable > 0) {
11045                conn.numUnstableIncs += unstable;
11046            }
11047            unstable = conn.unstableCount + unstable;
11048            if (unstable < 0) {
11049                throw new IllegalStateException("unstableCount < 0: " + unstable);
11050            }
11051
11052            if ((stable+unstable) <= 0) {
11053                throw new IllegalStateException("ref counts can't go to zero here: stable="
11054                        + stable + " unstable=" + unstable);
11055            }
11056            conn.stableCount = stable;
11057            conn.unstableCount = unstable;
11058            return !conn.dead;
11059        }
11060    }
11061
11062    public void unstableProviderDied(IBinder connection) {
11063        ContentProviderConnection conn;
11064        try {
11065            conn = (ContentProviderConnection)connection;
11066        } catch (ClassCastException e) {
11067            String msg ="refContentProvider: " + connection
11068                    + " not a ContentProviderConnection";
11069            Slog.w(TAG, msg);
11070            throw new IllegalArgumentException(msg);
11071        }
11072        if (conn == null) {
11073            throw new NullPointerException("connection is null");
11074        }
11075
11076        // Safely retrieve the content provider associated with the connection.
11077        IContentProvider provider;
11078        synchronized (this) {
11079            provider = conn.provider.provider;
11080        }
11081
11082        if (provider == null) {
11083            // Um, yeah, we're way ahead of you.
11084            return;
11085        }
11086
11087        // Make sure the caller is being honest with us.
11088        if (provider.asBinder().pingBinder()) {
11089            // Er, no, still looks good to us.
11090            synchronized (this) {
11091                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11092                        + " says " + conn + " died, but we don't agree");
11093                return;
11094            }
11095        }
11096
11097        // Well look at that!  It's dead!
11098        synchronized (this) {
11099            if (conn.provider.provider != provider) {
11100                // But something changed...  good enough.
11101                return;
11102            }
11103
11104            ProcessRecord proc = conn.provider.proc;
11105            if (proc == null || proc.thread == null) {
11106                // Seems like the process is already cleaned up.
11107                return;
11108            }
11109
11110            // As far as we're concerned, this is just like receiving a
11111            // death notification...  just a bit prematurely.
11112            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11113                    + ") early provider death");
11114            final long ident = Binder.clearCallingIdentity();
11115            try {
11116                appDiedLocked(proc);
11117            } finally {
11118                Binder.restoreCallingIdentity(ident);
11119            }
11120        }
11121    }
11122
11123    @Override
11124    public void appNotRespondingViaProvider(IBinder connection) {
11125        enforceCallingPermission(
11126                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11127
11128        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11129        if (conn == null) {
11130            Slog.w(TAG, "ContentProviderConnection is null");
11131            return;
11132        }
11133
11134        final ProcessRecord host = conn.provider.proc;
11135        if (host == null) {
11136            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11137            return;
11138        }
11139
11140        mHandler.post(new Runnable() {
11141            @Override
11142            public void run() {
11143                mAppErrors.appNotResponding(host, null, null, false,
11144                        "ContentProvider not responding");
11145            }
11146        });
11147    }
11148
11149    public final void installSystemProviders() {
11150        List<ProviderInfo> providers;
11151        synchronized (this) {
11152            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11153            providers = generateApplicationProvidersLocked(app);
11154            if (providers != null) {
11155                for (int i=providers.size()-1; i>=0; i--) {
11156                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11157                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11158                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11159                                + ": not system .apk");
11160                        providers.remove(i);
11161                    }
11162                }
11163            }
11164        }
11165        if (providers != null) {
11166            mSystemThread.installSystemProviders(providers);
11167        }
11168
11169        mCoreSettingsObserver = new CoreSettingsObserver(this);
11170        mFontScaleSettingObserver = new FontScaleSettingObserver();
11171
11172        //mUsageStatsService.monitorPackages();
11173    }
11174
11175    private void startPersistentApps(int matchFlags) {
11176        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11177
11178        synchronized (this) {
11179            try {
11180                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11181                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11182                for (ApplicationInfo app : apps) {
11183                    if (!"android".equals(app.packageName)) {
11184                        addAppLocked(app, false, null /* ABI override */);
11185                    }
11186                }
11187            } catch (RemoteException ex) {
11188            }
11189        }
11190    }
11191
11192    /**
11193     * When a user is unlocked, we need to install encryption-unaware providers
11194     * belonging to any running apps.
11195     */
11196    private void installEncryptionUnawareProviders(int userId) {
11197        // We're only interested in providers that are encryption unaware, and
11198        // we don't care about uninstalled apps, since there's no way they're
11199        // running at this point.
11200        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11201
11202        synchronized (this) {
11203            final int NP = mProcessNames.getMap().size();
11204            for (int ip = 0; ip < NP; ip++) {
11205                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11206                final int NA = apps.size();
11207                for (int ia = 0; ia < NA; ia++) {
11208                    final ProcessRecord app = apps.valueAt(ia);
11209                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11210
11211                    final int NG = app.pkgList.size();
11212                    for (int ig = 0; ig < NG; ig++) {
11213                        try {
11214                            final String pkgName = app.pkgList.keyAt(ig);
11215                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11216                                    .getPackageInfo(pkgName, matchFlags, userId);
11217                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11218                                for (ProviderInfo pi : pkgInfo.providers) {
11219                                    // TODO: keep in sync with generateApplicationProvidersLocked
11220                                    final boolean processMatch = Objects.equals(pi.processName,
11221                                            app.processName) || pi.multiprocess;
11222                                    final boolean userMatch = isSingleton(pi.processName,
11223                                            pi.applicationInfo, pi.name, pi.flags)
11224                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11225                                    if (processMatch && userMatch) {
11226                                        Log.v(TAG, "Installing " + pi);
11227                                        app.thread.scheduleInstallProvider(pi);
11228                                    } else {
11229                                        Log.v(TAG, "Skipping " + pi);
11230                                    }
11231                                }
11232                            }
11233                        } catch (RemoteException ignored) {
11234                        }
11235                    }
11236                }
11237            }
11238        }
11239    }
11240
11241    /**
11242     * Allows apps to retrieve the MIME type of a URI.
11243     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11244     * users, then it does not need permission to access the ContentProvider.
11245     * Either, it needs cross-user uri grants.
11246     *
11247     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11248     *
11249     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11250     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11251     */
11252    public String getProviderMimeType(Uri uri, int userId) {
11253        enforceNotIsolatedCaller("getProviderMimeType");
11254        final String name = uri.getAuthority();
11255        int callingUid = Binder.getCallingUid();
11256        int callingPid = Binder.getCallingPid();
11257        long ident = 0;
11258        boolean clearedIdentity = false;
11259        synchronized (this) {
11260            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11261        }
11262        if (canClearIdentity(callingPid, callingUid, userId)) {
11263            clearedIdentity = true;
11264            ident = Binder.clearCallingIdentity();
11265        }
11266        ContentProviderHolder holder = null;
11267        try {
11268            holder = getContentProviderExternalUnchecked(name, null, userId);
11269            if (holder != null) {
11270                return holder.provider.getType(uri);
11271            }
11272        } catch (RemoteException e) {
11273            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11274            return null;
11275        } finally {
11276            // We need to clear the identity to call removeContentProviderExternalUnchecked
11277            if (!clearedIdentity) {
11278                ident = Binder.clearCallingIdentity();
11279            }
11280            try {
11281                if (holder != null) {
11282                    removeContentProviderExternalUnchecked(name, null, userId);
11283                }
11284            } finally {
11285                Binder.restoreCallingIdentity(ident);
11286            }
11287        }
11288
11289        return null;
11290    }
11291
11292    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11293        if (UserHandle.getUserId(callingUid) == userId) {
11294            return true;
11295        }
11296        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11297                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11298                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11299                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11300                return true;
11301        }
11302        return false;
11303    }
11304
11305    // =========================================================
11306    // GLOBAL MANAGEMENT
11307    // =========================================================
11308
11309    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11310            boolean isolated, int isolatedUid) {
11311        String proc = customProcess != null ? customProcess : info.processName;
11312        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11313        final int userId = UserHandle.getUserId(info.uid);
11314        int uid = info.uid;
11315        if (isolated) {
11316            if (isolatedUid == 0) {
11317                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11318                while (true) {
11319                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11320                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11321                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11322                    }
11323                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11324                    mNextIsolatedProcessUid++;
11325                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11326                        // No process for this uid, use it.
11327                        break;
11328                    }
11329                    stepsLeft--;
11330                    if (stepsLeft <= 0) {
11331                        return null;
11332                    }
11333                }
11334            } else {
11335                // Special case for startIsolatedProcess (internal only), where
11336                // the uid of the isolated process is specified by the caller.
11337                uid = isolatedUid;
11338            }
11339        }
11340        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11341        if (!mBooted && !mBooting
11342                && userId == UserHandle.USER_SYSTEM
11343                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11344            r.persistent = true;
11345        }
11346        addProcessNameLocked(r);
11347        return r;
11348    }
11349
11350    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11351            String abiOverride) {
11352        ProcessRecord app;
11353        if (!isolated) {
11354            app = getProcessRecordLocked(info.processName, info.uid, true);
11355        } else {
11356            app = null;
11357        }
11358
11359        if (app == null) {
11360            app = newProcessRecordLocked(info, null, isolated, 0);
11361            updateLruProcessLocked(app, false, null);
11362            updateOomAdjLocked();
11363        }
11364
11365        // This package really, really can not be stopped.
11366        try {
11367            AppGlobals.getPackageManager().setPackageStoppedState(
11368                    info.packageName, false, UserHandle.getUserId(app.uid));
11369        } catch (RemoteException e) {
11370        } catch (IllegalArgumentException e) {
11371            Slog.w(TAG, "Failed trying to unstop package "
11372                    + info.packageName + ": " + e);
11373        }
11374
11375        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11376            app.persistent = true;
11377            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11378        }
11379        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11380            mPersistentStartingProcesses.add(app);
11381            startProcessLocked(app, "added application", app.processName, abiOverride,
11382                    null /* entryPoint */, null /* entryPointArgs */);
11383        }
11384
11385        return app;
11386    }
11387
11388    public void unhandledBack() {
11389        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11390                "unhandledBack()");
11391
11392        synchronized(this) {
11393            final long origId = Binder.clearCallingIdentity();
11394            try {
11395                getFocusedStack().unhandledBackLocked();
11396            } finally {
11397                Binder.restoreCallingIdentity(origId);
11398            }
11399        }
11400    }
11401
11402    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11403        enforceNotIsolatedCaller("openContentUri");
11404        final int userId = UserHandle.getCallingUserId();
11405        String name = uri.getAuthority();
11406        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11407        ParcelFileDescriptor pfd = null;
11408        if (cph != null) {
11409            // We record the binder invoker's uid in thread-local storage before
11410            // going to the content provider to open the file.  Later, in the code
11411            // that handles all permissions checks, we look for this uid and use
11412            // that rather than the Activity Manager's own uid.  The effect is that
11413            // we do the check against the caller's permissions even though it looks
11414            // to the content provider like the Activity Manager itself is making
11415            // the request.
11416            Binder token = new Binder();
11417            sCallerIdentity.set(new Identity(
11418                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11419            try {
11420                pfd = cph.provider.openFile(null, uri, "r", null, token);
11421            } catch (FileNotFoundException e) {
11422                // do nothing; pfd will be returned null
11423            } finally {
11424                // Ensure that whatever happens, we clean up the identity state
11425                sCallerIdentity.remove();
11426                // Ensure we're done with the provider.
11427                removeContentProviderExternalUnchecked(name, null, userId);
11428            }
11429        } else {
11430            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11431        }
11432        return pfd;
11433    }
11434
11435    // Actually is sleeping or shutting down or whatever else in the future
11436    // is an inactive state.
11437    public boolean isSleepingOrShuttingDown() {
11438        return isSleeping() || mShuttingDown;
11439    }
11440
11441    public boolean isSleeping() {
11442        return mSleeping;
11443    }
11444
11445    void onWakefulnessChanged(int wakefulness) {
11446        synchronized(this) {
11447            mWakefulness = wakefulness;
11448            updateSleepIfNeededLocked();
11449        }
11450    }
11451
11452    void finishRunningVoiceLocked() {
11453        if (mRunningVoice != null) {
11454            mRunningVoice = null;
11455            mVoiceWakeLock.release();
11456            updateSleepIfNeededLocked();
11457        }
11458    }
11459
11460    void startTimeTrackingFocusedActivityLocked() {
11461        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11462            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11463        }
11464    }
11465
11466    void updateSleepIfNeededLocked() {
11467        if (mSleeping && !shouldSleepLocked()) {
11468            mSleeping = false;
11469            startTimeTrackingFocusedActivityLocked();
11470            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11471            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11472            updateOomAdjLocked();
11473        } else if (!mSleeping && shouldSleepLocked()) {
11474            mSleeping = true;
11475            if (mCurAppTimeTracker != null) {
11476                mCurAppTimeTracker.stop();
11477            }
11478            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11479            mStackSupervisor.goingToSleepLocked();
11480            updateOomAdjLocked();
11481
11482            // Initialize the wake times of all processes.
11483            checkExcessivePowerUsageLocked(false);
11484            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11485            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11486            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11487        }
11488    }
11489
11490    private boolean shouldSleepLocked() {
11491        // Resume applications while running a voice interactor.
11492        if (mRunningVoice != null) {
11493            return false;
11494        }
11495
11496        // TODO: Transform the lock screen state into a sleep token instead.
11497        switch (mWakefulness) {
11498            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11499            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11500            case PowerManagerInternal.WAKEFULNESS_DOZING:
11501                // Pause applications whenever the lock screen is shown or any sleep
11502                // tokens have been acquired.
11503                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11504            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11505            default:
11506                // If we're asleep then pause applications unconditionally.
11507                return true;
11508        }
11509    }
11510
11511    /** Pokes the task persister. */
11512    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11513        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11514    }
11515
11516    /** Notifies all listeners when the task stack has changed. */
11517    void notifyTaskStackChangedLocked() {
11518        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11519        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11520        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11521        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11522    }
11523
11524    /** Notifies all listeners when an Activity is pinned. */
11525    void notifyActivityPinnedLocked() {
11526        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11527        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11528    }
11529
11530    /**
11531     * Notifies all listeners when an attempt was made to start an an activity that is already
11532     * running in the pinned stack and the activity was not actually started, but the task is
11533     * either brought to the front or a new Intent is delivered to it.
11534     */
11535    void notifyPinnedActivityRestartAttemptLocked() {
11536        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11537        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11538    }
11539
11540    /** Notifies all listeners when the pinned stack animation ends. */
11541    @Override
11542    public void notifyPinnedStackAnimationEnded() {
11543        synchronized (this) {
11544            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11545            mHandler.obtainMessage(
11546                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11547        }
11548    }
11549
11550    @Override
11551    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11552        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11553    }
11554
11555    @Override
11556    public boolean shutdown(int timeout) {
11557        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11558                != PackageManager.PERMISSION_GRANTED) {
11559            throw new SecurityException("Requires permission "
11560                    + android.Manifest.permission.SHUTDOWN);
11561        }
11562
11563        boolean timedout = false;
11564
11565        synchronized(this) {
11566            mShuttingDown = true;
11567            updateEventDispatchingLocked();
11568            timedout = mStackSupervisor.shutdownLocked(timeout);
11569        }
11570
11571        mAppOpsService.shutdown();
11572        if (mUsageStatsService != null) {
11573            mUsageStatsService.prepareShutdown();
11574        }
11575        mBatteryStatsService.shutdown();
11576        synchronized (this) {
11577            mProcessStats.shutdownLocked();
11578            notifyTaskPersisterLocked(null, true);
11579        }
11580
11581        return timedout;
11582    }
11583
11584    public final void activitySlept(IBinder token) {
11585        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11586
11587        final long origId = Binder.clearCallingIdentity();
11588
11589        synchronized (this) {
11590            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11591            if (r != null) {
11592                mStackSupervisor.activitySleptLocked(r);
11593            }
11594        }
11595
11596        Binder.restoreCallingIdentity(origId);
11597    }
11598
11599    private String lockScreenShownToString() {
11600        switch (mLockScreenShown) {
11601            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11602            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11603            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11604            default: return "Unknown=" + mLockScreenShown;
11605        }
11606    }
11607
11608    void logLockScreen(String msg) {
11609        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11610                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11611                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11612                + " mSleeping=" + mSleeping);
11613    }
11614
11615    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11616        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11617        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11618        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11619            boolean wasRunningVoice = mRunningVoice != null;
11620            mRunningVoice = session;
11621            if (!wasRunningVoice) {
11622                mVoiceWakeLock.acquire();
11623                updateSleepIfNeededLocked();
11624            }
11625        }
11626    }
11627
11628    private void updateEventDispatchingLocked() {
11629        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11630    }
11631
11632    public void setLockScreenShown(boolean showing, boolean occluded) {
11633        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11634                != PackageManager.PERMISSION_GRANTED) {
11635            throw new SecurityException("Requires permission "
11636                    + android.Manifest.permission.DEVICE_POWER);
11637        }
11638
11639        synchronized(this) {
11640            long ident = Binder.clearCallingIdentity();
11641            try {
11642                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11643                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11644                if (showing && occluded) {
11645                    // The lock screen is currently showing, but is occluded by a window that can
11646                    // show on top of the lock screen. In this can we want to dismiss the docked
11647                    // stack since it will be complicated/risky to try to put the activity on top
11648                    // of the lock screen in the right fullscreen configuration.
11649                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11650                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11651                }
11652
11653                updateSleepIfNeededLocked();
11654            } finally {
11655                Binder.restoreCallingIdentity(ident);
11656            }
11657        }
11658    }
11659
11660    @Override
11661    public void notifyLockedProfile(@UserIdInt int userId) {
11662        try {
11663            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11664                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11665            }
11666        } catch (RemoteException ex) {
11667            throw new SecurityException("Fail to check is caller a privileged app", ex);
11668        }
11669
11670        synchronized (this) {
11671            if (mStackSupervisor.isUserLockedProfile(userId)) {
11672                final long ident = Binder.clearCallingIdentity();
11673                try {
11674                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11675                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11676                        // If there is no device lock, we will show the profile's credential page.
11677                        mActivityStarter.showConfirmDeviceCredential(userId);
11678                    } else {
11679                        // Showing launcher to avoid user entering credential twice.
11680                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11681                    }
11682                } finally {
11683                    Binder.restoreCallingIdentity(ident);
11684                }
11685            }
11686        }
11687    }
11688
11689    @Override
11690    public void startConfirmDeviceCredentialIntent(Intent intent) {
11691        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11692        synchronized (this) {
11693            final long ident = Binder.clearCallingIdentity();
11694            try {
11695                mActivityStarter.startConfirmCredentialIntent(intent);
11696            } finally {
11697                Binder.restoreCallingIdentity(ident);
11698            }
11699        }
11700    }
11701
11702    @Override
11703    public void stopAppSwitches() {
11704        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11705                != PackageManager.PERMISSION_GRANTED) {
11706            throw new SecurityException("viewquires permission "
11707                    + android.Manifest.permission.STOP_APP_SWITCHES);
11708        }
11709
11710        synchronized(this) {
11711            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11712                    + APP_SWITCH_DELAY_TIME;
11713            mDidAppSwitch = false;
11714            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11715            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11716            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11717        }
11718    }
11719
11720    public void resumeAppSwitches() {
11721        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11722                != PackageManager.PERMISSION_GRANTED) {
11723            throw new SecurityException("Requires permission "
11724                    + android.Manifest.permission.STOP_APP_SWITCHES);
11725        }
11726
11727        synchronized(this) {
11728            // Note that we don't execute any pending app switches... we will
11729            // let those wait until either the timeout, or the next start
11730            // activity request.
11731            mAppSwitchesAllowedTime = 0;
11732        }
11733    }
11734
11735    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11736            int callingPid, int callingUid, String name) {
11737        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11738            return true;
11739        }
11740
11741        int perm = checkComponentPermission(
11742                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11743                sourceUid, -1, true);
11744        if (perm == PackageManager.PERMISSION_GRANTED) {
11745            return true;
11746        }
11747
11748        // If the actual IPC caller is different from the logical source, then
11749        // also see if they are allowed to control app switches.
11750        if (callingUid != -1 && callingUid != sourceUid) {
11751            perm = checkComponentPermission(
11752                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11753                    callingUid, -1, true);
11754            if (perm == PackageManager.PERMISSION_GRANTED) {
11755                return true;
11756            }
11757        }
11758
11759        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11760        return false;
11761    }
11762
11763    public void setDebugApp(String packageName, boolean waitForDebugger,
11764            boolean persistent) {
11765        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11766                "setDebugApp()");
11767
11768        long ident = Binder.clearCallingIdentity();
11769        try {
11770            // Note that this is not really thread safe if there are multiple
11771            // callers into it at the same time, but that's not a situation we
11772            // care about.
11773            if (persistent) {
11774                final ContentResolver resolver = mContext.getContentResolver();
11775                Settings.Global.putString(
11776                    resolver, Settings.Global.DEBUG_APP,
11777                    packageName);
11778                Settings.Global.putInt(
11779                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11780                    waitForDebugger ? 1 : 0);
11781            }
11782
11783            synchronized (this) {
11784                if (!persistent) {
11785                    mOrigDebugApp = mDebugApp;
11786                    mOrigWaitForDebugger = mWaitForDebugger;
11787                }
11788                mDebugApp = packageName;
11789                mWaitForDebugger = waitForDebugger;
11790                mDebugTransient = !persistent;
11791                if (packageName != null) {
11792                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11793                            false, UserHandle.USER_ALL, "set debug app");
11794                }
11795            }
11796        } finally {
11797            Binder.restoreCallingIdentity(ident);
11798        }
11799    }
11800
11801    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11802        synchronized (this) {
11803            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11804            if (!isDebuggable) {
11805                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11806                    throw new SecurityException("Process not debuggable: " + app.packageName);
11807                }
11808            }
11809
11810            mTrackAllocationApp = processName;
11811        }
11812    }
11813
11814    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11815        synchronized (this) {
11816            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11817            if (!isDebuggable) {
11818                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11819                    throw new SecurityException("Process not debuggable: " + app.packageName);
11820                }
11821            }
11822            mProfileApp = processName;
11823            mProfileFile = profilerInfo.profileFile;
11824            if (mProfileFd != null) {
11825                try {
11826                    mProfileFd.close();
11827                } catch (IOException e) {
11828                }
11829                mProfileFd = null;
11830            }
11831            mProfileFd = profilerInfo.profileFd;
11832            mSamplingInterval = profilerInfo.samplingInterval;
11833            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11834            mProfileType = 0;
11835        }
11836    }
11837
11838    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11839        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11840        if (!isDebuggable) {
11841            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11842                throw new SecurityException("Process not debuggable: " + app.packageName);
11843            }
11844        }
11845        mNativeDebuggingApp = processName;
11846    }
11847
11848    @Override
11849    public void setAlwaysFinish(boolean enabled) {
11850        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11851                "setAlwaysFinish()");
11852
11853        long ident = Binder.clearCallingIdentity();
11854        try {
11855            Settings.Global.putInt(
11856                    mContext.getContentResolver(),
11857                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11858
11859            synchronized (this) {
11860                mAlwaysFinishActivities = enabled;
11861            }
11862        } finally {
11863            Binder.restoreCallingIdentity(ident);
11864        }
11865    }
11866
11867    @Override
11868    public void setLenientBackgroundCheck(boolean enabled) {
11869        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11870                "setLenientBackgroundCheck()");
11871
11872        long ident = Binder.clearCallingIdentity();
11873        try {
11874            Settings.Global.putInt(
11875                    mContext.getContentResolver(),
11876                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11877
11878            synchronized (this) {
11879                mLenientBackgroundCheck = enabled;
11880            }
11881        } finally {
11882            Binder.restoreCallingIdentity(ident);
11883        }
11884    }
11885
11886    @Override
11887    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11888        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11889                "setActivityController()");
11890        synchronized (this) {
11891            mController = controller;
11892            mControllerIsAMonkey = imAMonkey;
11893            Watchdog.getInstance().setActivityController(controller);
11894        }
11895    }
11896
11897    @Override
11898    public void setUserIsMonkey(boolean userIsMonkey) {
11899        synchronized (this) {
11900            synchronized (mPidsSelfLocked) {
11901                final int callingPid = Binder.getCallingPid();
11902                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11903                if (precessRecord == null) {
11904                    throw new SecurityException("Unknown process: " + callingPid);
11905                }
11906                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11907                    throw new SecurityException("Only an instrumentation process "
11908                            + "with a UiAutomation can call setUserIsMonkey");
11909                }
11910            }
11911            mUserIsMonkey = userIsMonkey;
11912        }
11913    }
11914
11915    @Override
11916    public boolean isUserAMonkey() {
11917        synchronized (this) {
11918            // If there is a controller also implies the user is a monkey.
11919            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11920        }
11921    }
11922
11923    public void requestBugReport(int bugreportType) {
11924        String service = null;
11925        switch (bugreportType) {
11926            case ActivityManager.BUGREPORT_OPTION_FULL:
11927                service = "bugreport";
11928                break;
11929            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11930                service = "bugreportplus";
11931                break;
11932            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11933                service = "bugreportremote";
11934                break;
11935        }
11936        if (service == null) {
11937            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11938                    + bugreportType);
11939        }
11940        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11941        SystemProperties.set("ctl.start", service);
11942    }
11943
11944    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11945        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11946    }
11947
11948    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11949        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11950            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11951        }
11952        return KEY_DISPATCHING_TIMEOUT;
11953    }
11954
11955    @Override
11956    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11957        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11958                != PackageManager.PERMISSION_GRANTED) {
11959            throw new SecurityException("Requires permission "
11960                    + android.Manifest.permission.FILTER_EVENTS);
11961        }
11962        ProcessRecord proc;
11963        long timeout;
11964        synchronized (this) {
11965            synchronized (mPidsSelfLocked) {
11966                proc = mPidsSelfLocked.get(pid);
11967            }
11968            timeout = getInputDispatchingTimeoutLocked(proc);
11969        }
11970
11971        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11972            return -1;
11973        }
11974
11975        return timeout;
11976    }
11977
11978    /**
11979     * Handle input dispatching timeouts.
11980     * Returns whether input dispatching should be aborted or not.
11981     */
11982    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11983            final ActivityRecord activity, final ActivityRecord parent,
11984            final boolean aboveSystem, String reason) {
11985        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11986                != PackageManager.PERMISSION_GRANTED) {
11987            throw new SecurityException("Requires permission "
11988                    + android.Manifest.permission.FILTER_EVENTS);
11989        }
11990
11991        final String annotation;
11992        if (reason == null) {
11993            annotation = "Input dispatching timed out";
11994        } else {
11995            annotation = "Input dispatching timed out (" + reason + ")";
11996        }
11997
11998        if (proc != null) {
11999            synchronized (this) {
12000                if (proc.debugging) {
12001                    return false;
12002                }
12003
12004                if (mDidDexOpt) {
12005                    // Give more time since we were dexopting.
12006                    mDidDexOpt = false;
12007                    return false;
12008                }
12009
12010                if (proc.instrumentationClass != null) {
12011                    Bundle info = new Bundle();
12012                    info.putString("shortMsg", "keyDispatchingTimedOut");
12013                    info.putString("longMsg", annotation);
12014                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12015                    return true;
12016                }
12017            }
12018            mHandler.post(new Runnable() {
12019                @Override
12020                public void run() {
12021                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12022                }
12023            });
12024        }
12025
12026        return true;
12027    }
12028
12029    @Override
12030    public Bundle getAssistContextExtras(int requestType) {
12031        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12032                null, null, true /* focused */, true /* newSessionId */,
12033                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12034        if (pae == null) {
12035            return null;
12036        }
12037        synchronized (pae) {
12038            while (!pae.haveResult) {
12039                try {
12040                    pae.wait();
12041                } catch (InterruptedException e) {
12042                }
12043            }
12044        }
12045        synchronized (this) {
12046            buildAssistBundleLocked(pae, pae.result);
12047            mPendingAssistExtras.remove(pae);
12048            mUiHandler.removeCallbacks(pae);
12049        }
12050        return pae.extras;
12051    }
12052
12053    @Override
12054    public boolean isAssistDataAllowedOnCurrentActivity() {
12055        int userId;
12056        synchronized (this) {
12057            userId = mUserController.getCurrentUserIdLocked();
12058            ActivityRecord activity = getFocusedStack().topActivity();
12059            if (activity == null) {
12060                return false;
12061            }
12062            userId = activity.userId;
12063        }
12064        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12065                Context.DEVICE_POLICY_SERVICE);
12066        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12067    }
12068
12069    @Override
12070    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12071        long ident = Binder.clearCallingIdentity();
12072        try {
12073            synchronized (this) {
12074                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12075                ActivityRecord top = getFocusedStack().topActivity();
12076                if (top != caller) {
12077                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12078                            + " is not current top " + top);
12079                    return false;
12080                }
12081                if (!top.nowVisible) {
12082                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12083                            + " is not visible");
12084                    return false;
12085                }
12086            }
12087            AssistUtils utils = new AssistUtils(mContext);
12088            return utils.showSessionForActiveService(args,
12089                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12090        } finally {
12091            Binder.restoreCallingIdentity(ident);
12092        }
12093    }
12094
12095    @Override
12096    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12097            Bundle receiverExtras,
12098            IBinder activityToken, boolean focused, boolean newSessionId) {
12099        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12100                activityToken, focused, newSessionId,
12101                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12102                != null;
12103    }
12104
12105    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12106            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12107            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12108        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12109                "enqueueAssistContext()");
12110        synchronized (this) {
12111            ActivityRecord activity = getFocusedStack().topActivity();
12112            if (activity == null) {
12113                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12114                return null;
12115            }
12116            if (activity.app == null || activity.app.thread == null) {
12117                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12118                return null;
12119            }
12120            if (focused) {
12121                if (activityToken != null) {
12122                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12123                    if (activity != caller) {
12124                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12125                                + " is not current top " + activity);
12126                        return null;
12127                    }
12128                }
12129            } else {
12130                activity = ActivityRecord.forTokenLocked(activityToken);
12131                if (activity == null) {
12132                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12133                            + " couldn't be found");
12134                    return null;
12135                }
12136            }
12137
12138            PendingAssistExtras pae;
12139            Bundle extras = new Bundle();
12140            if (args != null) {
12141                extras.putAll(args);
12142            }
12143            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12144            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12145            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12146                    userHandle);
12147            // Increment the sessionId if necessary
12148            if (newSessionId) {
12149                mViSessionId++;
12150            }
12151            try {
12152                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12153                        requestType, mViSessionId);
12154                mPendingAssistExtras.add(pae);
12155                mUiHandler.postDelayed(pae, timeout);
12156            } catch (RemoteException e) {
12157                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12158                return null;
12159            }
12160            return pae;
12161        }
12162    }
12163
12164    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12165        IResultReceiver receiver;
12166        synchronized (this) {
12167            mPendingAssistExtras.remove(pae);
12168            receiver = pae.receiver;
12169        }
12170        if (receiver != null) {
12171            // Caller wants result sent back to them.
12172            Bundle sendBundle = new Bundle();
12173            // At least return the receiver extras
12174            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12175                    pae.receiverExtras);
12176            try {
12177                pae.receiver.send(0, sendBundle);
12178            } catch (RemoteException e) {
12179            }
12180        }
12181    }
12182
12183    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12184        if (result != null) {
12185            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12186        }
12187        if (pae.hint != null) {
12188            pae.extras.putBoolean(pae.hint, true);
12189        }
12190    }
12191
12192    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12193            AssistContent content, Uri referrer) {
12194        PendingAssistExtras pae = (PendingAssistExtras)token;
12195        synchronized (pae) {
12196            pae.result = extras;
12197            pae.structure = structure;
12198            pae.content = content;
12199            if (referrer != null) {
12200                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12201            }
12202            pae.haveResult = true;
12203            pae.notifyAll();
12204            if (pae.intent == null && pae.receiver == null) {
12205                // Caller is just waiting for the result.
12206                return;
12207            }
12208        }
12209
12210        // We are now ready to launch the assist activity.
12211        IResultReceiver sendReceiver = null;
12212        Bundle sendBundle = null;
12213        synchronized (this) {
12214            buildAssistBundleLocked(pae, extras);
12215            boolean exists = mPendingAssistExtras.remove(pae);
12216            mUiHandler.removeCallbacks(pae);
12217            if (!exists) {
12218                // Timed out.
12219                return;
12220            }
12221            if ((sendReceiver=pae.receiver) != null) {
12222                // Caller wants result sent back to them.
12223                sendBundle = new Bundle();
12224                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12225                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12226                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12227                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12228                        pae.receiverExtras);
12229            }
12230        }
12231        if (sendReceiver != null) {
12232            try {
12233                sendReceiver.send(0, sendBundle);
12234            } catch (RemoteException e) {
12235            }
12236            return;
12237        }
12238
12239        long ident = Binder.clearCallingIdentity();
12240        try {
12241            pae.intent.replaceExtras(pae.extras);
12242            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12243                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12244                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12245            closeSystemDialogs("assist");
12246            try {
12247                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12248            } catch (ActivityNotFoundException e) {
12249                Slog.w(TAG, "No activity to handle assist action.", e);
12250            }
12251        } finally {
12252            Binder.restoreCallingIdentity(ident);
12253        }
12254    }
12255
12256    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12257            Bundle args) {
12258        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12259                true /* focused */, true /* newSessionId */,
12260                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12261    }
12262
12263    public void registerProcessObserver(IProcessObserver observer) {
12264        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12265                "registerProcessObserver()");
12266        synchronized (this) {
12267            mProcessObservers.register(observer);
12268        }
12269    }
12270
12271    @Override
12272    public void unregisterProcessObserver(IProcessObserver observer) {
12273        synchronized (this) {
12274            mProcessObservers.unregister(observer);
12275        }
12276    }
12277
12278    @Override
12279    public void registerUidObserver(IUidObserver observer, int which) {
12280        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12281                "registerUidObserver()");
12282        synchronized (this) {
12283            mUidObservers.register(observer, which);
12284        }
12285    }
12286
12287    @Override
12288    public void unregisterUidObserver(IUidObserver observer) {
12289        synchronized (this) {
12290            mUidObservers.unregister(observer);
12291        }
12292    }
12293
12294    @Override
12295    public boolean convertFromTranslucent(IBinder token) {
12296        final long origId = Binder.clearCallingIdentity();
12297        try {
12298            synchronized (this) {
12299                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12300                if (r == null) {
12301                    return false;
12302                }
12303                final boolean translucentChanged = r.changeWindowTranslucency(true);
12304                if (translucentChanged) {
12305                    r.task.stack.releaseBackgroundResources(r);
12306                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12307                }
12308                mWindowManager.setAppFullscreen(token, true);
12309                return translucentChanged;
12310            }
12311        } finally {
12312            Binder.restoreCallingIdentity(origId);
12313        }
12314    }
12315
12316    @Override
12317    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12318        final long origId = Binder.clearCallingIdentity();
12319        try {
12320            synchronized (this) {
12321                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12322                if (r == null) {
12323                    return false;
12324                }
12325                int index = r.task.mActivities.lastIndexOf(r);
12326                if (index > 0) {
12327                    ActivityRecord under = r.task.mActivities.get(index - 1);
12328                    under.returningOptions = options;
12329                }
12330                final boolean translucentChanged = r.changeWindowTranslucency(false);
12331                if (translucentChanged) {
12332                    r.task.stack.convertActivityToTranslucent(r);
12333                }
12334                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12335                mWindowManager.setAppFullscreen(token, false);
12336                return translucentChanged;
12337            }
12338        } finally {
12339            Binder.restoreCallingIdentity(origId);
12340        }
12341    }
12342
12343    @Override
12344    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12345        final long origId = Binder.clearCallingIdentity();
12346        try {
12347            synchronized (this) {
12348                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12349                if (r != null) {
12350                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12351                }
12352            }
12353            return false;
12354        } finally {
12355            Binder.restoreCallingIdentity(origId);
12356        }
12357    }
12358
12359    @Override
12360    public boolean isBackgroundVisibleBehind(IBinder token) {
12361        final long origId = Binder.clearCallingIdentity();
12362        try {
12363            synchronized (this) {
12364                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12365                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12366                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12367                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12368                return visible;
12369            }
12370        } finally {
12371            Binder.restoreCallingIdentity(origId);
12372        }
12373    }
12374
12375    @Override
12376    public ActivityOptions getActivityOptions(IBinder token) {
12377        final long origId = Binder.clearCallingIdentity();
12378        try {
12379            synchronized (this) {
12380                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12381                if (r != null) {
12382                    final ActivityOptions activityOptions = r.pendingOptions;
12383                    r.pendingOptions = null;
12384                    return activityOptions;
12385                }
12386                return null;
12387            }
12388        } finally {
12389            Binder.restoreCallingIdentity(origId);
12390        }
12391    }
12392
12393    @Override
12394    public void setImmersive(IBinder token, boolean immersive) {
12395        synchronized(this) {
12396            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12397            if (r == null) {
12398                throw new IllegalArgumentException();
12399            }
12400            r.immersive = immersive;
12401
12402            // update associated state if we're frontmost
12403            if (r == mFocusedActivity) {
12404                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12405                applyUpdateLockStateLocked(r);
12406            }
12407        }
12408    }
12409
12410    @Override
12411    public boolean isImmersive(IBinder token) {
12412        synchronized (this) {
12413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12414            if (r == null) {
12415                throw new IllegalArgumentException();
12416            }
12417            return r.immersive;
12418        }
12419    }
12420
12421    @Override
12422    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12423        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12424            throw new UnsupportedOperationException("VR mode not supported on this device!");
12425        }
12426
12427        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12428
12429        ActivityRecord r;
12430        synchronized (this) {
12431            r = ActivityRecord.isInStackLocked(token);
12432        }
12433
12434        if (r == null) {
12435            throw new IllegalArgumentException();
12436        }
12437
12438        int err;
12439        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12440                VrManagerInternal.NO_ERROR) {
12441            return err;
12442        }
12443
12444        synchronized(this) {
12445            r.requestedVrComponent = (enabled) ? packageName : null;
12446
12447            // Update associated state if this activity is currently focused
12448            if (r == mFocusedActivity) {
12449                applyUpdateVrModeLocked(r);
12450            }
12451            return 0;
12452        }
12453    }
12454
12455    @Override
12456    public boolean isVrModePackageEnabled(ComponentName packageName) {
12457        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12458            throw new UnsupportedOperationException("VR mode not supported on this device!");
12459        }
12460
12461        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12462
12463        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12464                VrManagerInternal.NO_ERROR;
12465    }
12466
12467    public boolean isTopActivityImmersive() {
12468        enforceNotIsolatedCaller("startActivity");
12469        synchronized (this) {
12470            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12471            return (r != null) ? r.immersive : false;
12472        }
12473    }
12474
12475    @Override
12476    public boolean isTopOfTask(IBinder token) {
12477        synchronized (this) {
12478            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12479            if (r == null) {
12480                throw new IllegalArgumentException();
12481            }
12482            return r.task.getTopActivity() == r;
12483        }
12484    }
12485
12486    public final void enterSafeMode() {
12487        synchronized(this) {
12488            // It only makes sense to do this before the system is ready
12489            // and started launching other packages.
12490            if (!mSystemReady) {
12491                try {
12492                    AppGlobals.getPackageManager().enterSafeMode();
12493                } catch (RemoteException e) {
12494                }
12495            }
12496
12497            mSafeMode = true;
12498        }
12499    }
12500
12501    public final void showSafeModeOverlay() {
12502        View v = LayoutInflater.from(mContext).inflate(
12503                com.android.internal.R.layout.safe_mode, null);
12504        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12505        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12506        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12507        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12508        lp.gravity = Gravity.BOTTOM | Gravity.START;
12509        lp.format = v.getBackground().getOpacity();
12510        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12511                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12512        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12513        ((WindowManager)mContext.getSystemService(
12514                Context.WINDOW_SERVICE)).addView(v, lp);
12515    }
12516
12517    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12518        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12519            return;
12520        }
12521        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12522        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12523        synchronized (stats) {
12524            if (mBatteryStatsService.isOnBattery()) {
12525                mBatteryStatsService.enforceCallingPermission();
12526                int MY_UID = Binder.getCallingUid();
12527                final int uid;
12528                if (sender == null) {
12529                    uid = sourceUid;
12530                } else {
12531                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12532                }
12533                BatteryStatsImpl.Uid.Pkg pkg =
12534                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12535                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12536                pkg.noteWakeupAlarmLocked(tag);
12537            }
12538        }
12539    }
12540
12541    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12542        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12543            return;
12544        }
12545        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12546        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12547        synchronized (stats) {
12548            mBatteryStatsService.enforceCallingPermission();
12549            int MY_UID = Binder.getCallingUid();
12550            final int uid;
12551            if (sender == null) {
12552                uid = sourceUid;
12553            } else {
12554                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12555            }
12556            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12557        }
12558    }
12559
12560    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12561        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12562            return;
12563        }
12564        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12565        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12566        synchronized (stats) {
12567            mBatteryStatsService.enforceCallingPermission();
12568            int MY_UID = Binder.getCallingUid();
12569            final int uid;
12570            if (sender == null) {
12571                uid = sourceUid;
12572            } else {
12573                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12574            }
12575            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12576        }
12577    }
12578
12579    public boolean killPids(int[] pids, String pReason, boolean secure) {
12580        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12581            throw new SecurityException("killPids only available to the system");
12582        }
12583        String reason = (pReason == null) ? "Unknown" : pReason;
12584        // XXX Note: don't acquire main activity lock here, because the window
12585        // manager calls in with its locks held.
12586
12587        boolean killed = false;
12588        synchronized (mPidsSelfLocked) {
12589            int worstType = 0;
12590            for (int i=0; i<pids.length; i++) {
12591                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12592                if (proc != null) {
12593                    int type = proc.setAdj;
12594                    if (type > worstType) {
12595                        worstType = type;
12596                    }
12597                }
12598            }
12599
12600            // If the worst oom_adj is somewhere in the cached proc LRU range,
12601            // then constrain it so we will kill all cached procs.
12602            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12603                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12604                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12605            }
12606
12607            // If this is not a secure call, don't let it kill processes that
12608            // are important.
12609            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12610                worstType = ProcessList.SERVICE_ADJ;
12611            }
12612
12613            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12614            for (int i=0; i<pids.length; i++) {
12615                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12616                if (proc == null) {
12617                    continue;
12618                }
12619                int adj = proc.setAdj;
12620                if (adj >= worstType && !proc.killedByAm) {
12621                    proc.kill(reason, true);
12622                    killed = true;
12623                }
12624            }
12625        }
12626        return killed;
12627    }
12628
12629    @Override
12630    public void killUid(int appId, int userId, String reason) {
12631        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12632        synchronized (this) {
12633            final long identity = Binder.clearCallingIdentity();
12634            try {
12635                killPackageProcessesLocked(null, appId, userId,
12636                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12637                        reason != null ? reason : "kill uid");
12638            } finally {
12639                Binder.restoreCallingIdentity(identity);
12640            }
12641        }
12642    }
12643
12644    @Override
12645    public boolean killProcessesBelowForeground(String reason) {
12646        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12647            throw new SecurityException("killProcessesBelowForeground() only available to system");
12648        }
12649
12650        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12651    }
12652
12653    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12654        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12655            throw new SecurityException("killProcessesBelowAdj() only available to system");
12656        }
12657
12658        boolean killed = false;
12659        synchronized (mPidsSelfLocked) {
12660            final int size = mPidsSelfLocked.size();
12661            for (int i = 0; i < size; i++) {
12662                final int pid = mPidsSelfLocked.keyAt(i);
12663                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12664                if (proc == null) continue;
12665
12666                final int adj = proc.setAdj;
12667                if (adj > belowAdj && !proc.killedByAm) {
12668                    proc.kill(reason, true);
12669                    killed = true;
12670                }
12671            }
12672        }
12673        return killed;
12674    }
12675
12676    @Override
12677    public void hang(final IBinder who, boolean allowRestart) {
12678        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12679                != PackageManager.PERMISSION_GRANTED) {
12680            throw new SecurityException("Requires permission "
12681                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12682        }
12683
12684        final IBinder.DeathRecipient death = new DeathRecipient() {
12685            @Override
12686            public void binderDied() {
12687                synchronized (this) {
12688                    notifyAll();
12689                }
12690            }
12691        };
12692
12693        try {
12694            who.linkToDeath(death, 0);
12695        } catch (RemoteException e) {
12696            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12697            return;
12698        }
12699
12700        synchronized (this) {
12701            Watchdog.getInstance().setAllowRestart(allowRestart);
12702            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12703            synchronized (death) {
12704                while (who.isBinderAlive()) {
12705                    try {
12706                        death.wait();
12707                    } catch (InterruptedException e) {
12708                    }
12709                }
12710            }
12711            Watchdog.getInstance().setAllowRestart(true);
12712        }
12713    }
12714
12715    @Override
12716    public void restart() {
12717        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12718                != PackageManager.PERMISSION_GRANTED) {
12719            throw new SecurityException("Requires permission "
12720                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12721        }
12722
12723        Log.i(TAG, "Sending shutdown broadcast...");
12724
12725        BroadcastReceiver br = new BroadcastReceiver() {
12726            @Override public void onReceive(Context context, Intent intent) {
12727                // Now the broadcast is done, finish up the low-level shutdown.
12728                Log.i(TAG, "Shutting down activity manager...");
12729                shutdown(10000);
12730                Log.i(TAG, "Shutdown complete, restarting!");
12731                Process.killProcess(Process.myPid());
12732                System.exit(10);
12733            }
12734        };
12735
12736        // First send the high-level shut down broadcast.
12737        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12738        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12739        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12740        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12741        mContext.sendOrderedBroadcastAsUser(intent,
12742                UserHandle.ALL, null, br, mHandler, 0, null, null);
12743        */
12744        br.onReceive(mContext, intent);
12745    }
12746
12747    private long getLowRamTimeSinceIdle(long now) {
12748        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12749    }
12750
12751    @Override
12752    public void performIdleMaintenance() {
12753        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12754                != PackageManager.PERMISSION_GRANTED) {
12755            throw new SecurityException("Requires permission "
12756                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12757        }
12758
12759        synchronized (this) {
12760            final long now = SystemClock.uptimeMillis();
12761            final long timeSinceLastIdle = now - mLastIdleTime;
12762            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12763            mLastIdleTime = now;
12764            mLowRamTimeSinceLastIdle = 0;
12765            if (mLowRamStartTime != 0) {
12766                mLowRamStartTime = now;
12767            }
12768
12769            StringBuilder sb = new StringBuilder(128);
12770            sb.append("Idle maintenance over ");
12771            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12772            sb.append(" low RAM for ");
12773            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12774            Slog.i(TAG, sb.toString());
12775
12776            // If at least 1/3 of our time since the last idle period has been spent
12777            // with RAM low, then we want to kill processes.
12778            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12779
12780            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12781                ProcessRecord proc = mLruProcesses.get(i);
12782                if (proc.notCachedSinceIdle) {
12783                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12784                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12785                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12786                        if (doKilling && proc.initialIdlePss != 0
12787                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12788                            sb = new StringBuilder(128);
12789                            sb.append("Kill");
12790                            sb.append(proc.processName);
12791                            sb.append(" in idle maint: pss=");
12792                            sb.append(proc.lastPss);
12793                            sb.append(", swapPss=");
12794                            sb.append(proc.lastSwapPss);
12795                            sb.append(", initialPss=");
12796                            sb.append(proc.initialIdlePss);
12797                            sb.append(", period=");
12798                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12799                            sb.append(", lowRamPeriod=");
12800                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12801                            Slog.wtfQuiet(TAG, sb.toString());
12802                            proc.kill("idle maint (pss " + proc.lastPss
12803                                    + " from " + proc.initialIdlePss + ")", true);
12804                        }
12805                    }
12806                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12807                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12808                    proc.notCachedSinceIdle = true;
12809                    proc.initialIdlePss = 0;
12810                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12811                            mTestPssMode, isSleeping(), now);
12812                }
12813            }
12814
12815            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12816            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12817        }
12818    }
12819
12820    @Override
12821    public void sendIdleJobTrigger() {
12822        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12823                != PackageManager.PERMISSION_GRANTED) {
12824            throw new SecurityException("Requires permission "
12825                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12826        }
12827
12828        final long ident = Binder.clearCallingIdentity();
12829        try {
12830            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12831                    .setPackage("android")
12832                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12833            broadcastIntent(null, intent, null, null, 0, null, null, null,
12834                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12835        } finally {
12836            Binder.restoreCallingIdentity(ident);
12837        }
12838    }
12839
12840    private void retrieveSettings() {
12841        final ContentResolver resolver = mContext.getContentResolver();
12842        final boolean freeformWindowManagement =
12843                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12844                        || Settings.Global.getInt(
12845                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12846        final boolean supportsPictureInPicture =
12847                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12848
12849        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12850        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12851        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12852        final boolean alwaysFinishActivities =
12853                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12854        final boolean lenientBackgroundCheck =
12855                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12856        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12857        final boolean forceResizable = Settings.Global.getInt(
12858                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12859        final boolean supportsLeanbackOnly =
12860                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12861
12862        // Transfer any global setting for forcing RTL layout, into a System Property
12863        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12864
12865        final Configuration configuration = new Configuration();
12866        Settings.System.getConfiguration(resolver, configuration);
12867        if (forceRtl) {
12868            // This will take care of setting the correct layout direction flags
12869            configuration.setLayoutDirection(configuration.locale);
12870        }
12871
12872        synchronized (this) {
12873            mDebugApp = mOrigDebugApp = debugApp;
12874            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12875            mAlwaysFinishActivities = alwaysFinishActivities;
12876            mLenientBackgroundCheck = lenientBackgroundCheck;
12877            mSupportsLeanbackOnly = supportsLeanbackOnly;
12878            mForceResizableActivities = forceResizable;
12879            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12880            if (supportsMultiWindow || forceResizable) {
12881                mSupportsMultiWindow = true;
12882                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12883                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12884            } else {
12885                mSupportsMultiWindow = false;
12886                mSupportsFreeformWindowManagement = false;
12887                mSupportsPictureInPicture = false;
12888            }
12889            // This happens before any activities are started, so we can
12890            // change mConfiguration in-place.
12891            updateConfigurationLocked(configuration, null, true);
12892            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12893                    "Initial config: " + mConfiguration);
12894
12895            // Load resources only after the current configuration has been set.
12896            final Resources res = mContext.getResources();
12897            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12898            mThumbnailWidth = res.getDimensionPixelSize(
12899                    com.android.internal.R.dimen.thumbnail_width);
12900            mThumbnailHeight = res.getDimensionPixelSize(
12901                    com.android.internal.R.dimen.thumbnail_height);
12902            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12903                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12904            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12905                    com.android.internal.R.string.config_appsNotReportingCrashes));
12906            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12907                mFullscreenThumbnailScale = (float) res
12908                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12909                    (float) mConfiguration.screenWidthDp;
12910            } else {
12911                mFullscreenThumbnailScale = res.getFraction(
12912                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12913            }
12914        }
12915    }
12916
12917    public boolean testIsSystemReady() {
12918        // no need to synchronize(this) just to read & return the value
12919        return mSystemReady;
12920    }
12921
12922    public void systemReady(final Runnable goingCallback) {
12923        synchronized(this) {
12924            if (mSystemReady) {
12925                // If we're done calling all the receivers, run the next "boot phase" passed in
12926                // by the SystemServer
12927                if (goingCallback != null) {
12928                    goingCallback.run();
12929                }
12930                return;
12931            }
12932
12933            mLocalDeviceIdleController
12934                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12935
12936            // Make sure we have the current profile info, since it is needed for security checks.
12937            mUserController.onSystemReady();
12938            mRecentTasks.onSystemReadyLocked();
12939            mAppOpsService.systemReady();
12940            mSystemReady = true;
12941        }
12942
12943        ArrayList<ProcessRecord> procsToKill = null;
12944        synchronized(mPidsSelfLocked) {
12945            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12946                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12947                if (!isAllowedWhileBooting(proc.info)){
12948                    if (procsToKill == null) {
12949                        procsToKill = new ArrayList<ProcessRecord>();
12950                    }
12951                    procsToKill.add(proc);
12952                }
12953            }
12954        }
12955
12956        synchronized(this) {
12957            if (procsToKill != null) {
12958                for (int i=procsToKill.size()-1; i>=0; i--) {
12959                    ProcessRecord proc = procsToKill.get(i);
12960                    Slog.i(TAG, "Removing system update proc: " + proc);
12961                    removeProcessLocked(proc, true, false, "system update done");
12962                }
12963            }
12964
12965            // Now that we have cleaned up any update processes, we
12966            // are ready to start launching real processes and know that
12967            // we won't trample on them any more.
12968            mProcessesReady = true;
12969        }
12970
12971        Slog.i(TAG, "System now ready");
12972        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12973            SystemClock.uptimeMillis());
12974
12975        synchronized(this) {
12976            // Make sure we have no pre-ready processes sitting around.
12977
12978            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12979                ResolveInfo ri = mContext.getPackageManager()
12980                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12981                                STOCK_PM_FLAGS);
12982                CharSequence errorMsg = null;
12983                if (ri != null) {
12984                    ActivityInfo ai = ri.activityInfo;
12985                    ApplicationInfo app = ai.applicationInfo;
12986                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12987                        mTopAction = Intent.ACTION_FACTORY_TEST;
12988                        mTopData = null;
12989                        mTopComponent = new ComponentName(app.packageName,
12990                                ai.name);
12991                    } else {
12992                        errorMsg = mContext.getResources().getText(
12993                                com.android.internal.R.string.factorytest_not_system);
12994                    }
12995                } else {
12996                    errorMsg = mContext.getResources().getText(
12997                            com.android.internal.R.string.factorytest_no_action);
12998                }
12999                if (errorMsg != null) {
13000                    mTopAction = null;
13001                    mTopData = null;
13002                    mTopComponent = null;
13003                    Message msg = Message.obtain();
13004                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13005                    msg.getData().putCharSequence("msg", errorMsg);
13006                    mUiHandler.sendMessage(msg);
13007                }
13008            }
13009        }
13010
13011        retrieveSettings();
13012        final int currentUserId;
13013        synchronized (this) {
13014            currentUserId = mUserController.getCurrentUserIdLocked();
13015            readGrantedUriPermissionsLocked();
13016        }
13017
13018        if (goingCallback != null) goingCallback.run();
13019
13020        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13021                Integer.toString(currentUserId), currentUserId);
13022        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13023                Integer.toString(currentUserId), currentUserId);
13024        mSystemServiceManager.startUser(currentUserId);
13025
13026        synchronized (this) {
13027            // Only start up encryption-aware persistent apps; once user is
13028            // unlocked we'll come back around and start unaware apps
13029            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13030
13031            // Start up initial activity.
13032            mBooting = true;
13033            // Enable home activity for system user, so that the system can always boot
13034            if (UserManager.isSplitSystemUser()) {
13035                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13036                try {
13037                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13038                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13039                            UserHandle.USER_SYSTEM);
13040                } catch (RemoteException e) {
13041                    throw e.rethrowAsRuntimeException();
13042                }
13043            }
13044            startHomeActivityLocked(currentUserId, "systemReady");
13045
13046            try {
13047                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13048                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13049                            + " data partition or your device will be unstable.");
13050                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13051                }
13052            } catch (RemoteException e) {
13053            }
13054
13055            if (!Build.isBuildConsistent()) {
13056                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13057                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13058            }
13059
13060            long ident = Binder.clearCallingIdentity();
13061            try {
13062                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13064                        | Intent.FLAG_RECEIVER_FOREGROUND);
13065                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13066                broadcastIntentLocked(null, null, intent,
13067                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13068                        null, false, false, MY_PID, Process.SYSTEM_UID,
13069                        currentUserId);
13070                intent = new Intent(Intent.ACTION_USER_STARTING);
13071                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13072                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13073                broadcastIntentLocked(null, null, intent,
13074                        null, new IIntentReceiver.Stub() {
13075                            @Override
13076                            public void performReceive(Intent intent, int resultCode, String data,
13077                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13078                                    throws RemoteException {
13079                            }
13080                        }, 0, null, null,
13081                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13082                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13083            } catch (Throwable t) {
13084                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13085            } finally {
13086                Binder.restoreCallingIdentity(ident);
13087            }
13088            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13089            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13090        }
13091    }
13092
13093    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13094        synchronized (this) {
13095            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13096        }
13097    }
13098
13099    void skipCurrentReceiverLocked(ProcessRecord app) {
13100        for (BroadcastQueue queue : mBroadcastQueues) {
13101            queue.skipCurrentReceiverLocked(app);
13102        }
13103    }
13104
13105    /**
13106     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13107     * The application process will exit immediately after this call returns.
13108     * @param app object of the crashing app, null for the system server
13109     * @param crashInfo describing the exception
13110     */
13111    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13112        ProcessRecord r = findAppProcess(app, "Crash");
13113        final String processName = app == null ? "system_server"
13114                : (r == null ? "unknown" : r.processName);
13115
13116        handleApplicationCrashInner("crash", r, processName, crashInfo);
13117    }
13118
13119    /* Native crash reporting uses this inner version because it needs to be somewhat
13120     * decoupled from the AM-managed cleanup lifecycle
13121     */
13122    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13123            ApplicationErrorReport.CrashInfo crashInfo) {
13124        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13125                UserHandle.getUserId(Binder.getCallingUid()), processName,
13126                r == null ? -1 : r.info.flags,
13127                crashInfo.exceptionClassName,
13128                crashInfo.exceptionMessage,
13129                crashInfo.throwFileName,
13130                crashInfo.throwLineNumber);
13131
13132        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13133
13134        mAppErrors.crashApplication(r, crashInfo);
13135    }
13136
13137    public void handleApplicationStrictModeViolation(
13138            IBinder app,
13139            int violationMask,
13140            StrictMode.ViolationInfo info) {
13141        ProcessRecord r = findAppProcess(app, "StrictMode");
13142        if (r == null) {
13143            return;
13144        }
13145
13146        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13147            Integer stackFingerprint = info.hashCode();
13148            boolean logIt = true;
13149            synchronized (mAlreadyLoggedViolatedStacks) {
13150                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13151                    logIt = false;
13152                    // TODO: sub-sample into EventLog for these, with
13153                    // the info.durationMillis?  Then we'd get
13154                    // the relative pain numbers, without logging all
13155                    // the stack traces repeatedly.  We'd want to do
13156                    // likewise in the client code, which also does
13157                    // dup suppression, before the Binder call.
13158                } else {
13159                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13160                        mAlreadyLoggedViolatedStacks.clear();
13161                    }
13162                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13163                }
13164            }
13165            if (logIt) {
13166                logStrictModeViolationToDropBox(r, info);
13167            }
13168        }
13169
13170        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13171            AppErrorResult result = new AppErrorResult();
13172            synchronized (this) {
13173                final long origId = Binder.clearCallingIdentity();
13174
13175                Message msg = Message.obtain();
13176                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13177                HashMap<String, Object> data = new HashMap<String, Object>();
13178                data.put("result", result);
13179                data.put("app", r);
13180                data.put("violationMask", violationMask);
13181                data.put("info", info);
13182                msg.obj = data;
13183                mUiHandler.sendMessage(msg);
13184
13185                Binder.restoreCallingIdentity(origId);
13186            }
13187            int res = result.get();
13188            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13189        }
13190    }
13191
13192    // Depending on the policy in effect, there could be a bunch of
13193    // these in quick succession so we try to batch these together to
13194    // minimize disk writes, number of dropbox entries, and maximize
13195    // compression, by having more fewer, larger records.
13196    private void logStrictModeViolationToDropBox(
13197            ProcessRecord process,
13198            StrictMode.ViolationInfo info) {
13199        if (info == null) {
13200            return;
13201        }
13202        final boolean isSystemApp = process == null ||
13203                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13204                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13205        final String processName = process == null ? "unknown" : process.processName;
13206        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13207        final DropBoxManager dbox = (DropBoxManager)
13208                mContext.getSystemService(Context.DROPBOX_SERVICE);
13209
13210        // Exit early if the dropbox isn't configured to accept this report type.
13211        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13212
13213        boolean bufferWasEmpty;
13214        boolean needsFlush;
13215        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13216        synchronized (sb) {
13217            bufferWasEmpty = sb.length() == 0;
13218            appendDropBoxProcessHeaders(process, processName, sb);
13219            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13220            sb.append("System-App: ").append(isSystemApp).append("\n");
13221            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13222            if (info.violationNumThisLoop != 0) {
13223                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13224            }
13225            if (info.numAnimationsRunning != 0) {
13226                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13227            }
13228            if (info.broadcastIntentAction != null) {
13229                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13230            }
13231            if (info.durationMillis != -1) {
13232                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13233            }
13234            if (info.numInstances != -1) {
13235                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13236            }
13237            if (info.tags != null) {
13238                for (String tag : info.tags) {
13239                    sb.append("Span-Tag: ").append(tag).append("\n");
13240                }
13241            }
13242            sb.append("\n");
13243            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13244                sb.append(info.crashInfo.stackTrace);
13245                sb.append("\n");
13246            }
13247            if (info.message != null) {
13248                sb.append(info.message);
13249                sb.append("\n");
13250            }
13251
13252            // Only buffer up to ~64k.  Various logging bits truncate
13253            // things at 128k.
13254            needsFlush = (sb.length() > 64 * 1024);
13255        }
13256
13257        // Flush immediately if the buffer's grown too large, or this
13258        // is a non-system app.  Non-system apps are isolated with a
13259        // different tag & policy and not batched.
13260        //
13261        // Batching is useful during internal testing with
13262        // StrictMode settings turned up high.  Without batching,
13263        // thousands of separate files could be created on boot.
13264        if (!isSystemApp || needsFlush) {
13265            new Thread("Error dump: " + dropboxTag) {
13266                @Override
13267                public void run() {
13268                    String report;
13269                    synchronized (sb) {
13270                        report = sb.toString();
13271                        sb.delete(0, sb.length());
13272                        sb.trimToSize();
13273                    }
13274                    if (report.length() != 0) {
13275                        dbox.addText(dropboxTag, report);
13276                    }
13277                }
13278            }.start();
13279            return;
13280        }
13281
13282        // System app batching:
13283        if (!bufferWasEmpty) {
13284            // An existing dropbox-writing thread is outstanding, so
13285            // we don't need to start it up.  The existing thread will
13286            // catch the buffer appends we just did.
13287            return;
13288        }
13289
13290        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13291        // (After this point, we shouldn't access AMS internal data structures.)
13292        new Thread("Error dump: " + dropboxTag) {
13293            @Override
13294            public void run() {
13295                // 5 second sleep to let stacks arrive and be batched together
13296                try {
13297                    Thread.sleep(5000);  // 5 seconds
13298                } catch (InterruptedException e) {}
13299
13300                String errorReport;
13301                synchronized (mStrictModeBuffer) {
13302                    errorReport = mStrictModeBuffer.toString();
13303                    if (errorReport.length() == 0) {
13304                        return;
13305                    }
13306                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13307                    mStrictModeBuffer.trimToSize();
13308                }
13309                dbox.addText(dropboxTag, errorReport);
13310            }
13311        }.start();
13312    }
13313
13314    /**
13315     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13316     * @param app object of the crashing app, null for the system server
13317     * @param tag reported by the caller
13318     * @param system whether this wtf is coming from the system
13319     * @param crashInfo describing the context of the error
13320     * @return true if the process should exit immediately (WTF is fatal)
13321     */
13322    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13323            final ApplicationErrorReport.CrashInfo crashInfo) {
13324        final int callingUid = Binder.getCallingUid();
13325        final int callingPid = Binder.getCallingPid();
13326
13327        if (system) {
13328            // If this is coming from the system, we could very well have low-level
13329            // system locks held, so we want to do this all asynchronously.  And we
13330            // never want this to become fatal, so there is that too.
13331            mHandler.post(new Runnable() {
13332                @Override public void run() {
13333                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13334                }
13335            });
13336            return false;
13337        }
13338
13339        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13340                crashInfo);
13341
13342        if (r != null && r.pid != Process.myPid() &&
13343                Settings.Global.getInt(mContext.getContentResolver(),
13344                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13345            mAppErrors.crashApplication(r, crashInfo);
13346            return true;
13347        } else {
13348            return false;
13349        }
13350    }
13351
13352    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13353            final ApplicationErrorReport.CrashInfo crashInfo) {
13354        final ProcessRecord r = findAppProcess(app, "WTF");
13355        final String processName = app == null ? "system_server"
13356                : (r == null ? "unknown" : r.processName);
13357
13358        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13359                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13360
13361        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13362
13363        return r;
13364    }
13365
13366    /**
13367     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13368     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13369     */
13370    private ProcessRecord findAppProcess(IBinder app, String reason) {
13371        if (app == null) {
13372            return null;
13373        }
13374
13375        synchronized (this) {
13376            final int NP = mProcessNames.getMap().size();
13377            for (int ip=0; ip<NP; ip++) {
13378                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13379                final int NA = apps.size();
13380                for (int ia=0; ia<NA; ia++) {
13381                    ProcessRecord p = apps.valueAt(ia);
13382                    if (p.thread != null && p.thread.asBinder() == app) {
13383                        return p;
13384                    }
13385                }
13386            }
13387
13388            Slog.w(TAG, "Can't find mystery application for " + reason
13389                    + " from pid=" + Binder.getCallingPid()
13390                    + " uid=" + Binder.getCallingUid() + ": " + app);
13391            return null;
13392        }
13393    }
13394
13395    /**
13396     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13397     * to append various headers to the dropbox log text.
13398     */
13399    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13400            StringBuilder sb) {
13401        // Watchdog thread ends up invoking this function (with
13402        // a null ProcessRecord) to add the stack file to dropbox.
13403        // Do not acquire a lock on this (am) in such cases, as it
13404        // could cause a potential deadlock, if and when watchdog
13405        // is invoked due to unavailability of lock on am and it
13406        // would prevent watchdog from killing system_server.
13407        if (process == null) {
13408            sb.append("Process: ").append(processName).append("\n");
13409            return;
13410        }
13411        // Note: ProcessRecord 'process' is guarded by the service
13412        // instance.  (notably process.pkgList, which could otherwise change
13413        // concurrently during execution of this method)
13414        synchronized (this) {
13415            sb.append("Process: ").append(processName).append("\n");
13416            int flags = process.info.flags;
13417            IPackageManager pm = AppGlobals.getPackageManager();
13418            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13419            for (int ip=0; ip<process.pkgList.size(); ip++) {
13420                String pkg = process.pkgList.keyAt(ip);
13421                sb.append("Package: ").append(pkg);
13422                try {
13423                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13424                    if (pi != null) {
13425                        sb.append(" v").append(pi.versionCode);
13426                        if (pi.versionName != null) {
13427                            sb.append(" (").append(pi.versionName).append(")");
13428                        }
13429                    }
13430                } catch (RemoteException e) {
13431                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13432                }
13433                sb.append("\n");
13434            }
13435        }
13436    }
13437
13438    private static String processClass(ProcessRecord process) {
13439        if (process == null || process.pid == MY_PID) {
13440            return "system_server";
13441        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13442            return "system_app";
13443        } else {
13444            return "data_app";
13445        }
13446    }
13447
13448    private volatile long mWtfClusterStart;
13449    private volatile int mWtfClusterCount;
13450
13451    /**
13452     * Write a description of an error (crash, WTF, ANR) to the drop box.
13453     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13454     * @param process which caused the error, null means the system server
13455     * @param activity which triggered the error, null if unknown
13456     * @param parent activity related to the error, null if unknown
13457     * @param subject line related to the error, null if absent
13458     * @param report in long form describing the error, null if absent
13459     * @param logFile to include in the report, null if none
13460     * @param crashInfo giving an application stack trace, null if absent
13461     */
13462    public void addErrorToDropBox(String eventType,
13463            ProcessRecord process, String processName, ActivityRecord activity,
13464            ActivityRecord parent, String subject,
13465            final String report, final File logFile,
13466            final ApplicationErrorReport.CrashInfo crashInfo) {
13467        // NOTE -- this must never acquire the ActivityManagerService lock,
13468        // otherwise the watchdog may be prevented from resetting the system.
13469
13470        final String dropboxTag = processClass(process) + "_" + eventType;
13471        final DropBoxManager dbox = (DropBoxManager)
13472                mContext.getSystemService(Context.DROPBOX_SERVICE);
13473
13474        // Exit early if the dropbox isn't configured to accept this report type.
13475        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13476
13477        // Rate-limit how often we're willing to do the heavy lifting below to
13478        // collect and record logs; currently 5 logs per 10 second period.
13479        final long now = SystemClock.elapsedRealtime();
13480        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13481            mWtfClusterStart = now;
13482            mWtfClusterCount = 1;
13483        } else {
13484            if (mWtfClusterCount++ >= 5) return;
13485        }
13486
13487        final StringBuilder sb = new StringBuilder(1024);
13488        appendDropBoxProcessHeaders(process, processName, sb);
13489        if (process != null) {
13490            sb.append("Foreground: ")
13491                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13492                    .append("\n");
13493        }
13494        if (activity != null) {
13495            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13496        }
13497        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13498            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13499        }
13500        if (parent != null && parent != activity) {
13501            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13502        }
13503        if (subject != null) {
13504            sb.append("Subject: ").append(subject).append("\n");
13505        }
13506        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13507        if (Debug.isDebuggerConnected()) {
13508            sb.append("Debugger: Connected\n");
13509        }
13510        sb.append("\n");
13511
13512        // Do the rest in a worker thread to avoid blocking the caller on I/O
13513        // (After this point, we shouldn't access AMS internal data structures.)
13514        Thread worker = new Thread("Error dump: " + dropboxTag) {
13515            @Override
13516            public void run() {
13517                if (report != null) {
13518                    sb.append(report);
13519                }
13520                if (logFile != null) {
13521                    try {
13522                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13523                                    "\n\n[[TRUNCATED]]"));
13524                    } catch (IOException e) {
13525                        Slog.e(TAG, "Error reading " + logFile, e);
13526                    }
13527                }
13528                if (crashInfo != null && crashInfo.stackTrace != null) {
13529                    sb.append(crashInfo.stackTrace);
13530                }
13531
13532                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13533                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13534                if (lines > 0) {
13535                    sb.append("\n");
13536
13537                    // Merge several logcat streams, and take the last N lines
13538                    InputStreamReader input = null;
13539                    try {
13540                        java.lang.Process logcat = new ProcessBuilder(
13541                                "/system/bin/timeout", "-k", "15s", "10s",
13542                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13543                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13544                                        .redirectErrorStream(true).start();
13545
13546                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13547                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13548                        input = new InputStreamReader(logcat.getInputStream());
13549
13550                        int num;
13551                        char[] buf = new char[8192];
13552                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13553                    } catch (IOException e) {
13554                        Slog.e(TAG, "Error running logcat", e);
13555                    } finally {
13556                        if (input != null) try { input.close(); } catch (IOException e) {}
13557                    }
13558                }
13559
13560                dbox.addText(dropboxTag, sb.toString());
13561            }
13562        };
13563
13564        if (process == null) {
13565            // If process is null, we are being called from some internal code
13566            // and may be about to die -- run this synchronously.
13567            worker.run();
13568        } else {
13569            worker.start();
13570        }
13571    }
13572
13573    @Override
13574    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13575        enforceNotIsolatedCaller("getProcessesInErrorState");
13576        // assume our apps are happy - lazy create the list
13577        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13578
13579        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13580                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13581        int userId = UserHandle.getUserId(Binder.getCallingUid());
13582
13583        synchronized (this) {
13584
13585            // iterate across all processes
13586            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13587                ProcessRecord app = mLruProcesses.get(i);
13588                if (!allUsers && app.userId != userId) {
13589                    continue;
13590                }
13591                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13592                    // This one's in trouble, so we'll generate a report for it
13593                    // crashes are higher priority (in case there's a crash *and* an anr)
13594                    ActivityManager.ProcessErrorStateInfo report = null;
13595                    if (app.crashing) {
13596                        report = app.crashingReport;
13597                    } else if (app.notResponding) {
13598                        report = app.notRespondingReport;
13599                    }
13600
13601                    if (report != null) {
13602                        if (errList == null) {
13603                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13604                        }
13605                        errList.add(report);
13606                    } else {
13607                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13608                                " crashing = " + app.crashing +
13609                                " notResponding = " + app.notResponding);
13610                    }
13611                }
13612            }
13613        }
13614
13615        return errList;
13616    }
13617
13618    static int procStateToImportance(int procState, int memAdj,
13619            ActivityManager.RunningAppProcessInfo currApp) {
13620        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13621        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13622            currApp.lru = memAdj;
13623        } else {
13624            currApp.lru = 0;
13625        }
13626        return imp;
13627    }
13628
13629    private void fillInProcMemInfo(ProcessRecord app,
13630            ActivityManager.RunningAppProcessInfo outInfo) {
13631        outInfo.pid = app.pid;
13632        outInfo.uid = app.info.uid;
13633        if (mHeavyWeightProcess == app) {
13634            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13635        }
13636        if (app.persistent) {
13637            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13638        }
13639        if (app.activities.size() > 0) {
13640            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13641        }
13642        outInfo.lastTrimLevel = app.trimMemoryLevel;
13643        int adj = app.curAdj;
13644        int procState = app.curProcState;
13645        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13646        outInfo.importanceReasonCode = app.adjTypeCode;
13647        outInfo.processState = app.curProcState;
13648    }
13649
13650    @Override
13651    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13652        enforceNotIsolatedCaller("getRunningAppProcesses");
13653
13654        final int callingUid = Binder.getCallingUid();
13655
13656        // Lazy instantiation of list
13657        List<ActivityManager.RunningAppProcessInfo> runList = null;
13658        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13659                callingUid) == PackageManager.PERMISSION_GRANTED;
13660        final int userId = UserHandle.getUserId(callingUid);
13661        final boolean allUids = isGetTasksAllowed(
13662                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13663
13664        synchronized (this) {
13665            // Iterate across all processes
13666            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13667                ProcessRecord app = mLruProcesses.get(i);
13668                if ((!allUsers && app.userId != userId)
13669                        || (!allUids && app.uid != callingUid)) {
13670                    continue;
13671                }
13672                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13673                    // Generate process state info for running application
13674                    ActivityManager.RunningAppProcessInfo currApp =
13675                        new ActivityManager.RunningAppProcessInfo(app.processName,
13676                                app.pid, app.getPackageList());
13677                    fillInProcMemInfo(app, currApp);
13678                    if (app.adjSource instanceof ProcessRecord) {
13679                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13680                        currApp.importanceReasonImportance =
13681                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13682                                        app.adjSourceProcState);
13683                    } else if (app.adjSource instanceof ActivityRecord) {
13684                        ActivityRecord r = (ActivityRecord)app.adjSource;
13685                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13686                    }
13687                    if (app.adjTarget instanceof ComponentName) {
13688                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13689                    }
13690                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13691                    //        + " lru=" + currApp.lru);
13692                    if (runList == null) {
13693                        runList = new ArrayList<>();
13694                    }
13695                    runList.add(currApp);
13696                }
13697            }
13698        }
13699        return runList;
13700    }
13701
13702    @Override
13703    public List<ApplicationInfo> getRunningExternalApplications() {
13704        enforceNotIsolatedCaller("getRunningExternalApplications");
13705        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13706        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13707        if (runningApps != null && runningApps.size() > 0) {
13708            Set<String> extList = new HashSet<String>();
13709            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13710                if (app.pkgList != null) {
13711                    for (String pkg : app.pkgList) {
13712                        extList.add(pkg);
13713                    }
13714                }
13715            }
13716            IPackageManager pm = AppGlobals.getPackageManager();
13717            for (String pkg : extList) {
13718                try {
13719                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13720                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13721                        retList.add(info);
13722                    }
13723                } catch (RemoteException e) {
13724                }
13725            }
13726        }
13727        return retList;
13728    }
13729
13730    @Override
13731    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13732        enforceNotIsolatedCaller("getMyMemoryState");
13733        synchronized (this) {
13734            ProcessRecord proc;
13735            synchronized (mPidsSelfLocked) {
13736                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13737            }
13738            fillInProcMemInfo(proc, outInfo);
13739        }
13740    }
13741
13742    @Override
13743    public int getMemoryTrimLevel() {
13744        enforceNotIsolatedCaller("getMyMemoryState");
13745        synchronized (this) {
13746            return mLastMemoryLevel;
13747        }
13748    }
13749
13750    @Override
13751    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13752            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13753        (new ActivityManagerShellCommand(this, false)).exec(
13754                this, in, out, err, args, resultReceiver);
13755    }
13756
13757    @Override
13758    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13759        if (checkCallingPermission(android.Manifest.permission.DUMP)
13760                != PackageManager.PERMISSION_GRANTED) {
13761            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13762                    + Binder.getCallingPid()
13763                    + ", uid=" + Binder.getCallingUid()
13764                    + " without permission "
13765                    + android.Manifest.permission.DUMP);
13766            return;
13767        }
13768
13769        boolean dumpAll = false;
13770        boolean dumpClient = false;
13771        String dumpPackage = null;
13772
13773        int opti = 0;
13774        while (opti < args.length) {
13775            String opt = args[opti];
13776            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13777                break;
13778            }
13779            opti++;
13780            if ("-a".equals(opt)) {
13781                dumpAll = true;
13782            } else if ("-c".equals(opt)) {
13783                dumpClient = true;
13784            } else if ("-p".equals(opt)) {
13785                if (opti < args.length) {
13786                    dumpPackage = args[opti];
13787                    opti++;
13788                } else {
13789                    pw.println("Error: -p option requires package argument");
13790                    return;
13791                }
13792                dumpClient = true;
13793            } else if ("-h".equals(opt)) {
13794                ActivityManagerShellCommand.dumpHelp(pw, true);
13795                return;
13796            } else {
13797                pw.println("Unknown argument: " + opt + "; use -h for help");
13798            }
13799        }
13800
13801        long origId = Binder.clearCallingIdentity();
13802        boolean more = false;
13803        // Is the caller requesting to dump a particular piece of data?
13804        if (opti < args.length) {
13805            String cmd = args[opti];
13806            opti++;
13807            if ("activities".equals(cmd) || "a".equals(cmd)) {
13808                synchronized (this) {
13809                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13810                }
13811            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13812                synchronized (this) {
13813                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13814                }
13815            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13816                String[] newArgs;
13817                String name;
13818                if (opti >= args.length) {
13819                    name = null;
13820                    newArgs = EMPTY_STRING_ARRAY;
13821                } else {
13822                    dumpPackage = args[opti];
13823                    opti++;
13824                    newArgs = new String[args.length - opti];
13825                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13826                            args.length - opti);
13827                }
13828                synchronized (this) {
13829                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13830                }
13831            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13832                String[] newArgs;
13833                String name;
13834                if (opti >= args.length) {
13835                    name = null;
13836                    newArgs = EMPTY_STRING_ARRAY;
13837                } else {
13838                    dumpPackage = args[opti];
13839                    opti++;
13840                    newArgs = new String[args.length - opti];
13841                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13842                            args.length - opti);
13843                }
13844                synchronized (this) {
13845                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13846                }
13847            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13848                String[] newArgs;
13849                String name;
13850                if (opti >= args.length) {
13851                    name = null;
13852                    newArgs = EMPTY_STRING_ARRAY;
13853                } else {
13854                    dumpPackage = args[opti];
13855                    opti++;
13856                    newArgs = new String[args.length - opti];
13857                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13858                            args.length - opti);
13859                }
13860                synchronized (this) {
13861                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13862                }
13863            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13864                synchronized (this) {
13865                    dumpOomLocked(fd, pw, args, opti, true);
13866                }
13867            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13868                synchronized (this) {
13869                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13870                }
13871            } else if ("provider".equals(cmd)) {
13872                String[] newArgs;
13873                String name;
13874                if (opti >= args.length) {
13875                    name = null;
13876                    newArgs = EMPTY_STRING_ARRAY;
13877                } else {
13878                    name = args[opti];
13879                    opti++;
13880                    newArgs = new String[args.length - opti];
13881                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13882                }
13883                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13884                    pw.println("No providers match: " + name);
13885                    pw.println("Use -h for help.");
13886                }
13887            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13888                synchronized (this) {
13889                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13890                }
13891            } else if ("service".equals(cmd)) {
13892                String[] newArgs;
13893                String name;
13894                if (opti >= args.length) {
13895                    name = null;
13896                    newArgs = EMPTY_STRING_ARRAY;
13897                } else {
13898                    name = args[opti];
13899                    opti++;
13900                    newArgs = new String[args.length - opti];
13901                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13902                            args.length - opti);
13903                }
13904                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13905                    pw.println("No services match: " + name);
13906                    pw.println("Use -h for help.");
13907                }
13908            } else if ("package".equals(cmd)) {
13909                String[] newArgs;
13910                if (opti >= args.length) {
13911                    pw.println("package: no package name specified");
13912                    pw.println("Use -h for help.");
13913                } else {
13914                    dumpPackage = args[opti];
13915                    opti++;
13916                    newArgs = new String[args.length - opti];
13917                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13918                            args.length - opti);
13919                    args = newArgs;
13920                    opti = 0;
13921                    more = true;
13922                }
13923            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13924                synchronized (this) {
13925                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13926                }
13927            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13928                if (dumpClient) {
13929                    ActiveServices.ServiceDumper dumper;
13930                    synchronized (this) {
13931                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13932                                dumpPackage);
13933                    }
13934                    dumper.dumpWithClient();
13935                } else {
13936                    synchronized (this) {
13937                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13938                                dumpPackage).dumpLocked();
13939                    }
13940                }
13941            } else if ("locks".equals(cmd)) {
13942                LockGuard.dump(fd, pw, args);
13943            } else {
13944                // Dumping a single activity?
13945                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13946                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13947                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13948                    if (res < 0) {
13949                        pw.println("Bad activity command, or no activities match: " + cmd);
13950                        pw.println("Use -h for help.");
13951                    }
13952                }
13953            }
13954            if (!more) {
13955                Binder.restoreCallingIdentity(origId);
13956                return;
13957            }
13958        }
13959
13960        // No piece of data specified, dump everything.
13961        if (dumpClient) {
13962            ActiveServices.ServiceDumper sdumper;
13963            synchronized (this) {
13964                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13965                pw.println();
13966                if (dumpAll) {
13967                    pw.println("-------------------------------------------------------------------------------");
13968                }
13969                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13970                pw.println();
13971                if (dumpAll) {
13972                    pw.println("-------------------------------------------------------------------------------");
13973                }
13974                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13975                pw.println();
13976                if (dumpAll) {
13977                    pw.println("-------------------------------------------------------------------------------");
13978                }
13979                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13980                pw.println();
13981                if (dumpAll) {
13982                    pw.println("-------------------------------------------------------------------------------");
13983                }
13984                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13985                        dumpPackage);
13986            }
13987            sdumper.dumpWithClient();
13988            pw.println();
13989            synchronized (this) {
13990                if (dumpAll) {
13991                    pw.println("-------------------------------------------------------------------------------");
13992                }
13993                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13994                pw.println();
13995                if (dumpAll) {
13996                    pw.println("-------------------------------------------------------------------------------");
13997                }
13998                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13999                if (mAssociations.size() > 0) {
14000                    pw.println();
14001                    if (dumpAll) {
14002                        pw.println("-------------------------------------------------------------------------------");
14003                    }
14004                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14005                }
14006                pw.println();
14007                if (dumpAll) {
14008                    pw.println("-------------------------------------------------------------------------------");
14009                }
14010                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14011            }
14012
14013        } else {
14014            synchronized (this) {
14015                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14016                pw.println();
14017                if (dumpAll) {
14018                    pw.println("-------------------------------------------------------------------------------");
14019                }
14020                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14021                pw.println();
14022                if (dumpAll) {
14023                    pw.println("-------------------------------------------------------------------------------");
14024                }
14025                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14026                pw.println();
14027                if (dumpAll) {
14028                    pw.println("-------------------------------------------------------------------------------");
14029                }
14030                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14031                pw.println();
14032                if (dumpAll) {
14033                    pw.println("-------------------------------------------------------------------------------");
14034                }
14035                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14036                        .dumpLocked();
14037                pw.println();
14038                if (dumpAll) {
14039                    pw.println("-------------------------------------------------------------------------------");
14040                }
14041                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14042                pw.println();
14043                if (dumpAll) {
14044                    pw.println("-------------------------------------------------------------------------------");
14045                }
14046                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14047                if (mAssociations.size() > 0) {
14048                    pw.println();
14049                    if (dumpAll) {
14050                        pw.println("-------------------------------------------------------------------------------");
14051                    }
14052                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14053                }
14054                pw.println();
14055                if (dumpAll) {
14056                    pw.println("-------------------------------------------------------------------------------");
14057                }
14058                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14059            }
14060        }
14061        Binder.restoreCallingIdentity(origId);
14062    }
14063
14064    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14065            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14066        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14067
14068        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14069                dumpPackage);
14070        boolean needSep = printedAnything;
14071
14072        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14073                dumpPackage, needSep, "  mFocusedActivity: ");
14074        if (printed) {
14075            printedAnything = true;
14076            needSep = false;
14077        }
14078
14079        if (dumpPackage == null) {
14080            if (needSep) {
14081                pw.println();
14082            }
14083            needSep = true;
14084            printedAnything = true;
14085            mStackSupervisor.dump(pw, "  ");
14086        }
14087
14088        if (!printedAnything) {
14089            pw.println("  (nothing)");
14090        }
14091    }
14092
14093    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14094            int opti, boolean dumpAll, String dumpPackage) {
14095        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14096
14097        boolean printedAnything = false;
14098
14099        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14100            boolean printedHeader = false;
14101
14102            final int N = mRecentTasks.size();
14103            for (int i=0; i<N; i++) {
14104                TaskRecord tr = mRecentTasks.get(i);
14105                if (dumpPackage != null) {
14106                    if (tr.realActivity == null ||
14107                            !dumpPackage.equals(tr.realActivity)) {
14108                        continue;
14109                    }
14110                }
14111                if (!printedHeader) {
14112                    pw.println("  Recent tasks:");
14113                    printedHeader = true;
14114                    printedAnything = true;
14115                }
14116                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14117                        pw.println(tr);
14118                if (dumpAll) {
14119                    mRecentTasks.get(i).dump(pw, "    ");
14120                }
14121            }
14122        }
14123
14124        if (!printedAnything) {
14125            pw.println("  (nothing)");
14126        }
14127    }
14128
14129    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14130            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14131        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14132
14133        int dumpUid = 0;
14134        if (dumpPackage != null) {
14135            IPackageManager pm = AppGlobals.getPackageManager();
14136            try {
14137                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14138            } catch (RemoteException e) {
14139            }
14140        }
14141
14142        boolean printedAnything = false;
14143
14144        final long now = SystemClock.uptimeMillis();
14145
14146        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14147            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14148                    = mAssociations.valueAt(i1);
14149            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14150                SparseArray<ArrayMap<String, Association>> sourceUids
14151                        = targetComponents.valueAt(i2);
14152                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14153                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14154                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14155                        Association ass = sourceProcesses.valueAt(i4);
14156                        if (dumpPackage != null) {
14157                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14158                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14159                                continue;
14160                            }
14161                        }
14162                        printedAnything = true;
14163                        pw.print("  ");
14164                        pw.print(ass.mTargetProcess);
14165                        pw.print("/");
14166                        UserHandle.formatUid(pw, ass.mTargetUid);
14167                        pw.print(" <- ");
14168                        pw.print(ass.mSourceProcess);
14169                        pw.print("/");
14170                        UserHandle.formatUid(pw, ass.mSourceUid);
14171                        pw.println();
14172                        pw.print("    via ");
14173                        pw.print(ass.mTargetComponent.flattenToShortString());
14174                        pw.println();
14175                        pw.print("    ");
14176                        long dur = ass.mTime;
14177                        if (ass.mNesting > 0) {
14178                            dur += now - ass.mStartTime;
14179                        }
14180                        TimeUtils.formatDuration(dur, pw);
14181                        pw.print(" (");
14182                        pw.print(ass.mCount);
14183                        pw.print(" times)");
14184                        pw.print("  ");
14185                        for (int i=0; i<ass.mStateTimes.length; i++) {
14186                            long amt = ass.mStateTimes[i];
14187                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14188                                amt += now - ass.mLastStateUptime;
14189                            }
14190                            if (amt != 0) {
14191                                pw.print(" ");
14192                                pw.print(ProcessList.makeProcStateString(
14193                                            i + ActivityManager.MIN_PROCESS_STATE));
14194                                pw.print("=");
14195                                TimeUtils.formatDuration(amt, pw);
14196                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14197                                    pw.print("*");
14198                                }
14199                            }
14200                        }
14201                        pw.println();
14202                        if (ass.mNesting > 0) {
14203                            pw.print("    Currently active: ");
14204                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14205                            pw.println();
14206                        }
14207                    }
14208                }
14209            }
14210
14211        }
14212
14213        if (!printedAnything) {
14214            pw.println("  (nothing)");
14215        }
14216    }
14217
14218    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14219            String header, boolean needSep) {
14220        boolean printed = false;
14221        int whichAppId = -1;
14222        if (dumpPackage != null) {
14223            try {
14224                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14225                        dumpPackage, 0);
14226                whichAppId = UserHandle.getAppId(info.uid);
14227            } catch (NameNotFoundException e) {
14228                e.printStackTrace();
14229            }
14230        }
14231        for (int i=0; i<uids.size(); i++) {
14232            UidRecord uidRec = uids.valueAt(i);
14233            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14234                continue;
14235            }
14236            if (!printed) {
14237                printed = true;
14238                if (needSep) {
14239                    pw.println();
14240                }
14241                pw.print("  ");
14242                pw.println(header);
14243                needSep = true;
14244            }
14245            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14246            pw.print(": "); pw.println(uidRec);
14247        }
14248        return printed;
14249    }
14250
14251    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14252            int opti, boolean dumpAll, String dumpPackage) {
14253        boolean needSep = false;
14254        boolean printedAnything = false;
14255        int numPers = 0;
14256
14257        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14258
14259        if (dumpAll) {
14260            final int NP = mProcessNames.getMap().size();
14261            for (int ip=0; ip<NP; ip++) {
14262                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14263                final int NA = procs.size();
14264                for (int ia=0; ia<NA; ia++) {
14265                    ProcessRecord r = procs.valueAt(ia);
14266                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14267                        continue;
14268                    }
14269                    if (!needSep) {
14270                        pw.println("  All known processes:");
14271                        needSep = true;
14272                        printedAnything = true;
14273                    }
14274                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14275                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14276                        pw.print(" "); pw.println(r);
14277                    r.dump(pw, "    ");
14278                    if (r.persistent) {
14279                        numPers++;
14280                    }
14281                }
14282            }
14283        }
14284
14285        if (mIsolatedProcesses.size() > 0) {
14286            boolean printed = false;
14287            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14288                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14289                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14290                    continue;
14291                }
14292                if (!printed) {
14293                    if (needSep) {
14294                        pw.println();
14295                    }
14296                    pw.println("  Isolated process list (sorted by uid):");
14297                    printedAnything = true;
14298                    printed = true;
14299                    needSep = true;
14300                }
14301                pw.println(String.format("%sIsolated #%2d: %s",
14302                        "    ", i, r.toString()));
14303            }
14304        }
14305
14306        if (mActiveUids.size() > 0) {
14307            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14308                printedAnything = needSep = true;
14309            }
14310        }
14311        if (mValidateUids.size() > 0) {
14312            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14313                printedAnything = needSep = true;
14314            }
14315        }
14316
14317        if (mLruProcesses.size() > 0) {
14318            if (needSep) {
14319                pw.println();
14320            }
14321            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14322                    pw.print(" total, non-act at ");
14323                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14324                    pw.print(", non-svc at ");
14325                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14326                    pw.println("):");
14327            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14328            needSep = true;
14329            printedAnything = true;
14330        }
14331
14332        if (dumpAll || dumpPackage != null) {
14333            synchronized (mPidsSelfLocked) {
14334                boolean printed = false;
14335                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14336                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14337                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14338                        continue;
14339                    }
14340                    if (!printed) {
14341                        if (needSep) pw.println();
14342                        needSep = true;
14343                        pw.println("  PID mappings:");
14344                        printed = true;
14345                        printedAnything = true;
14346                    }
14347                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14348                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14349                }
14350            }
14351        }
14352
14353        if (mForegroundProcesses.size() > 0) {
14354            synchronized (mPidsSelfLocked) {
14355                boolean printed = false;
14356                for (int i=0; i<mForegroundProcesses.size(); i++) {
14357                    ProcessRecord r = mPidsSelfLocked.get(
14358                            mForegroundProcesses.valueAt(i).pid);
14359                    if (dumpPackage != null && (r == null
14360                            || !r.pkgList.containsKey(dumpPackage))) {
14361                        continue;
14362                    }
14363                    if (!printed) {
14364                        if (needSep) pw.println();
14365                        needSep = true;
14366                        pw.println("  Foreground Processes:");
14367                        printed = true;
14368                        printedAnything = true;
14369                    }
14370                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14371                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14372                }
14373            }
14374        }
14375
14376        if (mPersistentStartingProcesses.size() > 0) {
14377            if (needSep) pw.println();
14378            needSep = true;
14379            printedAnything = true;
14380            pw.println("  Persisent processes that are starting:");
14381            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14382                    "Starting Norm", "Restarting PERS", dumpPackage);
14383        }
14384
14385        if (mRemovedProcesses.size() > 0) {
14386            if (needSep) pw.println();
14387            needSep = true;
14388            printedAnything = true;
14389            pw.println("  Processes that are being removed:");
14390            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14391                    "Removed Norm", "Removed PERS", dumpPackage);
14392        }
14393
14394        if (mProcessesOnHold.size() > 0) {
14395            if (needSep) pw.println();
14396            needSep = true;
14397            printedAnything = true;
14398            pw.println("  Processes that are on old until the system is ready:");
14399            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14400                    "OnHold Norm", "OnHold PERS", dumpPackage);
14401        }
14402
14403        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14404
14405        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14406        if (needSep) {
14407            printedAnything = true;
14408        }
14409
14410        if (dumpPackage == null) {
14411            pw.println();
14412            needSep = false;
14413            mUserController.dump(pw, dumpAll);
14414        }
14415        if (mHomeProcess != null && (dumpPackage == null
14416                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14417            if (needSep) {
14418                pw.println();
14419                needSep = false;
14420            }
14421            pw.println("  mHomeProcess: " + mHomeProcess);
14422        }
14423        if (mPreviousProcess != null && (dumpPackage == null
14424                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14425            if (needSep) {
14426                pw.println();
14427                needSep = false;
14428            }
14429            pw.println("  mPreviousProcess: " + mPreviousProcess);
14430        }
14431        if (dumpAll) {
14432            StringBuilder sb = new StringBuilder(128);
14433            sb.append("  mPreviousProcessVisibleTime: ");
14434            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14435            pw.println(sb);
14436        }
14437        if (mHeavyWeightProcess != null && (dumpPackage == null
14438                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14439            if (needSep) {
14440                pw.println();
14441                needSep = false;
14442            }
14443            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14444        }
14445        if (dumpPackage == null) {
14446            pw.println("  mConfiguration: " + mConfiguration);
14447        }
14448        if (dumpAll) {
14449            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14450            if (mCompatModePackages.getPackages().size() > 0) {
14451                boolean printed = false;
14452                for (Map.Entry<String, Integer> entry
14453                        : mCompatModePackages.getPackages().entrySet()) {
14454                    String pkg = entry.getKey();
14455                    int mode = entry.getValue();
14456                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14457                        continue;
14458                    }
14459                    if (!printed) {
14460                        pw.println("  mScreenCompatPackages:");
14461                        printed = true;
14462                    }
14463                    pw.print("    "); pw.print(pkg); pw.print(": ");
14464                            pw.print(mode); pw.println();
14465                }
14466            }
14467        }
14468        if (dumpPackage == null) {
14469            pw.println("  mWakefulness="
14470                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14471            pw.println("  mSleepTokens=" + mSleepTokens);
14472            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14473                    + lockScreenShownToString());
14474            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14475            if (mRunningVoice != null) {
14476                pw.println("  mRunningVoice=" + mRunningVoice);
14477                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14478            }
14479        }
14480        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14481                || mOrigWaitForDebugger) {
14482            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14483                    || dumpPackage.equals(mOrigDebugApp)) {
14484                if (needSep) {
14485                    pw.println();
14486                    needSep = false;
14487                }
14488                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14489                        + " mDebugTransient=" + mDebugTransient
14490                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14491            }
14492        }
14493        if (mCurAppTimeTracker != null) {
14494            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14495        }
14496        if (mMemWatchProcesses.getMap().size() > 0) {
14497            pw.println("  Mem watch processes:");
14498            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14499                    = mMemWatchProcesses.getMap();
14500            for (int i=0; i<procs.size(); i++) {
14501                final String proc = procs.keyAt(i);
14502                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14503                for (int j=0; j<uids.size(); j++) {
14504                    if (needSep) {
14505                        pw.println();
14506                        needSep = false;
14507                    }
14508                    StringBuilder sb = new StringBuilder();
14509                    sb.append("    ").append(proc).append('/');
14510                    UserHandle.formatUid(sb, uids.keyAt(j));
14511                    Pair<Long, String> val = uids.valueAt(j);
14512                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14513                    if (val.second != null) {
14514                        sb.append(", report to ").append(val.second);
14515                    }
14516                    pw.println(sb.toString());
14517                }
14518            }
14519            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14520            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14521            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14522                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14523        }
14524        if (mTrackAllocationApp != null) {
14525            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14526                if (needSep) {
14527                    pw.println();
14528                    needSep = false;
14529                }
14530                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14531            }
14532        }
14533        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14534                || mProfileFd != null) {
14535            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14536                if (needSep) {
14537                    pw.println();
14538                    needSep = false;
14539                }
14540                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14541                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14542                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14543                        + mAutoStopProfiler);
14544                pw.println("  mProfileType=" + mProfileType);
14545            }
14546        }
14547        if (mNativeDebuggingApp != null) {
14548            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14549                if (needSep) {
14550                    pw.println();
14551                    needSep = false;
14552                }
14553                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14554            }
14555        }
14556        if (dumpPackage == null) {
14557            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14558                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14559                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14560            }
14561            if (mController != null) {
14562                pw.println("  mController=" + mController
14563                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14564            }
14565            if (dumpAll) {
14566                pw.println("  Total persistent processes: " + numPers);
14567                pw.println("  mProcessesReady=" + mProcessesReady
14568                        + " mSystemReady=" + mSystemReady
14569                        + " mBooted=" + mBooted
14570                        + " mFactoryTest=" + mFactoryTest);
14571                pw.println("  mBooting=" + mBooting
14572                        + " mCallFinishBooting=" + mCallFinishBooting
14573                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14574                pw.print("  mLastPowerCheckRealtime=");
14575                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14576                        pw.println("");
14577                pw.print("  mLastPowerCheckUptime=");
14578                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14579                        pw.println("");
14580                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14581                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14582                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14583                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14584                        + " (" + mLruProcesses.size() + " total)"
14585                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14586                        + " mNumServiceProcs=" + mNumServiceProcs
14587                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14588                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14589                        + " mLastMemoryLevel=" + mLastMemoryLevel
14590                        + " mLastNumProcesses=" + mLastNumProcesses);
14591                long now = SystemClock.uptimeMillis();
14592                pw.print("  mLastIdleTime=");
14593                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14594                        pw.print(" mLowRamSinceLastIdle=");
14595                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14596                        pw.println();
14597            }
14598        }
14599
14600        if (!printedAnything) {
14601            pw.println("  (nothing)");
14602        }
14603    }
14604
14605    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14606            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14607        if (mProcessesToGc.size() > 0) {
14608            boolean printed = false;
14609            long now = SystemClock.uptimeMillis();
14610            for (int i=0; i<mProcessesToGc.size(); i++) {
14611                ProcessRecord proc = mProcessesToGc.get(i);
14612                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14613                    continue;
14614                }
14615                if (!printed) {
14616                    if (needSep) pw.println();
14617                    needSep = true;
14618                    pw.println("  Processes that are waiting to GC:");
14619                    printed = true;
14620                }
14621                pw.print("    Process "); pw.println(proc);
14622                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14623                        pw.print(", last gced=");
14624                        pw.print(now-proc.lastRequestedGc);
14625                        pw.print(" ms ago, last lowMem=");
14626                        pw.print(now-proc.lastLowMemory);
14627                        pw.println(" ms ago");
14628
14629            }
14630        }
14631        return needSep;
14632    }
14633
14634    void printOomLevel(PrintWriter pw, String name, int adj) {
14635        pw.print("    ");
14636        if (adj >= 0) {
14637            pw.print(' ');
14638            if (adj < 10) pw.print(' ');
14639        } else {
14640            if (adj > -10) pw.print(' ');
14641        }
14642        pw.print(adj);
14643        pw.print(": ");
14644        pw.print(name);
14645        pw.print(" (");
14646        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14647        pw.println(")");
14648    }
14649
14650    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14651            int opti, boolean dumpAll) {
14652        boolean needSep = false;
14653
14654        if (mLruProcesses.size() > 0) {
14655            if (needSep) pw.println();
14656            needSep = true;
14657            pw.println("  OOM levels:");
14658            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14659            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14660            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14661            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14662            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14663            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14664            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14665            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14666            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14667            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14668            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14669            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14670            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14671            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14672
14673            if (needSep) pw.println();
14674            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14675                    pw.print(" total, non-act at ");
14676                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14677                    pw.print(", non-svc at ");
14678                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14679                    pw.println("):");
14680            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14681            needSep = true;
14682        }
14683
14684        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14685
14686        pw.println();
14687        pw.println("  mHomeProcess: " + mHomeProcess);
14688        pw.println("  mPreviousProcess: " + mPreviousProcess);
14689        if (mHeavyWeightProcess != null) {
14690            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14691        }
14692
14693        return true;
14694    }
14695
14696    /**
14697     * There are three ways to call this:
14698     *  - no provider specified: dump all the providers
14699     *  - a flattened component name that matched an existing provider was specified as the
14700     *    first arg: dump that one provider
14701     *  - the first arg isn't the flattened component name of an existing provider:
14702     *    dump all providers whose component contains the first arg as a substring
14703     */
14704    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14705            int opti, boolean dumpAll) {
14706        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14707    }
14708
14709    static class ItemMatcher {
14710        ArrayList<ComponentName> components;
14711        ArrayList<String> strings;
14712        ArrayList<Integer> objects;
14713        boolean all;
14714
14715        ItemMatcher() {
14716            all = true;
14717        }
14718
14719        void build(String name) {
14720            ComponentName componentName = ComponentName.unflattenFromString(name);
14721            if (componentName != null) {
14722                if (components == null) {
14723                    components = new ArrayList<ComponentName>();
14724                }
14725                components.add(componentName);
14726                all = false;
14727            } else {
14728                int objectId = 0;
14729                // Not a '/' separated full component name; maybe an object ID?
14730                try {
14731                    objectId = Integer.parseInt(name, 16);
14732                    if (objects == null) {
14733                        objects = new ArrayList<Integer>();
14734                    }
14735                    objects.add(objectId);
14736                    all = false;
14737                } catch (RuntimeException e) {
14738                    // Not an integer; just do string match.
14739                    if (strings == null) {
14740                        strings = new ArrayList<String>();
14741                    }
14742                    strings.add(name);
14743                    all = false;
14744                }
14745            }
14746        }
14747
14748        int build(String[] args, int opti) {
14749            for (; opti<args.length; opti++) {
14750                String name = args[opti];
14751                if ("--".equals(name)) {
14752                    return opti+1;
14753                }
14754                build(name);
14755            }
14756            return opti;
14757        }
14758
14759        boolean match(Object object, ComponentName comp) {
14760            if (all) {
14761                return true;
14762            }
14763            if (components != null) {
14764                for (int i=0; i<components.size(); i++) {
14765                    if (components.get(i).equals(comp)) {
14766                        return true;
14767                    }
14768                }
14769            }
14770            if (objects != null) {
14771                for (int i=0; i<objects.size(); i++) {
14772                    if (System.identityHashCode(object) == objects.get(i)) {
14773                        return true;
14774                    }
14775                }
14776            }
14777            if (strings != null) {
14778                String flat = comp.flattenToString();
14779                for (int i=0; i<strings.size(); i++) {
14780                    if (flat.contains(strings.get(i))) {
14781                        return true;
14782                    }
14783                }
14784            }
14785            return false;
14786        }
14787    }
14788
14789    /**
14790     * There are three things that cmd can be:
14791     *  - a flattened component name that matches an existing activity
14792     *  - the cmd arg isn't the flattened component name of an existing activity:
14793     *    dump all activity whose component contains the cmd as a substring
14794     *  - A hex number of the ActivityRecord object instance.
14795     */
14796    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14797            int opti, boolean dumpAll) {
14798        ArrayList<ActivityRecord> activities;
14799
14800        synchronized (this) {
14801            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14802        }
14803
14804        if (activities.size() <= 0) {
14805            return false;
14806        }
14807
14808        String[] newArgs = new String[args.length - opti];
14809        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14810
14811        TaskRecord lastTask = null;
14812        boolean needSep = false;
14813        for (int i=activities.size()-1; i>=0; i--) {
14814            ActivityRecord r = activities.get(i);
14815            if (needSep) {
14816                pw.println();
14817            }
14818            needSep = true;
14819            synchronized (this) {
14820                if (lastTask != r.task) {
14821                    lastTask = r.task;
14822                    pw.print("TASK "); pw.print(lastTask.affinity);
14823                            pw.print(" id="); pw.println(lastTask.taskId);
14824                    if (dumpAll) {
14825                        lastTask.dump(pw, "  ");
14826                    }
14827                }
14828            }
14829            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14830        }
14831        return true;
14832    }
14833
14834    /**
14835     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14836     * there is a thread associated with the activity.
14837     */
14838    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14839            final ActivityRecord r, String[] args, boolean dumpAll) {
14840        String innerPrefix = prefix + "  ";
14841        synchronized (this) {
14842            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14843                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14844                    pw.print(" pid=");
14845                    if (r.app != null) pw.println(r.app.pid);
14846                    else pw.println("(not running)");
14847            if (dumpAll) {
14848                r.dump(pw, innerPrefix);
14849            }
14850        }
14851        if (r.app != null && r.app.thread != null) {
14852            // flush anything that is already in the PrintWriter since the thread is going
14853            // to write to the file descriptor directly
14854            pw.flush();
14855            try {
14856                TransferPipe tp = new TransferPipe();
14857                try {
14858                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14859                            r.appToken, innerPrefix, args);
14860                    tp.go(fd);
14861                } finally {
14862                    tp.kill();
14863                }
14864            } catch (IOException e) {
14865                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14866            } catch (RemoteException e) {
14867                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14868            }
14869        }
14870    }
14871
14872    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14873            int opti, boolean dumpAll, String dumpPackage) {
14874        boolean needSep = false;
14875        boolean onlyHistory = false;
14876        boolean printedAnything = false;
14877
14878        if ("history".equals(dumpPackage)) {
14879            if (opti < args.length && "-s".equals(args[opti])) {
14880                dumpAll = false;
14881            }
14882            onlyHistory = true;
14883            dumpPackage = null;
14884        }
14885
14886        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14887        if (!onlyHistory && dumpAll) {
14888            if (mRegisteredReceivers.size() > 0) {
14889                boolean printed = false;
14890                Iterator it = mRegisteredReceivers.values().iterator();
14891                while (it.hasNext()) {
14892                    ReceiverList r = (ReceiverList)it.next();
14893                    if (dumpPackage != null && (r.app == null ||
14894                            !dumpPackage.equals(r.app.info.packageName))) {
14895                        continue;
14896                    }
14897                    if (!printed) {
14898                        pw.println("  Registered Receivers:");
14899                        needSep = true;
14900                        printed = true;
14901                        printedAnything = true;
14902                    }
14903                    pw.print("  * "); pw.println(r);
14904                    r.dump(pw, "    ");
14905                }
14906            }
14907
14908            if (mReceiverResolver.dump(pw, needSep ?
14909                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14910                    "    ", dumpPackage, false, false)) {
14911                needSep = true;
14912                printedAnything = true;
14913            }
14914        }
14915
14916        for (BroadcastQueue q : mBroadcastQueues) {
14917            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14918            printedAnything |= needSep;
14919        }
14920
14921        needSep = true;
14922
14923        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14924            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14925                if (needSep) {
14926                    pw.println();
14927                }
14928                needSep = true;
14929                printedAnything = true;
14930                pw.print("  Sticky broadcasts for user ");
14931                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14932                StringBuilder sb = new StringBuilder(128);
14933                for (Map.Entry<String, ArrayList<Intent>> ent
14934                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14935                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14936                    if (dumpAll) {
14937                        pw.println(":");
14938                        ArrayList<Intent> intents = ent.getValue();
14939                        final int N = intents.size();
14940                        for (int i=0; i<N; i++) {
14941                            sb.setLength(0);
14942                            sb.append("    Intent: ");
14943                            intents.get(i).toShortString(sb, false, true, false, false);
14944                            pw.println(sb.toString());
14945                            Bundle bundle = intents.get(i).getExtras();
14946                            if (bundle != null) {
14947                                pw.print("      ");
14948                                pw.println(bundle.toString());
14949                            }
14950                        }
14951                    } else {
14952                        pw.println("");
14953                    }
14954                }
14955            }
14956        }
14957
14958        if (!onlyHistory && dumpAll) {
14959            pw.println();
14960            for (BroadcastQueue queue : mBroadcastQueues) {
14961                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14962                        + queue.mBroadcastsScheduled);
14963            }
14964            pw.println("  mHandler:");
14965            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14966            needSep = true;
14967            printedAnything = true;
14968        }
14969
14970        if (!printedAnything) {
14971            pw.println("  (nothing)");
14972        }
14973    }
14974
14975    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14976            int opti, boolean dumpAll, String dumpPackage) {
14977        boolean needSep;
14978        boolean printedAnything = false;
14979
14980        ItemMatcher matcher = new ItemMatcher();
14981        matcher.build(args, opti);
14982
14983        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14984
14985        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14986        printedAnything |= needSep;
14987
14988        if (mLaunchingProviders.size() > 0) {
14989            boolean printed = false;
14990            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14991                ContentProviderRecord r = mLaunchingProviders.get(i);
14992                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14993                    continue;
14994                }
14995                if (!printed) {
14996                    if (needSep) pw.println();
14997                    needSep = true;
14998                    pw.println("  Launching content providers:");
14999                    printed = true;
15000                    printedAnything = true;
15001                }
15002                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15003                        pw.println(r);
15004            }
15005        }
15006
15007        if (!printedAnything) {
15008            pw.println("  (nothing)");
15009        }
15010    }
15011
15012    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15013            int opti, boolean dumpAll, String dumpPackage) {
15014        boolean needSep = false;
15015        boolean printedAnything = false;
15016
15017        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15018
15019        if (mGrantedUriPermissions.size() > 0) {
15020            boolean printed = false;
15021            int dumpUid = -2;
15022            if (dumpPackage != null) {
15023                try {
15024                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15025                            MATCH_UNINSTALLED_PACKAGES, 0);
15026                } catch (NameNotFoundException e) {
15027                    dumpUid = -1;
15028                }
15029            }
15030            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15031                int uid = mGrantedUriPermissions.keyAt(i);
15032                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15033                    continue;
15034                }
15035                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15036                if (!printed) {
15037                    if (needSep) pw.println();
15038                    needSep = true;
15039                    pw.println("  Granted Uri Permissions:");
15040                    printed = true;
15041                    printedAnything = true;
15042                }
15043                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15044                for (UriPermission perm : perms.values()) {
15045                    pw.print("    "); pw.println(perm);
15046                    if (dumpAll) {
15047                        perm.dump(pw, "      ");
15048                    }
15049                }
15050            }
15051        }
15052
15053        if (!printedAnything) {
15054            pw.println("  (nothing)");
15055        }
15056    }
15057
15058    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15059            int opti, boolean dumpAll, String dumpPackage) {
15060        boolean printed = false;
15061
15062        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15063
15064        if (mIntentSenderRecords.size() > 0) {
15065            Iterator<WeakReference<PendingIntentRecord>> it
15066                    = mIntentSenderRecords.values().iterator();
15067            while (it.hasNext()) {
15068                WeakReference<PendingIntentRecord> ref = it.next();
15069                PendingIntentRecord rec = ref != null ? ref.get(): null;
15070                if (dumpPackage != null && (rec == null
15071                        || !dumpPackage.equals(rec.key.packageName))) {
15072                    continue;
15073                }
15074                printed = true;
15075                if (rec != null) {
15076                    pw.print("  * "); pw.println(rec);
15077                    if (dumpAll) {
15078                        rec.dump(pw, "    ");
15079                    }
15080                } else {
15081                    pw.print("  * "); pw.println(ref);
15082                }
15083            }
15084        }
15085
15086        if (!printed) {
15087            pw.println("  (nothing)");
15088        }
15089    }
15090
15091    private static final int dumpProcessList(PrintWriter pw,
15092            ActivityManagerService service, List list,
15093            String prefix, String normalLabel, String persistentLabel,
15094            String dumpPackage) {
15095        int numPers = 0;
15096        final int N = list.size()-1;
15097        for (int i=N; i>=0; i--) {
15098            ProcessRecord r = (ProcessRecord)list.get(i);
15099            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15100                continue;
15101            }
15102            pw.println(String.format("%s%s #%2d: %s",
15103                    prefix, (r.persistent ? persistentLabel : normalLabel),
15104                    i, r.toString()));
15105            if (r.persistent) {
15106                numPers++;
15107            }
15108        }
15109        return numPers;
15110    }
15111
15112    private static final boolean dumpProcessOomList(PrintWriter pw,
15113            ActivityManagerService service, List<ProcessRecord> origList,
15114            String prefix, String normalLabel, String persistentLabel,
15115            boolean inclDetails, String dumpPackage) {
15116
15117        ArrayList<Pair<ProcessRecord, Integer>> list
15118                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15119        for (int i=0; i<origList.size(); i++) {
15120            ProcessRecord r = origList.get(i);
15121            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15122                continue;
15123            }
15124            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15125        }
15126
15127        if (list.size() <= 0) {
15128            return false;
15129        }
15130
15131        Comparator<Pair<ProcessRecord, Integer>> comparator
15132                = new Comparator<Pair<ProcessRecord, Integer>>() {
15133            @Override
15134            public int compare(Pair<ProcessRecord, Integer> object1,
15135                    Pair<ProcessRecord, Integer> object2) {
15136                if (object1.first.setAdj != object2.first.setAdj) {
15137                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15138                }
15139                if (object1.first.setProcState != object2.first.setProcState) {
15140                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15141                }
15142                if (object1.second.intValue() != object2.second.intValue()) {
15143                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15144                }
15145                return 0;
15146            }
15147        };
15148
15149        Collections.sort(list, comparator);
15150
15151        final long curRealtime = SystemClock.elapsedRealtime();
15152        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15153        final long curUptime = SystemClock.uptimeMillis();
15154        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15155
15156        for (int i=list.size()-1; i>=0; i--) {
15157            ProcessRecord r = list.get(i).first;
15158            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15159            char schedGroup;
15160            switch (r.setSchedGroup) {
15161                case ProcessList.SCHED_GROUP_BACKGROUND:
15162                    schedGroup = 'B';
15163                    break;
15164                case ProcessList.SCHED_GROUP_DEFAULT:
15165                    schedGroup = 'F';
15166                    break;
15167                case ProcessList.SCHED_GROUP_TOP_APP:
15168                    schedGroup = 'T';
15169                    break;
15170                default:
15171                    schedGroup = '?';
15172                    break;
15173            }
15174            char foreground;
15175            if (r.foregroundActivities) {
15176                foreground = 'A';
15177            } else if (r.foregroundServices) {
15178                foreground = 'S';
15179            } else {
15180                foreground = ' ';
15181            }
15182            String procState = ProcessList.makeProcStateString(r.curProcState);
15183            pw.print(prefix);
15184            pw.print(r.persistent ? persistentLabel : normalLabel);
15185            pw.print(" #");
15186            int num = (origList.size()-1)-list.get(i).second;
15187            if (num < 10) pw.print(' ');
15188            pw.print(num);
15189            pw.print(": ");
15190            pw.print(oomAdj);
15191            pw.print(' ');
15192            pw.print(schedGroup);
15193            pw.print('/');
15194            pw.print(foreground);
15195            pw.print('/');
15196            pw.print(procState);
15197            pw.print(" trm:");
15198            if (r.trimMemoryLevel < 10) pw.print(' ');
15199            pw.print(r.trimMemoryLevel);
15200            pw.print(' ');
15201            pw.print(r.toShortString());
15202            pw.print(" (");
15203            pw.print(r.adjType);
15204            pw.println(')');
15205            if (r.adjSource != null || r.adjTarget != null) {
15206                pw.print(prefix);
15207                pw.print("    ");
15208                if (r.adjTarget instanceof ComponentName) {
15209                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15210                } else if (r.adjTarget != null) {
15211                    pw.print(r.adjTarget.toString());
15212                } else {
15213                    pw.print("{null}");
15214                }
15215                pw.print("<=");
15216                if (r.adjSource instanceof ProcessRecord) {
15217                    pw.print("Proc{");
15218                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15219                    pw.println("}");
15220                } else if (r.adjSource != null) {
15221                    pw.println(r.adjSource.toString());
15222                } else {
15223                    pw.println("{null}");
15224                }
15225            }
15226            if (inclDetails) {
15227                pw.print(prefix);
15228                pw.print("    ");
15229                pw.print("oom: max="); pw.print(r.maxAdj);
15230                pw.print(" curRaw="); pw.print(r.curRawAdj);
15231                pw.print(" setRaw="); pw.print(r.setRawAdj);
15232                pw.print(" cur="); pw.print(r.curAdj);
15233                pw.print(" set="); pw.println(r.setAdj);
15234                pw.print(prefix);
15235                pw.print("    ");
15236                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15237                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15238                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15239                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15240                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15241                pw.println();
15242                pw.print(prefix);
15243                pw.print("    ");
15244                pw.print("cached="); pw.print(r.cached);
15245                pw.print(" empty="); pw.print(r.empty);
15246                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15247
15248                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15249                    if (r.lastWakeTime != 0) {
15250                        long wtime;
15251                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15252                        synchronized (stats) {
15253                            wtime = stats.getProcessWakeTime(r.info.uid,
15254                                    r.pid, curRealtime);
15255                        }
15256                        long timeUsed = wtime - r.lastWakeTime;
15257                        pw.print(prefix);
15258                        pw.print("    ");
15259                        pw.print("keep awake over ");
15260                        TimeUtils.formatDuration(realtimeSince, pw);
15261                        pw.print(" used ");
15262                        TimeUtils.formatDuration(timeUsed, pw);
15263                        pw.print(" (");
15264                        pw.print((timeUsed*100)/realtimeSince);
15265                        pw.println("%)");
15266                    }
15267                    if (r.lastCpuTime != 0) {
15268                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15269                        pw.print(prefix);
15270                        pw.print("    ");
15271                        pw.print("run cpu over ");
15272                        TimeUtils.formatDuration(uptimeSince, pw);
15273                        pw.print(" used ");
15274                        TimeUtils.formatDuration(timeUsed, pw);
15275                        pw.print(" (");
15276                        pw.print((timeUsed*100)/uptimeSince);
15277                        pw.println("%)");
15278                    }
15279                }
15280            }
15281        }
15282        return true;
15283    }
15284
15285    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15286            String[] args) {
15287        ArrayList<ProcessRecord> procs;
15288        synchronized (this) {
15289            if (args != null && args.length > start
15290                    && args[start].charAt(0) != '-') {
15291                procs = new ArrayList<ProcessRecord>();
15292                int pid = -1;
15293                try {
15294                    pid = Integer.parseInt(args[start]);
15295                } catch (NumberFormatException e) {
15296                }
15297                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15298                    ProcessRecord proc = mLruProcesses.get(i);
15299                    if (proc.pid == pid) {
15300                        procs.add(proc);
15301                    } else if (allPkgs && proc.pkgList != null
15302                            && proc.pkgList.containsKey(args[start])) {
15303                        procs.add(proc);
15304                    } else if (proc.processName.equals(args[start])) {
15305                        procs.add(proc);
15306                    }
15307                }
15308                if (procs.size() <= 0) {
15309                    return null;
15310                }
15311            } else {
15312                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15313            }
15314        }
15315        return procs;
15316    }
15317
15318    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15319            PrintWriter pw, String[] args) {
15320        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15321        if (procs == null) {
15322            pw.println("No process found for: " + args[0]);
15323            return;
15324        }
15325
15326        long uptime = SystemClock.uptimeMillis();
15327        long realtime = SystemClock.elapsedRealtime();
15328        pw.println("Applications Graphics Acceleration Info:");
15329        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15330
15331        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15332            ProcessRecord r = procs.get(i);
15333            if (r.thread != null) {
15334                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15335                pw.flush();
15336                try {
15337                    TransferPipe tp = new TransferPipe();
15338                    try {
15339                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15340                        tp.go(fd);
15341                    } finally {
15342                        tp.kill();
15343                    }
15344                } catch (IOException e) {
15345                    pw.println("Failure while dumping the app: " + r);
15346                    pw.flush();
15347                } catch (RemoteException e) {
15348                    pw.println("Got a RemoteException while dumping the app " + r);
15349                    pw.flush();
15350                }
15351            }
15352        }
15353    }
15354
15355    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15356        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15357        if (procs == null) {
15358            pw.println("No process found for: " + args[0]);
15359            return;
15360        }
15361
15362        pw.println("Applications Database Info:");
15363
15364        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15365            ProcessRecord r = procs.get(i);
15366            if (r.thread != null) {
15367                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15368                pw.flush();
15369                try {
15370                    TransferPipe tp = new TransferPipe();
15371                    try {
15372                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15373                        tp.go(fd);
15374                    } finally {
15375                        tp.kill();
15376                    }
15377                } catch (IOException e) {
15378                    pw.println("Failure while dumping the app: " + r);
15379                    pw.flush();
15380                } catch (RemoteException e) {
15381                    pw.println("Got a RemoteException while dumping the app " + r);
15382                    pw.flush();
15383                }
15384            }
15385        }
15386    }
15387
15388    final static class MemItem {
15389        final boolean isProc;
15390        final String label;
15391        final String shortLabel;
15392        final long pss;
15393        final long swapPss;
15394        final int id;
15395        final boolean hasActivities;
15396        ArrayList<MemItem> subitems;
15397
15398        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15399                boolean _hasActivities) {
15400            isProc = true;
15401            label = _label;
15402            shortLabel = _shortLabel;
15403            pss = _pss;
15404            swapPss = _swapPss;
15405            id = _id;
15406            hasActivities = _hasActivities;
15407        }
15408
15409        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15410            isProc = false;
15411            label = _label;
15412            shortLabel = _shortLabel;
15413            pss = _pss;
15414            swapPss = _swapPss;
15415            id = _id;
15416            hasActivities = false;
15417        }
15418    }
15419
15420    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15421            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15422        if (sort && !isCompact) {
15423            Collections.sort(items, new Comparator<MemItem>() {
15424                @Override
15425                public int compare(MemItem lhs, MemItem rhs) {
15426                    if (lhs.pss < rhs.pss) {
15427                        return 1;
15428                    } else if (lhs.pss > rhs.pss) {
15429                        return -1;
15430                    }
15431                    return 0;
15432                }
15433            });
15434        }
15435
15436        for (int i=0; i<items.size(); i++) {
15437            MemItem mi = items.get(i);
15438            if (!isCompact) {
15439                if (dumpSwapPss) {
15440                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15441                            mi.label, stringifyKBSize(mi.swapPss));
15442                } else {
15443                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15444                }
15445            } else if (mi.isProc) {
15446                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15447                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15448                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15449                pw.println(mi.hasActivities ? ",a" : ",e");
15450            } else {
15451                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15452                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15453            }
15454            if (mi.subitems != null) {
15455                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15456                        true, isCompact, dumpSwapPss);
15457            }
15458        }
15459    }
15460
15461    // These are in KB.
15462    static final long[] DUMP_MEM_BUCKETS = new long[] {
15463        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15464        120*1024, 160*1024, 200*1024,
15465        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15466        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15467    };
15468
15469    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15470            boolean stackLike) {
15471        int start = label.lastIndexOf('.');
15472        if (start >= 0) start++;
15473        else start = 0;
15474        int end = label.length();
15475        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15476            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15477                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15478                out.append(bucket);
15479                out.append(stackLike ? "MB." : "MB ");
15480                out.append(label, start, end);
15481                return;
15482            }
15483        }
15484        out.append(memKB/1024);
15485        out.append(stackLike ? "MB." : "MB ");
15486        out.append(label, start, end);
15487    }
15488
15489    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15490            ProcessList.NATIVE_ADJ,
15491            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15492            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15493            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15494            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15495            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15496            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15497    };
15498    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15499            "Native",
15500            "System", "Persistent", "Persistent Service", "Foreground",
15501            "Visible", "Perceptible",
15502            "Heavy Weight", "Backup",
15503            "A Services", "Home",
15504            "Previous", "B Services", "Cached"
15505    };
15506    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15507            "native",
15508            "sys", "pers", "persvc", "fore",
15509            "vis", "percept",
15510            "heavy", "backup",
15511            "servicea", "home",
15512            "prev", "serviceb", "cached"
15513    };
15514
15515    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15516            long realtime, boolean isCheckinRequest, boolean isCompact) {
15517        if (isCompact) {
15518            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15519        }
15520        if (isCheckinRequest || isCompact) {
15521            // short checkin version
15522            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15523        } else {
15524            pw.println("Applications Memory Usage (in Kilobytes):");
15525            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15526        }
15527    }
15528
15529    private static final int KSM_SHARED = 0;
15530    private static final int KSM_SHARING = 1;
15531    private static final int KSM_UNSHARED = 2;
15532    private static final int KSM_VOLATILE = 3;
15533
15534    private final long[] getKsmInfo() {
15535        long[] longOut = new long[4];
15536        final int[] SINGLE_LONG_FORMAT = new int[] {
15537            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15538        };
15539        long[] longTmp = new long[1];
15540        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15541                SINGLE_LONG_FORMAT, null, longTmp, null);
15542        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15543        longTmp[0] = 0;
15544        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15545                SINGLE_LONG_FORMAT, null, longTmp, null);
15546        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15547        longTmp[0] = 0;
15548        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15549                SINGLE_LONG_FORMAT, null, longTmp, null);
15550        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15551        longTmp[0] = 0;
15552        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15553                SINGLE_LONG_FORMAT, null, longTmp, null);
15554        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15555        return longOut;
15556    }
15557
15558    private static String stringifySize(long size, int order) {
15559        Locale locale = Locale.US;
15560        switch (order) {
15561            case 1:
15562                return String.format(locale, "%,13d", size);
15563            case 1024:
15564                return String.format(locale, "%,9dK", size / 1024);
15565            case 1024 * 1024:
15566                return String.format(locale, "%,5dM", size / 1024 / 1024);
15567            case 1024 * 1024 * 1024:
15568                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15569            default:
15570                throw new IllegalArgumentException("Invalid size order");
15571        }
15572    }
15573
15574    private static String stringifyKBSize(long size) {
15575        return stringifySize(size * 1024, 1024);
15576    }
15577
15578    // Update this version number in case you change the 'compact' format
15579    private static final int MEMINFO_COMPACT_VERSION = 1;
15580
15581    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15582            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15583        boolean dumpDetails = false;
15584        boolean dumpFullDetails = false;
15585        boolean dumpDalvik = false;
15586        boolean dumpSummaryOnly = false;
15587        boolean dumpUnreachable = false;
15588        boolean oomOnly = false;
15589        boolean isCompact = false;
15590        boolean localOnly = false;
15591        boolean packages = false;
15592        boolean isCheckinRequest = false;
15593        boolean dumpSwapPss = false;
15594
15595        int opti = 0;
15596        while (opti < args.length) {
15597            String opt = args[opti];
15598            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15599                break;
15600            }
15601            opti++;
15602            if ("-a".equals(opt)) {
15603                dumpDetails = true;
15604                dumpFullDetails = true;
15605                dumpDalvik = true;
15606                dumpSwapPss = true;
15607            } else if ("-d".equals(opt)) {
15608                dumpDalvik = true;
15609            } else if ("-c".equals(opt)) {
15610                isCompact = true;
15611            } else if ("-s".equals(opt)) {
15612                dumpDetails = true;
15613                dumpSummaryOnly = true;
15614            } else if ("-S".equals(opt)) {
15615                dumpSwapPss = true;
15616            } else if ("--unreachable".equals(opt)) {
15617                dumpUnreachable = true;
15618            } else if ("--oom".equals(opt)) {
15619                oomOnly = true;
15620            } else if ("--local".equals(opt)) {
15621                localOnly = true;
15622            } else if ("--package".equals(opt)) {
15623                packages = true;
15624            } else if ("--checkin".equals(opt)) {
15625                isCheckinRequest = true;
15626
15627            } else if ("-h".equals(opt)) {
15628                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15629                pw.println("  -a: include all available information for each process.");
15630                pw.println("  -d: include dalvik details.");
15631                pw.println("  -c: dump in a compact machine-parseable representation.");
15632                pw.println("  -s: dump only summary of application memory usage.");
15633                pw.println("  -S: dump also SwapPss.");
15634                pw.println("  --oom: only show processes organized by oom adj.");
15635                pw.println("  --local: only collect details locally, don't call process.");
15636                pw.println("  --package: interpret process arg as package, dumping all");
15637                pw.println("             processes that have loaded that package.");
15638                pw.println("  --checkin: dump data for a checkin");
15639                pw.println("If [process] is specified it can be the name or ");
15640                pw.println("pid of a specific process to dump.");
15641                return;
15642            } else {
15643                pw.println("Unknown argument: " + opt + "; use -h for help");
15644            }
15645        }
15646
15647        long uptime = SystemClock.uptimeMillis();
15648        long realtime = SystemClock.elapsedRealtime();
15649        final long[] tmpLong = new long[1];
15650
15651        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15652        if (procs == null) {
15653            // No Java processes.  Maybe they want to print a native process.
15654            if (args != null && args.length > opti
15655                    && args[opti].charAt(0) != '-') {
15656                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15657                        = new ArrayList<ProcessCpuTracker.Stats>();
15658                updateCpuStatsNow();
15659                int findPid = -1;
15660                try {
15661                    findPid = Integer.parseInt(args[opti]);
15662                } catch (NumberFormatException e) {
15663                }
15664                synchronized (mProcessCpuTracker) {
15665                    final int N = mProcessCpuTracker.countStats();
15666                    for (int i=0; i<N; i++) {
15667                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15668                        if (st.pid == findPid || (st.baseName != null
15669                                && st.baseName.equals(args[opti]))) {
15670                            nativeProcs.add(st);
15671                        }
15672                    }
15673                }
15674                if (nativeProcs.size() > 0) {
15675                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15676                            isCompact);
15677                    Debug.MemoryInfo mi = null;
15678                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15679                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15680                        final int pid = r.pid;
15681                        if (!isCheckinRequest && dumpDetails) {
15682                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15683                        }
15684                        if (mi == null) {
15685                            mi = new Debug.MemoryInfo();
15686                        }
15687                        if (dumpDetails || (!brief && !oomOnly)) {
15688                            Debug.getMemoryInfo(pid, mi);
15689                        } else {
15690                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15691                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15692                        }
15693                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15694                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15695                        if (isCheckinRequest) {
15696                            pw.println();
15697                        }
15698                    }
15699                    return;
15700                }
15701            }
15702            pw.println("No process found for: " + args[opti]);
15703            return;
15704        }
15705
15706        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15707            dumpDetails = true;
15708        }
15709
15710        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15711
15712        String[] innerArgs = new String[args.length-opti];
15713        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15714
15715        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15716        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15717        long nativePss = 0;
15718        long nativeSwapPss = 0;
15719        long dalvikPss = 0;
15720        long dalvikSwapPss = 0;
15721        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15722                EmptyArray.LONG;
15723        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15724                EmptyArray.LONG;
15725        long otherPss = 0;
15726        long otherSwapPss = 0;
15727        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15728        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15729
15730        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15731        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15732        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15733                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15734
15735        long totalPss = 0;
15736        long totalSwapPss = 0;
15737        long cachedPss = 0;
15738        long cachedSwapPss = 0;
15739        boolean hasSwapPss = false;
15740
15741        Debug.MemoryInfo mi = null;
15742        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15743            final ProcessRecord r = procs.get(i);
15744            final IApplicationThread thread;
15745            final int pid;
15746            final int oomAdj;
15747            final boolean hasActivities;
15748            synchronized (this) {
15749                thread = r.thread;
15750                pid = r.pid;
15751                oomAdj = r.getSetAdjWithServices();
15752                hasActivities = r.activities.size() > 0;
15753            }
15754            if (thread != null) {
15755                if (!isCheckinRequest && dumpDetails) {
15756                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15757                }
15758                if (mi == null) {
15759                    mi = new Debug.MemoryInfo();
15760                }
15761                if (dumpDetails || (!brief && !oomOnly)) {
15762                    Debug.getMemoryInfo(pid, mi);
15763                    hasSwapPss = mi.hasSwappedOutPss;
15764                } else {
15765                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15766                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15767                }
15768                if (dumpDetails) {
15769                    if (localOnly) {
15770                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15771                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15772                        if (isCheckinRequest) {
15773                            pw.println();
15774                        }
15775                    } else {
15776                        try {
15777                            pw.flush();
15778                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15779                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15780                        } catch (RemoteException e) {
15781                            if (!isCheckinRequest) {
15782                                pw.println("Got RemoteException!");
15783                                pw.flush();
15784                            }
15785                        }
15786                    }
15787                }
15788
15789                final long myTotalPss = mi.getTotalPss();
15790                final long myTotalUss = mi.getTotalUss();
15791                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15792
15793                synchronized (this) {
15794                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15795                        // Record this for posterity if the process has been stable.
15796                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15797                    }
15798                }
15799
15800                if (!isCheckinRequest && mi != null) {
15801                    totalPss += myTotalPss;
15802                    totalSwapPss += myTotalSwapPss;
15803                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15804                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15805                            myTotalSwapPss, pid, hasActivities);
15806                    procMems.add(pssItem);
15807                    procMemsMap.put(pid, pssItem);
15808
15809                    nativePss += mi.nativePss;
15810                    nativeSwapPss += mi.nativeSwappedOutPss;
15811                    dalvikPss += mi.dalvikPss;
15812                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15813                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15814                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15815                        dalvikSubitemSwapPss[j] +=
15816                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15817                    }
15818                    otherPss += mi.otherPss;
15819                    otherSwapPss += mi.otherSwappedOutPss;
15820                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15821                        long mem = mi.getOtherPss(j);
15822                        miscPss[j] += mem;
15823                        otherPss -= mem;
15824                        mem = mi.getOtherSwappedOutPss(j);
15825                        miscSwapPss[j] += mem;
15826                        otherSwapPss -= mem;
15827                    }
15828
15829                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15830                        cachedPss += myTotalPss;
15831                        cachedSwapPss += myTotalSwapPss;
15832                    }
15833
15834                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15835                        if (oomIndex == (oomPss.length - 1)
15836                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15837                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15838                            oomPss[oomIndex] += myTotalPss;
15839                            oomSwapPss[oomIndex] += myTotalSwapPss;
15840                            if (oomProcs[oomIndex] == null) {
15841                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15842                            }
15843                            oomProcs[oomIndex].add(pssItem);
15844                            break;
15845                        }
15846                    }
15847                }
15848            }
15849        }
15850
15851        long nativeProcTotalPss = 0;
15852
15853        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15854            // If we are showing aggregations, also look for native processes to
15855            // include so that our aggregations are more accurate.
15856            updateCpuStatsNow();
15857            mi = null;
15858            synchronized (mProcessCpuTracker) {
15859                final int N = mProcessCpuTracker.countStats();
15860                for (int i=0; i<N; i++) {
15861                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15862                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15863                        if (mi == null) {
15864                            mi = new Debug.MemoryInfo();
15865                        }
15866                        if (!brief && !oomOnly) {
15867                            Debug.getMemoryInfo(st.pid, mi);
15868                        } else {
15869                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15870                            mi.nativePrivateDirty = (int)tmpLong[0];
15871                        }
15872
15873                        final long myTotalPss = mi.getTotalPss();
15874                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15875                        totalPss += myTotalPss;
15876                        nativeProcTotalPss += myTotalPss;
15877
15878                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15879                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15880                        procMems.add(pssItem);
15881
15882                        nativePss += mi.nativePss;
15883                        nativeSwapPss += mi.nativeSwappedOutPss;
15884                        dalvikPss += mi.dalvikPss;
15885                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15886                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15887                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15888                            dalvikSubitemSwapPss[j] +=
15889                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15890                        }
15891                        otherPss += mi.otherPss;
15892                        otherSwapPss += mi.otherSwappedOutPss;
15893                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15894                            long mem = mi.getOtherPss(j);
15895                            miscPss[j] += mem;
15896                            otherPss -= mem;
15897                            mem = mi.getOtherSwappedOutPss(j);
15898                            miscSwapPss[j] += mem;
15899                            otherSwapPss -= mem;
15900                        }
15901                        oomPss[0] += myTotalPss;
15902                        oomSwapPss[0] += myTotalSwapPss;
15903                        if (oomProcs[0] == null) {
15904                            oomProcs[0] = new ArrayList<MemItem>();
15905                        }
15906                        oomProcs[0].add(pssItem);
15907                    }
15908                }
15909            }
15910
15911            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15912
15913            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15914            final MemItem dalvikItem =
15915                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15916            if (dalvikSubitemPss.length > 0) {
15917                dalvikItem.subitems = new ArrayList<MemItem>();
15918                for (int j=0; j<dalvikSubitemPss.length; j++) {
15919                    final String name = Debug.MemoryInfo.getOtherLabel(
15920                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15921                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15922                                    dalvikSubitemSwapPss[j], j));
15923                }
15924            }
15925            catMems.add(dalvikItem);
15926            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15927            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15928                String label = Debug.MemoryInfo.getOtherLabel(j);
15929                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15930            }
15931
15932            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15933            for (int j=0; j<oomPss.length; j++) {
15934                if (oomPss[j] != 0) {
15935                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15936                            : DUMP_MEM_OOM_LABEL[j];
15937                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15938                            DUMP_MEM_OOM_ADJ[j]);
15939                    item.subitems = oomProcs[j];
15940                    oomMems.add(item);
15941                }
15942            }
15943
15944            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15945            if (!brief && !oomOnly && !isCompact) {
15946                pw.println();
15947                pw.println("Total PSS by process:");
15948                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15949                pw.println();
15950            }
15951            if (!isCompact) {
15952                pw.println("Total PSS by OOM adjustment:");
15953            }
15954            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15955            if (!brief && !oomOnly) {
15956                PrintWriter out = categoryPw != null ? categoryPw : pw;
15957                if (!isCompact) {
15958                    out.println();
15959                    out.println("Total PSS by category:");
15960                }
15961                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15962            }
15963            if (!isCompact) {
15964                pw.println();
15965            }
15966            MemInfoReader memInfo = new MemInfoReader();
15967            memInfo.readMemInfo();
15968            if (nativeProcTotalPss > 0) {
15969                synchronized (this) {
15970                    final long cachedKb = memInfo.getCachedSizeKb();
15971                    final long freeKb = memInfo.getFreeSizeKb();
15972                    final long zramKb = memInfo.getZramTotalSizeKb();
15973                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15974                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15975                            kernelKb*1024, nativeProcTotalPss*1024);
15976                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15977                            nativeProcTotalPss);
15978                }
15979            }
15980            if (!brief) {
15981                if (!isCompact) {
15982                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15983                    pw.print(" (status ");
15984                    switch (mLastMemoryLevel) {
15985                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15986                            pw.println("normal)");
15987                            break;
15988                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15989                            pw.println("moderate)");
15990                            break;
15991                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15992                            pw.println("low)");
15993                            break;
15994                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15995                            pw.println("critical)");
15996                            break;
15997                        default:
15998                            pw.print(mLastMemoryLevel);
15999                            pw.println(")");
16000                            break;
16001                    }
16002                    pw.print(" Free RAM: ");
16003                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16004                            + memInfo.getFreeSizeKb()));
16005                    pw.print(" (");
16006                    pw.print(stringifyKBSize(cachedPss));
16007                    pw.print(" cached pss + ");
16008                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16009                    pw.print(" cached kernel + ");
16010                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16011                    pw.println(" free)");
16012                } else {
16013                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16014                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16015                            + memInfo.getFreeSizeKb()); pw.print(",");
16016                    pw.println(totalPss - cachedPss);
16017                }
16018            }
16019            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16020                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16021                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16022            if (!isCompact) {
16023                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16024                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16025                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16026                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16027                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16028            } else {
16029                pw.print("lostram,"); pw.println(lostRAM);
16030            }
16031            if (!brief) {
16032                if (memInfo.getZramTotalSizeKb() != 0) {
16033                    if (!isCompact) {
16034                        pw.print("     ZRAM: ");
16035                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16036                                pw.print(" physical used for ");
16037                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16038                                        - memInfo.getSwapFreeSizeKb()));
16039                                pw.print(" in swap (");
16040                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16041                                pw.println(" total swap)");
16042                    } else {
16043                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16044                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16045                                pw.println(memInfo.getSwapFreeSizeKb());
16046                    }
16047                }
16048                final long[] ksm = getKsmInfo();
16049                if (!isCompact) {
16050                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16051                            || ksm[KSM_VOLATILE] != 0) {
16052                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16053                                pw.print(" saved from shared ");
16054                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16055                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16056                                pw.print(" unshared; ");
16057                                pw.print(stringifyKBSize(
16058                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16059                    }
16060                    pw.print("   Tuning: ");
16061                    pw.print(ActivityManager.staticGetMemoryClass());
16062                    pw.print(" (large ");
16063                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16064                    pw.print("), oom ");
16065                    pw.print(stringifySize(
16066                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16067                    pw.print(", restore limit ");
16068                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16069                    if (ActivityManager.isLowRamDeviceStatic()) {
16070                        pw.print(" (low-ram)");
16071                    }
16072                    if (ActivityManager.isHighEndGfx()) {
16073                        pw.print(" (high-end-gfx)");
16074                    }
16075                    pw.println();
16076                } else {
16077                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16078                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16079                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16080                    pw.print("tuning,");
16081                    pw.print(ActivityManager.staticGetMemoryClass());
16082                    pw.print(',');
16083                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16084                    pw.print(',');
16085                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16086                    if (ActivityManager.isLowRamDeviceStatic()) {
16087                        pw.print(",low-ram");
16088                    }
16089                    if (ActivityManager.isHighEndGfx()) {
16090                        pw.print(",high-end-gfx");
16091                    }
16092                    pw.println();
16093                }
16094            }
16095        }
16096    }
16097
16098    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16099            long memtrack, String name) {
16100        sb.append("  ");
16101        sb.append(ProcessList.makeOomAdjString(oomAdj));
16102        sb.append(' ');
16103        sb.append(ProcessList.makeProcStateString(procState));
16104        sb.append(' ');
16105        ProcessList.appendRamKb(sb, pss);
16106        sb.append(": ");
16107        sb.append(name);
16108        if (memtrack > 0) {
16109            sb.append(" (");
16110            sb.append(stringifyKBSize(memtrack));
16111            sb.append(" memtrack)");
16112        }
16113    }
16114
16115    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16116        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16117        sb.append(" (pid ");
16118        sb.append(mi.pid);
16119        sb.append(") ");
16120        sb.append(mi.adjType);
16121        sb.append('\n');
16122        if (mi.adjReason != null) {
16123            sb.append("                      ");
16124            sb.append(mi.adjReason);
16125            sb.append('\n');
16126        }
16127    }
16128
16129    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16130        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16131        for (int i=0, N=memInfos.size(); i<N; i++) {
16132            ProcessMemInfo mi = memInfos.get(i);
16133            infoMap.put(mi.pid, mi);
16134        }
16135        updateCpuStatsNow();
16136        long[] memtrackTmp = new long[1];
16137        synchronized (mProcessCpuTracker) {
16138            final int N = mProcessCpuTracker.countStats();
16139            for (int i=0; i<N; i++) {
16140                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16141                if (st.vsize > 0) {
16142                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16143                    if (pss > 0) {
16144                        if (infoMap.indexOfKey(st.pid) < 0) {
16145                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16146                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16147                            mi.pss = pss;
16148                            mi.memtrack = memtrackTmp[0];
16149                            memInfos.add(mi);
16150                        }
16151                    }
16152                }
16153            }
16154        }
16155
16156        long totalPss = 0;
16157        long totalMemtrack = 0;
16158        for (int i=0, N=memInfos.size(); i<N; i++) {
16159            ProcessMemInfo mi = memInfos.get(i);
16160            if (mi.pss == 0) {
16161                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16162                mi.memtrack = memtrackTmp[0];
16163            }
16164            totalPss += mi.pss;
16165            totalMemtrack += mi.memtrack;
16166        }
16167        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16168            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16169                if (lhs.oomAdj != rhs.oomAdj) {
16170                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16171                }
16172                if (lhs.pss != rhs.pss) {
16173                    return lhs.pss < rhs.pss ? 1 : -1;
16174                }
16175                return 0;
16176            }
16177        });
16178
16179        StringBuilder tag = new StringBuilder(128);
16180        StringBuilder stack = new StringBuilder(128);
16181        tag.append("Low on memory -- ");
16182        appendMemBucket(tag, totalPss, "total", false);
16183        appendMemBucket(stack, totalPss, "total", true);
16184
16185        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16186        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16187        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16188
16189        boolean firstLine = true;
16190        int lastOomAdj = Integer.MIN_VALUE;
16191        long extraNativeRam = 0;
16192        long extraNativeMemtrack = 0;
16193        long cachedPss = 0;
16194        for (int i=0, N=memInfos.size(); i<N; i++) {
16195            ProcessMemInfo mi = memInfos.get(i);
16196
16197            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16198                cachedPss += mi.pss;
16199            }
16200
16201            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16202                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16203                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16204                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16205                if (lastOomAdj != mi.oomAdj) {
16206                    lastOomAdj = mi.oomAdj;
16207                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16208                        tag.append(" / ");
16209                    }
16210                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16211                        if (firstLine) {
16212                            stack.append(":");
16213                            firstLine = false;
16214                        }
16215                        stack.append("\n\t at ");
16216                    } else {
16217                        stack.append("$");
16218                    }
16219                } else {
16220                    tag.append(" ");
16221                    stack.append("$");
16222                }
16223                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16224                    appendMemBucket(tag, mi.pss, mi.name, false);
16225                }
16226                appendMemBucket(stack, mi.pss, mi.name, true);
16227                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16228                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16229                    stack.append("(");
16230                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16231                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16232                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16233                            stack.append(":");
16234                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16235                        }
16236                    }
16237                    stack.append(")");
16238                }
16239            }
16240
16241            appendMemInfo(fullNativeBuilder, mi);
16242            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16243                // The short form only has native processes that are >= 512K.
16244                if (mi.pss >= 512) {
16245                    appendMemInfo(shortNativeBuilder, mi);
16246                } else {
16247                    extraNativeRam += mi.pss;
16248                    extraNativeMemtrack += mi.memtrack;
16249                }
16250            } else {
16251                // Short form has all other details, but if we have collected RAM
16252                // from smaller native processes let's dump a summary of that.
16253                if (extraNativeRam > 0) {
16254                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16255                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16256                    shortNativeBuilder.append('\n');
16257                    extraNativeRam = 0;
16258                }
16259                appendMemInfo(fullJavaBuilder, mi);
16260            }
16261        }
16262
16263        fullJavaBuilder.append("           ");
16264        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16265        fullJavaBuilder.append(": TOTAL");
16266        if (totalMemtrack > 0) {
16267            fullJavaBuilder.append(" (");
16268            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16269            fullJavaBuilder.append(" memtrack)");
16270        } else {
16271        }
16272        fullJavaBuilder.append("\n");
16273
16274        MemInfoReader memInfo = new MemInfoReader();
16275        memInfo.readMemInfo();
16276        final long[] infos = memInfo.getRawInfo();
16277
16278        StringBuilder memInfoBuilder = new StringBuilder(1024);
16279        Debug.getMemInfo(infos);
16280        memInfoBuilder.append("  MemInfo: ");
16281        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16282        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16283        memInfoBuilder.append(stringifyKBSize(
16284                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16285        memInfoBuilder.append(stringifyKBSize(
16286                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16287        memInfoBuilder.append(stringifyKBSize(
16288                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16289        memInfoBuilder.append("           ");
16290        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16291        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16292        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16293        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16294        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16295            memInfoBuilder.append("  ZRAM: ");
16296            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16297            memInfoBuilder.append(" RAM, ");
16298            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16299            memInfoBuilder.append(" swap total, ");
16300            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16301            memInfoBuilder.append(" swap free\n");
16302        }
16303        final long[] ksm = getKsmInfo();
16304        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16305                || ksm[KSM_VOLATILE] != 0) {
16306            memInfoBuilder.append("  KSM: ");
16307            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16308            memInfoBuilder.append(" saved from shared ");
16309            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16310            memInfoBuilder.append("\n       ");
16311            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16312            memInfoBuilder.append(" unshared; ");
16313            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16314            memInfoBuilder.append(" volatile\n");
16315        }
16316        memInfoBuilder.append("  Free RAM: ");
16317        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16318                + memInfo.getFreeSizeKb()));
16319        memInfoBuilder.append("\n");
16320        memInfoBuilder.append("  Used RAM: ");
16321        memInfoBuilder.append(stringifyKBSize(
16322                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16323        memInfoBuilder.append("\n");
16324        memInfoBuilder.append("  Lost RAM: ");
16325        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16326                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16327                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16328        memInfoBuilder.append("\n");
16329        Slog.i(TAG, "Low on memory:");
16330        Slog.i(TAG, shortNativeBuilder.toString());
16331        Slog.i(TAG, fullJavaBuilder.toString());
16332        Slog.i(TAG, memInfoBuilder.toString());
16333
16334        StringBuilder dropBuilder = new StringBuilder(1024);
16335        /*
16336        StringWriter oomSw = new StringWriter();
16337        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16338        StringWriter catSw = new StringWriter();
16339        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16340        String[] emptyArgs = new String[] { };
16341        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16342        oomPw.flush();
16343        String oomString = oomSw.toString();
16344        */
16345        dropBuilder.append("Low on memory:");
16346        dropBuilder.append(stack);
16347        dropBuilder.append('\n');
16348        dropBuilder.append(fullNativeBuilder);
16349        dropBuilder.append(fullJavaBuilder);
16350        dropBuilder.append('\n');
16351        dropBuilder.append(memInfoBuilder);
16352        dropBuilder.append('\n');
16353        /*
16354        dropBuilder.append(oomString);
16355        dropBuilder.append('\n');
16356        */
16357        StringWriter catSw = new StringWriter();
16358        synchronized (ActivityManagerService.this) {
16359            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16360            String[] emptyArgs = new String[] { };
16361            catPw.println();
16362            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16363            catPw.println();
16364            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16365                    false, null).dumpLocked();
16366            catPw.println();
16367            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16368            catPw.flush();
16369        }
16370        dropBuilder.append(catSw.toString());
16371        addErrorToDropBox("lowmem", null, "system_server", null,
16372                null, tag.toString(), dropBuilder.toString(), null, null);
16373        //Slog.i(TAG, "Sent to dropbox:");
16374        //Slog.i(TAG, dropBuilder.toString());
16375        synchronized (ActivityManagerService.this) {
16376            long now = SystemClock.uptimeMillis();
16377            if (mLastMemUsageReportTime < now) {
16378                mLastMemUsageReportTime = now;
16379            }
16380        }
16381    }
16382
16383    /**
16384     * Searches array of arguments for the specified string
16385     * @param args array of argument strings
16386     * @param value value to search for
16387     * @return true if the value is contained in the array
16388     */
16389    private static boolean scanArgs(String[] args, String value) {
16390        if (args != null) {
16391            for (String arg : args) {
16392                if (value.equals(arg)) {
16393                    return true;
16394                }
16395            }
16396        }
16397        return false;
16398    }
16399
16400    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16401            ContentProviderRecord cpr, boolean always) {
16402        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16403
16404        if (!inLaunching || always) {
16405            synchronized (cpr) {
16406                cpr.launchingApp = null;
16407                cpr.notifyAll();
16408            }
16409            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16410            String names[] = cpr.info.authority.split(";");
16411            for (int j = 0; j < names.length; j++) {
16412                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16413            }
16414        }
16415
16416        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16417            ContentProviderConnection conn = cpr.connections.get(i);
16418            if (conn.waiting) {
16419                // If this connection is waiting for the provider, then we don't
16420                // need to mess with its process unless we are always removing
16421                // or for some reason the provider is not currently launching.
16422                if (inLaunching && !always) {
16423                    continue;
16424                }
16425            }
16426            ProcessRecord capp = conn.client;
16427            conn.dead = true;
16428            if (conn.stableCount > 0) {
16429                if (!capp.persistent && capp.thread != null
16430                        && capp.pid != 0
16431                        && capp.pid != MY_PID) {
16432                    capp.kill("depends on provider "
16433                            + cpr.name.flattenToShortString()
16434                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16435                }
16436            } else if (capp.thread != null && conn.provider.provider != null) {
16437                try {
16438                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16439                } catch (RemoteException e) {
16440                }
16441                // In the protocol here, we don't expect the client to correctly
16442                // clean up this connection, we'll just remove it.
16443                cpr.connections.remove(i);
16444                if (conn.client.conProviders.remove(conn)) {
16445                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16446                }
16447            }
16448        }
16449
16450        if (inLaunching && always) {
16451            mLaunchingProviders.remove(cpr);
16452        }
16453        return inLaunching;
16454    }
16455
16456    /**
16457     * Main code for cleaning up a process when it has gone away.  This is
16458     * called both as a result of the process dying, or directly when stopping
16459     * a process when running in single process mode.
16460     *
16461     * @return Returns true if the given process has been restarted, so the
16462     * app that was passed in must remain on the process lists.
16463     */
16464    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16465            boolean restarting, boolean allowRestart, int index) {
16466        if (index >= 0) {
16467            removeLruProcessLocked(app);
16468            ProcessList.remove(app.pid);
16469        }
16470
16471        mProcessesToGc.remove(app);
16472        mPendingPssProcesses.remove(app);
16473
16474        // Dismiss any open dialogs.
16475        if (app.crashDialog != null && !app.forceCrashReport) {
16476            app.crashDialog.dismiss();
16477            app.crashDialog = null;
16478        }
16479        if (app.anrDialog != null) {
16480            app.anrDialog.dismiss();
16481            app.anrDialog = null;
16482        }
16483        if (app.waitDialog != null) {
16484            app.waitDialog.dismiss();
16485            app.waitDialog = null;
16486        }
16487
16488        app.crashing = false;
16489        app.notResponding = false;
16490
16491        app.resetPackageList(mProcessStats);
16492        app.unlinkDeathRecipient();
16493        app.makeInactive(mProcessStats);
16494        app.waitingToKill = null;
16495        app.forcingToForeground = null;
16496        updateProcessForegroundLocked(app, false, false);
16497        app.foregroundActivities = false;
16498        app.hasShownUi = false;
16499        app.treatLikeActivity = false;
16500        app.hasAboveClient = false;
16501        app.hasClientActivities = false;
16502
16503        mServices.killServicesLocked(app, allowRestart);
16504
16505        boolean restart = false;
16506
16507        // Remove published content providers.
16508        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16509            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16510            final boolean always = app.bad || !allowRestart;
16511            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16512            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16513                // We left the provider in the launching list, need to
16514                // restart it.
16515                restart = true;
16516            }
16517
16518            cpr.provider = null;
16519            cpr.proc = null;
16520        }
16521        app.pubProviders.clear();
16522
16523        // Take care of any launching providers waiting for this process.
16524        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16525            restart = true;
16526        }
16527
16528        // Unregister from connected content providers.
16529        if (!app.conProviders.isEmpty()) {
16530            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16531                ContentProviderConnection conn = app.conProviders.get(i);
16532                conn.provider.connections.remove(conn);
16533                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16534                        conn.provider.name);
16535            }
16536            app.conProviders.clear();
16537        }
16538
16539        // At this point there may be remaining entries in mLaunchingProviders
16540        // where we were the only one waiting, so they are no longer of use.
16541        // Look for these and clean up if found.
16542        // XXX Commented out for now.  Trying to figure out a way to reproduce
16543        // the actual situation to identify what is actually going on.
16544        if (false) {
16545            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16546                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16547                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16548                    synchronized (cpr) {
16549                        cpr.launchingApp = null;
16550                        cpr.notifyAll();
16551                    }
16552                }
16553            }
16554        }
16555
16556        skipCurrentReceiverLocked(app);
16557
16558        // Unregister any receivers.
16559        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16560            removeReceiverLocked(app.receivers.valueAt(i));
16561        }
16562        app.receivers.clear();
16563
16564        // If the app is undergoing backup, tell the backup manager about it
16565        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16566            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16567                    + mBackupTarget.appInfo + " died during backup");
16568            try {
16569                IBackupManager bm = IBackupManager.Stub.asInterface(
16570                        ServiceManager.getService(Context.BACKUP_SERVICE));
16571                bm.agentDisconnected(app.info.packageName);
16572            } catch (RemoteException e) {
16573                // can't happen; backup manager is local
16574            }
16575        }
16576
16577        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16578            ProcessChangeItem item = mPendingProcessChanges.get(i);
16579            if (item.pid == app.pid) {
16580                mPendingProcessChanges.remove(i);
16581                mAvailProcessChanges.add(item);
16582            }
16583        }
16584        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16585                null).sendToTarget();
16586
16587        // If the caller is restarting this app, then leave it in its
16588        // current lists and let the caller take care of it.
16589        if (restarting) {
16590            return false;
16591        }
16592
16593        if (!app.persistent || app.isolated) {
16594            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16595                    "Removing non-persistent process during cleanup: " + app);
16596            removeProcessNameLocked(app.processName, app.uid);
16597            if (mHeavyWeightProcess == app) {
16598                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16599                        mHeavyWeightProcess.userId, 0));
16600                mHeavyWeightProcess = null;
16601            }
16602        } else if (!app.removed) {
16603            // This app is persistent, so we need to keep its record around.
16604            // If it is not already on the pending app list, add it there
16605            // and start a new process for it.
16606            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16607                mPersistentStartingProcesses.add(app);
16608                restart = true;
16609            }
16610        }
16611        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16612                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16613        mProcessesOnHold.remove(app);
16614
16615        if (app == mHomeProcess) {
16616            mHomeProcess = null;
16617        }
16618        if (app == mPreviousProcess) {
16619            mPreviousProcess = null;
16620        }
16621
16622        if (restart && !app.isolated) {
16623            // We have components that still need to be running in the
16624            // process, so re-launch it.
16625            if (index < 0) {
16626                ProcessList.remove(app.pid);
16627            }
16628            addProcessNameLocked(app);
16629            startProcessLocked(app, "restart", app.processName);
16630            return true;
16631        } else if (app.pid > 0 && app.pid != MY_PID) {
16632            // Goodbye!
16633            boolean removed;
16634            synchronized (mPidsSelfLocked) {
16635                mPidsSelfLocked.remove(app.pid);
16636                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16637            }
16638            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16639            if (app.isolated) {
16640                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16641            }
16642            app.setPid(0);
16643        }
16644        return false;
16645    }
16646
16647    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16648        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16649            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16650            if (cpr.launchingApp == app) {
16651                return true;
16652            }
16653        }
16654        return false;
16655    }
16656
16657    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16658        // Look through the content providers we are waiting to have launched,
16659        // and if any run in this process then either schedule a restart of
16660        // the process or kill the client waiting for it if this process has
16661        // gone bad.
16662        boolean restart = false;
16663        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16664            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16665            if (cpr.launchingApp == app) {
16666                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16667                    restart = true;
16668                } else {
16669                    removeDyingProviderLocked(app, cpr, true);
16670                }
16671            }
16672        }
16673        return restart;
16674    }
16675
16676    // =========================================================
16677    // SERVICES
16678    // =========================================================
16679
16680    @Override
16681    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16682            int flags) {
16683        enforceNotIsolatedCaller("getServices");
16684        synchronized (this) {
16685            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16686        }
16687    }
16688
16689    @Override
16690    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16691        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16692        synchronized (this) {
16693            return mServices.getRunningServiceControlPanelLocked(name);
16694        }
16695    }
16696
16697    @Override
16698    public ComponentName startService(IApplicationThread caller, Intent service,
16699            String resolvedType, String callingPackage, int userId)
16700            throws TransactionTooLargeException {
16701        enforceNotIsolatedCaller("startService");
16702        // Refuse possible leaked file descriptors
16703        if (service != null && service.hasFileDescriptors() == true) {
16704            throw new IllegalArgumentException("File descriptors passed in Intent");
16705        }
16706
16707        if (callingPackage == null) {
16708            throw new IllegalArgumentException("callingPackage cannot be null");
16709        }
16710
16711        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16712                "startService: " + service + " type=" + resolvedType);
16713        synchronized(this) {
16714            final int callingPid = Binder.getCallingPid();
16715            final int callingUid = Binder.getCallingUid();
16716            final long origId = Binder.clearCallingIdentity();
16717            ComponentName res = mServices.startServiceLocked(caller, service,
16718                    resolvedType, callingPid, callingUid, callingPackage, userId);
16719            Binder.restoreCallingIdentity(origId);
16720            return res;
16721        }
16722    }
16723
16724    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16725            String callingPackage, int userId)
16726            throws TransactionTooLargeException {
16727        synchronized(this) {
16728            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16729                    "startServiceInPackage: " + service + " type=" + resolvedType);
16730            final long origId = Binder.clearCallingIdentity();
16731            ComponentName res = mServices.startServiceLocked(null, service,
16732                    resolvedType, -1, uid, callingPackage, userId);
16733            Binder.restoreCallingIdentity(origId);
16734            return res;
16735        }
16736    }
16737
16738    @Override
16739    public int stopService(IApplicationThread caller, Intent service,
16740            String resolvedType, int userId) {
16741        enforceNotIsolatedCaller("stopService");
16742        // Refuse possible leaked file descriptors
16743        if (service != null && service.hasFileDescriptors() == true) {
16744            throw new IllegalArgumentException("File descriptors passed in Intent");
16745        }
16746
16747        synchronized(this) {
16748            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16749        }
16750    }
16751
16752    @Override
16753    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16754        enforceNotIsolatedCaller("peekService");
16755        // Refuse possible leaked file descriptors
16756        if (service != null && service.hasFileDescriptors() == true) {
16757            throw new IllegalArgumentException("File descriptors passed in Intent");
16758        }
16759
16760        if (callingPackage == null) {
16761            throw new IllegalArgumentException("callingPackage cannot be null");
16762        }
16763
16764        synchronized(this) {
16765            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16766        }
16767    }
16768
16769    @Override
16770    public boolean stopServiceToken(ComponentName className, IBinder token,
16771            int startId) {
16772        synchronized(this) {
16773            return mServices.stopServiceTokenLocked(className, token, startId);
16774        }
16775    }
16776
16777    @Override
16778    public void setServiceForeground(ComponentName className, IBinder token,
16779            int id, Notification notification, int flags) {
16780        synchronized(this) {
16781            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16782        }
16783    }
16784
16785    @Override
16786    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16787            boolean requireFull, String name, String callerPackage) {
16788        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16789                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16790    }
16791
16792    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16793            String className, int flags) {
16794        boolean result = false;
16795        // For apps that don't have pre-defined UIDs, check for permission
16796        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16797            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16798                if (ActivityManager.checkUidPermission(
16799                        INTERACT_ACROSS_USERS,
16800                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16801                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16802                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16803                            + " requests FLAG_SINGLE_USER, but app does not hold "
16804                            + INTERACT_ACROSS_USERS;
16805                    Slog.w(TAG, msg);
16806                    throw new SecurityException(msg);
16807                }
16808                // Permission passed
16809                result = true;
16810            }
16811        } else if ("system".equals(componentProcessName)) {
16812            result = true;
16813        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16814            // Phone app and persistent apps are allowed to export singleuser providers.
16815            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16816                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16817        }
16818        if (DEBUG_MU) Slog.v(TAG_MU,
16819                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16820                + Integer.toHexString(flags) + ") = " + result);
16821        return result;
16822    }
16823
16824    /**
16825     * Checks to see if the caller is in the same app as the singleton
16826     * component, or the component is in a special app. It allows special apps
16827     * to export singleton components but prevents exporting singleton
16828     * components for regular apps.
16829     */
16830    boolean isValidSingletonCall(int callingUid, int componentUid) {
16831        int componentAppId = UserHandle.getAppId(componentUid);
16832        return UserHandle.isSameApp(callingUid, componentUid)
16833                || componentAppId == Process.SYSTEM_UID
16834                || componentAppId == Process.PHONE_UID
16835                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16836                        == PackageManager.PERMISSION_GRANTED;
16837    }
16838
16839    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16840            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16841            int userId) throws TransactionTooLargeException {
16842        enforceNotIsolatedCaller("bindService");
16843
16844        // Refuse possible leaked file descriptors
16845        if (service != null && service.hasFileDescriptors() == true) {
16846            throw new IllegalArgumentException("File descriptors passed in Intent");
16847        }
16848
16849        if (callingPackage == null) {
16850            throw new IllegalArgumentException("callingPackage cannot be null");
16851        }
16852
16853        synchronized(this) {
16854            return mServices.bindServiceLocked(caller, token, service,
16855                    resolvedType, connection, flags, callingPackage, userId);
16856        }
16857    }
16858
16859    public boolean unbindService(IServiceConnection connection) {
16860        synchronized (this) {
16861            return mServices.unbindServiceLocked(connection);
16862        }
16863    }
16864
16865    public void publishService(IBinder token, Intent intent, IBinder service) {
16866        // Refuse possible leaked file descriptors
16867        if (intent != null && intent.hasFileDescriptors() == true) {
16868            throw new IllegalArgumentException("File descriptors passed in Intent");
16869        }
16870
16871        synchronized(this) {
16872            if (!(token instanceof ServiceRecord)) {
16873                throw new IllegalArgumentException("Invalid service token");
16874            }
16875            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16876        }
16877    }
16878
16879    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16880        // Refuse possible leaked file descriptors
16881        if (intent != null && intent.hasFileDescriptors() == true) {
16882            throw new IllegalArgumentException("File descriptors passed in Intent");
16883        }
16884
16885        synchronized(this) {
16886            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16887        }
16888    }
16889
16890    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16891        synchronized(this) {
16892            if (!(token instanceof ServiceRecord)) {
16893                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16894                throw new IllegalArgumentException("Invalid service token");
16895            }
16896            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16897        }
16898    }
16899
16900    // =========================================================
16901    // BACKUP AND RESTORE
16902    // =========================================================
16903
16904    // Cause the target app to be launched if necessary and its backup agent
16905    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16906    // activity manager to announce its creation.
16907    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16908        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16909                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16910        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16911
16912        synchronized(this) {
16913            // !!! TODO: currently no check here that we're already bound
16914            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16915            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16916            synchronized (stats) {
16917                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16918            }
16919
16920            // Backup agent is now in use, its package can't be stopped.
16921            try {
16922                AppGlobals.getPackageManager().setPackageStoppedState(
16923                        app.packageName, false, UserHandle.getUserId(app.uid));
16924            } catch (RemoteException e) {
16925            } catch (IllegalArgumentException e) {
16926                Slog.w(TAG, "Failed trying to unstop package "
16927                        + app.packageName + ": " + e);
16928            }
16929
16930            BackupRecord r = new BackupRecord(ss, app, backupMode);
16931            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16932                    ? new ComponentName(app.packageName, app.backupAgentName)
16933                    : new ComponentName("android", "FullBackupAgent");
16934            // startProcessLocked() returns existing proc's record if it's already running
16935            ProcessRecord proc = startProcessLocked(app.processName, app,
16936                    false, 0, "backup", hostingName, false, false, false);
16937            if (proc == null) {
16938                Slog.e(TAG, "Unable to start backup agent process " + r);
16939                return false;
16940            }
16941
16942            // If the app is a regular app (uid >= 10000) and not the system server or phone
16943            // process, etc, then mark it as being in full backup so that certain calls to the
16944            // process can be blocked. This is not reset to false anywhere because we kill the
16945            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16946            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16947                proc.inFullBackup = true;
16948            }
16949            r.app = proc;
16950            mBackupTarget = r;
16951            mBackupAppName = app.packageName;
16952
16953            // Try not to kill the process during backup
16954            updateOomAdjLocked(proc);
16955
16956            // If the process is already attached, schedule the creation of the backup agent now.
16957            // If it is not yet live, this will be done when it attaches to the framework.
16958            if (proc.thread != null) {
16959                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16960                try {
16961                    proc.thread.scheduleCreateBackupAgent(app,
16962                            compatibilityInfoForPackageLocked(app), backupMode);
16963                } catch (RemoteException e) {
16964                    // Will time out on the backup manager side
16965                }
16966            } else {
16967                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16968            }
16969            // Invariants: at this point, the target app process exists and the application
16970            // is either already running or in the process of coming up.  mBackupTarget and
16971            // mBackupAppName describe the app, so that when it binds back to the AM we
16972            // know that it's scheduled for a backup-agent operation.
16973        }
16974
16975        return true;
16976    }
16977
16978    @Override
16979    public void clearPendingBackup() {
16980        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16981        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16982
16983        synchronized (this) {
16984            mBackupTarget = null;
16985            mBackupAppName = null;
16986        }
16987    }
16988
16989    // A backup agent has just come up
16990    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16991        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16992                + " = " + agent);
16993
16994        synchronized(this) {
16995            if (!agentPackageName.equals(mBackupAppName)) {
16996                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16997                return;
16998            }
16999        }
17000
17001        long oldIdent = Binder.clearCallingIdentity();
17002        try {
17003            IBackupManager bm = IBackupManager.Stub.asInterface(
17004                    ServiceManager.getService(Context.BACKUP_SERVICE));
17005            bm.agentConnected(agentPackageName, agent);
17006        } catch (RemoteException e) {
17007            // can't happen; the backup manager service is local
17008        } catch (Exception e) {
17009            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17010            e.printStackTrace();
17011        } finally {
17012            Binder.restoreCallingIdentity(oldIdent);
17013        }
17014    }
17015
17016    // done with this agent
17017    public void unbindBackupAgent(ApplicationInfo appInfo) {
17018        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17019        if (appInfo == null) {
17020            Slog.w(TAG, "unbind backup agent for null app");
17021            return;
17022        }
17023
17024        synchronized(this) {
17025            try {
17026                if (mBackupAppName == null) {
17027                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17028                    return;
17029                }
17030
17031                if (!mBackupAppName.equals(appInfo.packageName)) {
17032                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17033                    return;
17034                }
17035
17036                // Not backing this app up any more; reset its OOM adjustment
17037                final ProcessRecord proc = mBackupTarget.app;
17038                updateOomAdjLocked(proc);
17039
17040                // If the app crashed during backup, 'thread' will be null here
17041                if (proc.thread != null) {
17042                    try {
17043                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17044                                compatibilityInfoForPackageLocked(appInfo));
17045                    } catch (Exception e) {
17046                        Slog.e(TAG, "Exception when unbinding backup agent:");
17047                        e.printStackTrace();
17048                    }
17049                }
17050            } finally {
17051                mBackupTarget = null;
17052                mBackupAppName = null;
17053            }
17054        }
17055    }
17056    // =========================================================
17057    // BROADCASTS
17058    // =========================================================
17059
17060    boolean isPendingBroadcastProcessLocked(int pid) {
17061        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17062                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17063    }
17064
17065    void skipPendingBroadcastLocked(int pid) {
17066            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17067            for (BroadcastQueue queue : mBroadcastQueues) {
17068                queue.skipPendingBroadcastLocked(pid);
17069            }
17070    }
17071
17072    // The app just attached; send any pending broadcasts that it should receive
17073    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17074        boolean didSomething = false;
17075        for (BroadcastQueue queue : mBroadcastQueues) {
17076            didSomething |= queue.sendPendingBroadcastsLocked(app);
17077        }
17078        return didSomething;
17079    }
17080
17081    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17082            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17083        enforceNotIsolatedCaller("registerReceiver");
17084        ArrayList<Intent> stickyIntents = null;
17085        ProcessRecord callerApp = null;
17086        int callingUid;
17087        int callingPid;
17088        synchronized(this) {
17089            if (caller != null) {
17090                callerApp = getRecordForAppLocked(caller);
17091                if (callerApp == null) {
17092                    throw new SecurityException(
17093                            "Unable to find app for caller " + caller
17094                            + " (pid=" + Binder.getCallingPid()
17095                            + ") when registering receiver " + receiver);
17096                }
17097                if (callerApp.info.uid != Process.SYSTEM_UID &&
17098                        !callerApp.pkgList.containsKey(callerPackage) &&
17099                        !"android".equals(callerPackage)) {
17100                    throw new SecurityException("Given caller package " + callerPackage
17101                            + " is not running in process " + callerApp);
17102                }
17103                callingUid = callerApp.info.uid;
17104                callingPid = callerApp.pid;
17105            } else {
17106                callerPackage = null;
17107                callingUid = Binder.getCallingUid();
17108                callingPid = Binder.getCallingPid();
17109            }
17110
17111            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17112                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17113
17114            Iterator<String> actions = filter.actionsIterator();
17115            if (actions == null) {
17116                ArrayList<String> noAction = new ArrayList<String>(1);
17117                noAction.add(null);
17118                actions = noAction.iterator();
17119            }
17120
17121            // Collect stickies of users
17122            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17123            while (actions.hasNext()) {
17124                String action = actions.next();
17125                for (int id : userIds) {
17126                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17127                    if (stickies != null) {
17128                        ArrayList<Intent> intents = stickies.get(action);
17129                        if (intents != null) {
17130                            if (stickyIntents == null) {
17131                                stickyIntents = new ArrayList<Intent>();
17132                            }
17133                            stickyIntents.addAll(intents);
17134                        }
17135                    }
17136                }
17137            }
17138        }
17139
17140        ArrayList<Intent> allSticky = null;
17141        if (stickyIntents != null) {
17142            final ContentResolver resolver = mContext.getContentResolver();
17143            // Look for any matching sticky broadcasts...
17144            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17145                Intent intent = stickyIntents.get(i);
17146                // If intent has scheme "content", it will need to acccess
17147                // provider that needs to lock mProviderMap in ActivityThread
17148                // and also it may need to wait application response, so we
17149                // cannot lock ActivityManagerService here.
17150                if (filter.match(resolver, intent, true, TAG) >= 0) {
17151                    if (allSticky == null) {
17152                        allSticky = new ArrayList<Intent>();
17153                    }
17154                    allSticky.add(intent);
17155                }
17156            }
17157        }
17158
17159        // The first sticky in the list is returned directly back to the client.
17160        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17161        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17162        if (receiver == null) {
17163            return sticky;
17164        }
17165
17166        synchronized (this) {
17167            if (callerApp != null && (callerApp.thread == null
17168                    || callerApp.thread.asBinder() != caller.asBinder())) {
17169                // Original caller already died
17170                return null;
17171            }
17172            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17173            if (rl == null) {
17174                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17175                        userId, receiver);
17176                if (rl.app != null) {
17177                    rl.app.receivers.add(rl);
17178                } else {
17179                    try {
17180                        receiver.asBinder().linkToDeath(rl, 0);
17181                    } catch (RemoteException e) {
17182                        return sticky;
17183                    }
17184                    rl.linkedToDeath = true;
17185                }
17186                mRegisteredReceivers.put(receiver.asBinder(), rl);
17187            } else if (rl.uid != callingUid) {
17188                throw new IllegalArgumentException(
17189                        "Receiver requested to register for uid " + callingUid
17190                        + " was previously registered for uid " + rl.uid);
17191            } else if (rl.pid != callingPid) {
17192                throw new IllegalArgumentException(
17193                        "Receiver requested to register for pid " + callingPid
17194                        + " was previously registered for pid " + rl.pid);
17195            } else if (rl.userId != userId) {
17196                throw new IllegalArgumentException(
17197                        "Receiver requested to register for user " + userId
17198                        + " was previously registered for user " + rl.userId);
17199            }
17200            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17201                    permission, callingUid, userId);
17202            rl.add(bf);
17203            if (!bf.debugCheck()) {
17204                Slog.w(TAG, "==> For Dynamic broadcast");
17205            }
17206            mReceiverResolver.addFilter(bf);
17207
17208            // Enqueue broadcasts for all existing stickies that match
17209            // this filter.
17210            if (allSticky != null) {
17211                ArrayList receivers = new ArrayList();
17212                receivers.add(bf);
17213
17214                final int stickyCount = allSticky.size();
17215                for (int i = 0; i < stickyCount; i++) {
17216                    Intent intent = allSticky.get(i);
17217                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17218                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17219                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17220                            null, 0, null, null, false, true, true, -1);
17221                    queue.enqueueParallelBroadcastLocked(r);
17222                    queue.scheduleBroadcastsLocked();
17223                }
17224            }
17225
17226            return sticky;
17227        }
17228    }
17229
17230    public void unregisterReceiver(IIntentReceiver receiver) {
17231        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17232
17233        final long origId = Binder.clearCallingIdentity();
17234        try {
17235            boolean doTrim = false;
17236
17237            synchronized(this) {
17238                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17239                if (rl != null) {
17240                    final BroadcastRecord r = rl.curBroadcast;
17241                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17242                        final boolean doNext = r.queue.finishReceiverLocked(
17243                                r, r.resultCode, r.resultData, r.resultExtras,
17244                                r.resultAbort, false);
17245                        if (doNext) {
17246                            doTrim = true;
17247                            r.queue.processNextBroadcast(false);
17248                        }
17249                    }
17250
17251                    if (rl.app != null) {
17252                        rl.app.receivers.remove(rl);
17253                    }
17254                    removeReceiverLocked(rl);
17255                    if (rl.linkedToDeath) {
17256                        rl.linkedToDeath = false;
17257                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17258                    }
17259                }
17260            }
17261
17262            // If we actually concluded any broadcasts, we might now be able
17263            // to trim the recipients' apps from our working set
17264            if (doTrim) {
17265                trimApplications();
17266                return;
17267            }
17268
17269        } finally {
17270            Binder.restoreCallingIdentity(origId);
17271        }
17272    }
17273
17274    void removeReceiverLocked(ReceiverList rl) {
17275        mRegisteredReceivers.remove(rl.receiver.asBinder());
17276        for (int i = rl.size() - 1; i >= 0; i--) {
17277            mReceiverResolver.removeFilter(rl.get(i));
17278        }
17279    }
17280
17281    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17282        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17283            ProcessRecord r = mLruProcesses.get(i);
17284            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17285                try {
17286                    r.thread.dispatchPackageBroadcast(cmd, packages);
17287                } catch (RemoteException ex) {
17288                }
17289            }
17290        }
17291    }
17292
17293    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17294            int callingUid, int[] users) {
17295        // TODO: come back and remove this assumption to triage all broadcasts
17296        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17297
17298        List<ResolveInfo> receivers = null;
17299        try {
17300            HashSet<ComponentName> singleUserReceivers = null;
17301            boolean scannedFirstReceivers = false;
17302            for (int user : users) {
17303                // Skip users that have Shell restrictions, with exception of always permitted
17304                // Shell broadcasts
17305                if (callingUid == Process.SHELL_UID
17306                        && mUserController.hasUserRestriction(
17307                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17308                        && !isPermittedShellBroadcast(intent)) {
17309                    continue;
17310                }
17311                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17312                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17313                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17314                    // If this is not the system user, we need to check for
17315                    // any receivers that should be filtered out.
17316                    for (int i=0; i<newReceivers.size(); i++) {
17317                        ResolveInfo ri = newReceivers.get(i);
17318                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17319                            newReceivers.remove(i);
17320                            i--;
17321                        }
17322                    }
17323                }
17324                if (newReceivers != null && newReceivers.size() == 0) {
17325                    newReceivers = null;
17326                }
17327                if (receivers == null) {
17328                    receivers = newReceivers;
17329                } else if (newReceivers != null) {
17330                    // We need to concatenate the additional receivers
17331                    // found with what we have do far.  This would be easy,
17332                    // but we also need to de-dup any receivers that are
17333                    // singleUser.
17334                    if (!scannedFirstReceivers) {
17335                        // Collect any single user receivers we had already retrieved.
17336                        scannedFirstReceivers = true;
17337                        for (int i=0; i<receivers.size(); i++) {
17338                            ResolveInfo ri = receivers.get(i);
17339                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17340                                ComponentName cn = new ComponentName(
17341                                        ri.activityInfo.packageName, ri.activityInfo.name);
17342                                if (singleUserReceivers == null) {
17343                                    singleUserReceivers = new HashSet<ComponentName>();
17344                                }
17345                                singleUserReceivers.add(cn);
17346                            }
17347                        }
17348                    }
17349                    // Add the new results to the existing results, tracking
17350                    // and de-dupping single user receivers.
17351                    for (int i=0; i<newReceivers.size(); i++) {
17352                        ResolveInfo ri = newReceivers.get(i);
17353                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17354                            ComponentName cn = new ComponentName(
17355                                    ri.activityInfo.packageName, ri.activityInfo.name);
17356                            if (singleUserReceivers == null) {
17357                                singleUserReceivers = new HashSet<ComponentName>();
17358                            }
17359                            if (!singleUserReceivers.contains(cn)) {
17360                                singleUserReceivers.add(cn);
17361                                receivers.add(ri);
17362                            }
17363                        } else {
17364                            receivers.add(ri);
17365                        }
17366                    }
17367                }
17368            }
17369        } catch (RemoteException ex) {
17370            // pm is in same process, this will never happen.
17371        }
17372        return receivers;
17373    }
17374
17375    private boolean isPermittedShellBroadcast(Intent intent) {
17376        // remote bugreport should always be allowed to be taken
17377        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17378    }
17379
17380    final int broadcastIntentLocked(ProcessRecord callerApp,
17381            String callerPackage, Intent intent, String resolvedType,
17382            IIntentReceiver resultTo, int resultCode, String resultData,
17383            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17384            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17385        intent = new Intent(intent);
17386
17387        // By default broadcasts do not go to stopped apps.
17388        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17389
17390        // If we have not finished booting, don't allow this to launch new processes.
17391        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17392            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17393        }
17394
17395        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17396                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17397                + " ordered=" + ordered + " userid=" + userId);
17398        if ((resultTo != null) && !ordered) {
17399            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17400        }
17401
17402        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17403                ALLOW_NON_FULL, "broadcast", callerPackage);
17404
17405        // Make sure that the user who is receiving this broadcast is running.
17406        // If not, we will just skip it. Make an exception for shutdown broadcasts
17407        // and upgrade steps.
17408
17409        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17410            if ((callingUid != Process.SYSTEM_UID
17411                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17412                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17413                Slog.w(TAG, "Skipping broadcast of " + intent
17414                        + ": user " + userId + " is stopped");
17415                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17416            }
17417        }
17418
17419        BroadcastOptions brOptions = null;
17420        if (bOptions != null) {
17421            brOptions = new BroadcastOptions(bOptions);
17422            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17423                // See if the caller is allowed to do this.  Note we are checking against
17424                // the actual real caller (not whoever provided the operation as say a
17425                // PendingIntent), because that who is actually supplied the arguments.
17426                if (checkComponentPermission(
17427                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17428                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17429                        != PackageManager.PERMISSION_GRANTED) {
17430                    String msg = "Permission Denial: " + intent.getAction()
17431                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17432                            + ", uid=" + callingUid + ")"
17433                            + " requires "
17434                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17435                    Slog.w(TAG, msg);
17436                    throw new SecurityException(msg);
17437                }
17438            }
17439        }
17440
17441        // Verify that protected broadcasts are only being sent by system code,
17442        // and that system code is only sending protected broadcasts.
17443        final String action = intent.getAction();
17444        final boolean isProtectedBroadcast;
17445        try {
17446            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17447        } catch (RemoteException e) {
17448            Slog.w(TAG, "Remote exception", e);
17449            return ActivityManager.BROADCAST_SUCCESS;
17450        }
17451
17452        final boolean isCallerSystem;
17453        switch (UserHandle.getAppId(callingUid)) {
17454            case Process.ROOT_UID:
17455            case Process.SYSTEM_UID:
17456            case Process.PHONE_UID:
17457            case Process.BLUETOOTH_UID:
17458            case Process.NFC_UID:
17459                isCallerSystem = true;
17460                break;
17461            default:
17462                isCallerSystem = (callerApp != null) && callerApp.persistent;
17463                break;
17464        }
17465
17466        if (isCallerSystem) {
17467            if (isProtectedBroadcast
17468                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17469                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17470                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17471                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17472                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17473                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17474                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17475                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17476                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17477                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17478                // Broadcast is either protected, or it's a public action that
17479                // we've relaxed, so it's fine for system internals to send.
17480            } else {
17481                // The vast majority of broadcasts sent from system internals
17482                // should be protected to avoid security holes, so yell loudly
17483                // to ensure we examine these cases.
17484                if (callerApp != null) {
17485                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17486                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17487                            new Throwable());
17488                } else {
17489                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17490                            + " from system uid " + UserHandle.formatUid(callingUid)
17491                            + " pkg " + callerPackage,
17492                            new Throwable());
17493                }
17494            }
17495
17496        } else {
17497            if (isProtectedBroadcast) {
17498                String msg = "Permission Denial: not allowed to send broadcast "
17499                        + action + " from pid="
17500                        + callingPid + ", uid=" + callingUid;
17501                Slog.w(TAG, msg);
17502                throw new SecurityException(msg);
17503
17504            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17505                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17506                // Special case for compatibility: we don't want apps to send this,
17507                // but historically it has not been protected and apps may be using it
17508                // to poke their own app widget.  So, instead of making it protected,
17509                // just limit it to the caller.
17510                if (callerPackage == null) {
17511                    String msg = "Permission Denial: not allowed to send broadcast "
17512                            + action + " from unknown caller.";
17513                    Slog.w(TAG, msg);
17514                    throw new SecurityException(msg);
17515                } else if (intent.getComponent() != null) {
17516                    // They are good enough to send to an explicit component...  verify
17517                    // it is being sent to the calling app.
17518                    if (!intent.getComponent().getPackageName().equals(
17519                            callerPackage)) {
17520                        String msg = "Permission Denial: not allowed to send broadcast "
17521                                + action + " to "
17522                                + intent.getComponent().getPackageName() + " from "
17523                                + callerPackage;
17524                        Slog.w(TAG, msg);
17525                        throw new SecurityException(msg);
17526                    }
17527                } else {
17528                    // Limit broadcast to their own package.
17529                    intent.setPackage(callerPackage);
17530                }
17531            }
17532        }
17533
17534        if (action != null) {
17535            switch (action) {
17536                case Intent.ACTION_UID_REMOVED:
17537                case Intent.ACTION_PACKAGE_REMOVED:
17538                case Intent.ACTION_PACKAGE_CHANGED:
17539                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17540                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17541                case Intent.ACTION_PACKAGES_SUSPENDED:
17542                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17543                    // Handle special intents: if this broadcast is from the package
17544                    // manager about a package being removed, we need to remove all of
17545                    // its activities from the history stack.
17546                    if (checkComponentPermission(
17547                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17548                            callingPid, callingUid, -1, true)
17549                            != PackageManager.PERMISSION_GRANTED) {
17550                        String msg = "Permission Denial: " + intent.getAction()
17551                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17552                                + ", uid=" + callingUid + ")"
17553                                + " requires "
17554                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17555                        Slog.w(TAG, msg);
17556                        throw new SecurityException(msg);
17557                    }
17558                    switch (action) {
17559                        case Intent.ACTION_UID_REMOVED:
17560                            final Bundle intentExtras = intent.getExtras();
17561                            final int uid = intentExtras != null
17562                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17563                            if (uid >= 0) {
17564                                mBatteryStatsService.removeUid(uid);
17565                                mAppOpsService.uidRemoved(uid);
17566                            }
17567                            break;
17568                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17569                            // If resources are unavailable just force stop all those packages
17570                            // and flush the attribute cache as well.
17571                            String list[] =
17572                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17573                            if (list != null && list.length > 0) {
17574                                for (int i = 0; i < list.length; i++) {
17575                                    forceStopPackageLocked(list[i], -1, false, true, true,
17576                                            false, false, userId, "storage unmount");
17577                                }
17578                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17579                                sendPackageBroadcastLocked(
17580                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17581                                        userId);
17582                            }
17583                            break;
17584                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17585                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17586                            break;
17587                        case Intent.ACTION_PACKAGE_REMOVED:
17588                        case Intent.ACTION_PACKAGE_CHANGED:
17589                            Uri data = intent.getData();
17590                            String ssp;
17591                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17592                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17593                                final boolean replacing =
17594                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17595                                final boolean killProcess =
17596                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17597                                final boolean fullUninstall = removed && !replacing;
17598                                if (removed) {
17599                                    if (killProcess) {
17600                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17601                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17602                                                false, true, true, false, fullUninstall, userId,
17603                                                removed ? "pkg removed" : "pkg changed");
17604                                    }
17605                                    final int cmd = killProcess
17606                                            ? IApplicationThread.PACKAGE_REMOVED
17607                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17608                                    sendPackageBroadcastLocked(cmd,
17609                                            new String[] {ssp}, userId);
17610                                    if (fullUninstall) {
17611                                        mAppOpsService.packageRemoved(
17612                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17613
17614                                        // Remove all permissions granted from/to this package
17615                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17616
17617                                        removeTasksByPackageNameLocked(ssp, userId);
17618                                        mBatteryStatsService.notePackageUninstalled(ssp);
17619                                    }
17620                                } else {
17621                                    if (killProcess) {
17622                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17623                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17624                                                userId, ProcessList.INVALID_ADJ,
17625                                                false, true, true, false, "change " + ssp);
17626                                    }
17627                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17628                                            intent.getStringArrayExtra(
17629                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17630                                }
17631                            }
17632                            break;
17633                        case Intent.ACTION_PACKAGES_SUSPENDED:
17634                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17635                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17636                                    intent.getAction());
17637                            final String[] packageNames = intent.getStringArrayExtra(
17638                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17639                            final int userHandle = intent.getIntExtra(
17640                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17641
17642                            synchronized(ActivityManagerService.this) {
17643                                mRecentTasks.onPackagesSuspendedChanged(
17644                                        packageNames, suspended, userHandle);
17645                            }
17646                            break;
17647                    }
17648                    break;
17649                case Intent.ACTION_PACKAGE_REPLACED:
17650                {
17651                    final Uri data = intent.getData();
17652                    final String ssp;
17653                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17654                        final ApplicationInfo aInfo =
17655                                getPackageManagerInternalLocked().getApplicationInfo(
17656                                        ssp,
17657                                        userId);
17658                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17659                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17660                                new String[] {ssp}, userId);
17661                    }
17662                    break;
17663                }
17664                case Intent.ACTION_PACKAGE_ADDED:
17665                {
17666                    // Special case for adding a package: by default turn on compatibility mode.
17667                    Uri data = intent.getData();
17668                    String ssp;
17669                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17670                        final boolean replacing =
17671                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17672                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17673
17674                        try {
17675                            ApplicationInfo ai = AppGlobals.getPackageManager().
17676                                    getApplicationInfo(ssp, 0, 0);
17677                            mBatteryStatsService.notePackageInstalled(ssp,
17678                                    ai != null ? ai.versionCode : 0);
17679                        } catch (RemoteException e) {
17680                        }
17681                    }
17682                    break;
17683                }
17684                case Intent.ACTION_TIMEZONE_CHANGED:
17685                    // If this is the time zone changed action, queue up a message that will reset
17686                    // the timezone of all currently running processes. This message will get
17687                    // queued up before the broadcast happens.
17688                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17689                    break;
17690                case Intent.ACTION_TIME_CHANGED:
17691                    // If the user set the time, let all running processes know.
17692                    final int is24Hour =
17693                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17694                                    : 0;
17695                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17696                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17697                    synchronized (stats) {
17698                        stats.noteCurrentTimeChangedLocked();
17699                    }
17700                    break;
17701                case Intent.ACTION_CLEAR_DNS_CACHE:
17702                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17703                    break;
17704                case Proxy.PROXY_CHANGE_ACTION:
17705                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17706                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17707                    break;
17708                case android.hardware.Camera.ACTION_NEW_PICTURE:
17709                case android.hardware.Camera.ACTION_NEW_VIDEO:
17710                    // These broadcasts are no longer allowed by the system, since they can
17711                    // cause significant thrashing at a crictical point (using the camera).
17712                    // Apps should use JobScehduler to monitor for media provider changes.
17713                    Slog.w(TAG, action + " no longer allowed; dropping from "
17714                            + UserHandle.formatUid(callingUid));
17715                    // Lie; we don't want to crash the app.
17716                    return ActivityManager.BROADCAST_SUCCESS;
17717            }
17718        }
17719
17720        // Add to the sticky list if requested.
17721        if (sticky) {
17722            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17723                    callingPid, callingUid)
17724                    != PackageManager.PERMISSION_GRANTED) {
17725                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17726                        + callingPid + ", uid=" + callingUid
17727                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17728                Slog.w(TAG, msg);
17729                throw new SecurityException(msg);
17730            }
17731            if (requiredPermissions != null && requiredPermissions.length > 0) {
17732                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17733                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17734                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17735            }
17736            if (intent.getComponent() != null) {
17737                throw new SecurityException(
17738                        "Sticky broadcasts can't target a specific component");
17739            }
17740            // We use userId directly here, since the "all" target is maintained
17741            // as a separate set of sticky broadcasts.
17742            if (userId != UserHandle.USER_ALL) {
17743                // But first, if this is not a broadcast to all users, then
17744                // make sure it doesn't conflict with an existing broadcast to
17745                // all users.
17746                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17747                        UserHandle.USER_ALL);
17748                if (stickies != null) {
17749                    ArrayList<Intent> list = stickies.get(intent.getAction());
17750                    if (list != null) {
17751                        int N = list.size();
17752                        int i;
17753                        for (i=0; i<N; i++) {
17754                            if (intent.filterEquals(list.get(i))) {
17755                                throw new IllegalArgumentException(
17756                                        "Sticky broadcast " + intent + " for user "
17757                                        + userId + " conflicts with existing global broadcast");
17758                            }
17759                        }
17760                    }
17761                }
17762            }
17763            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17764            if (stickies == null) {
17765                stickies = new ArrayMap<>();
17766                mStickyBroadcasts.put(userId, stickies);
17767            }
17768            ArrayList<Intent> list = stickies.get(intent.getAction());
17769            if (list == null) {
17770                list = new ArrayList<>();
17771                stickies.put(intent.getAction(), list);
17772            }
17773            final int stickiesCount = list.size();
17774            int i;
17775            for (i = 0; i < stickiesCount; i++) {
17776                if (intent.filterEquals(list.get(i))) {
17777                    // This sticky already exists, replace it.
17778                    list.set(i, new Intent(intent));
17779                    break;
17780                }
17781            }
17782            if (i >= stickiesCount) {
17783                list.add(new Intent(intent));
17784            }
17785        }
17786
17787        int[] users;
17788        if (userId == UserHandle.USER_ALL) {
17789            // Caller wants broadcast to go to all started users.
17790            users = mUserController.getStartedUserArrayLocked();
17791        } else {
17792            // Caller wants broadcast to go to one specific user.
17793            users = new int[] {userId};
17794        }
17795
17796        // Figure out who all will receive this broadcast.
17797        List receivers = null;
17798        List<BroadcastFilter> registeredReceivers = null;
17799        // Need to resolve the intent to interested receivers...
17800        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17801                 == 0) {
17802            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17803        }
17804        if (intent.getComponent() == null) {
17805            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17806                // Query one target user at a time, excluding shell-restricted users
17807                for (int i = 0; i < users.length; i++) {
17808                    if (mUserController.hasUserRestriction(
17809                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17810                        continue;
17811                    }
17812                    List<BroadcastFilter> registeredReceiversForUser =
17813                            mReceiverResolver.queryIntent(intent,
17814                                    resolvedType, false, users[i]);
17815                    if (registeredReceivers == null) {
17816                        registeredReceivers = registeredReceiversForUser;
17817                    } else if (registeredReceiversForUser != null) {
17818                        registeredReceivers.addAll(registeredReceiversForUser);
17819                    }
17820                }
17821            } else {
17822                registeredReceivers = mReceiverResolver.queryIntent(intent,
17823                        resolvedType, false, userId);
17824            }
17825        }
17826
17827        final boolean replacePending =
17828                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17829
17830        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17831                + " replacePending=" + replacePending);
17832
17833        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17834        if (!ordered && NR > 0) {
17835            // If we are not serializing this broadcast, then send the
17836            // registered receivers separately so they don't wait for the
17837            // components to be launched.
17838            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17839            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17840                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17841                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17842                    resultExtras, ordered, sticky, false, userId);
17843            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17844            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17845            if (!replaced) {
17846                queue.enqueueParallelBroadcastLocked(r);
17847                queue.scheduleBroadcastsLocked();
17848            }
17849            registeredReceivers = null;
17850            NR = 0;
17851        }
17852
17853        // Merge into one list.
17854        int ir = 0;
17855        if (receivers != null) {
17856            // A special case for PACKAGE_ADDED: do not allow the package
17857            // being added to see this broadcast.  This prevents them from
17858            // using this as a back door to get run as soon as they are
17859            // installed.  Maybe in the future we want to have a special install
17860            // broadcast or such for apps, but we'd like to deliberately make
17861            // this decision.
17862            String skipPackages[] = null;
17863            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17864                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17865                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17866                Uri data = intent.getData();
17867                if (data != null) {
17868                    String pkgName = data.getSchemeSpecificPart();
17869                    if (pkgName != null) {
17870                        skipPackages = new String[] { pkgName };
17871                    }
17872                }
17873            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17874                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17875            }
17876            if (skipPackages != null && (skipPackages.length > 0)) {
17877                for (String skipPackage : skipPackages) {
17878                    if (skipPackage != null) {
17879                        int NT = receivers.size();
17880                        for (int it=0; it<NT; it++) {
17881                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17882                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17883                                receivers.remove(it);
17884                                it--;
17885                                NT--;
17886                            }
17887                        }
17888                    }
17889                }
17890            }
17891
17892            int NT = receivers != null ? receivers.size() : 0;
17893            int it = 0;
17894            ResolveInfo curt = null;
17895            BroadcastFilter curr = null;
17896            while (it < NT && ir < NR) {
17897                if (curt == null) {
17898                    curt = (ResolveInfo)receivers.get(it);
17899                }
17900                if (curr == null) {
17901                    curr = registeredReceivers.get(ir);
17902                }
17903                if (curr.getPriority() >= curt.priority) {
17904                    // Insert this broadcast record into the final list.
17905                    receivers.add(it, curr);
17906                    ir++;
17907                    curr = null;
17908                    it++;
17909                    NT++;
17910                } else {
17911                    // Skip to the next ResolveInfo in the final list.
17912                    it++;
17913                    curt = null;
17914                }
17915            }
17916        }
17917        while (ir < NR) {
17918            if (receivers == null) {
17919                receivers = new ArrayList();
17920            }
17921            receivers.add(registeredReceivers.get(ir));
17922            ir++;
17923        }
17924
17925        if ((receivers != null && receivers.size() > 0)
17926                || resultTo != null) {
17927            BroadcastQueue queue = broadcastQueueForIntent(intent);
17928            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17929                    callerPackage, callingPid, callingUid, resolvedType,
17930                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17931                    resultData, resultExtras, ordered, sticky, false, userId);
17932
17933            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17934                    + ": prev had " + queue.mOrderedBroadcasts.size());
17935            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17936                    "Enqueueing broadcast " + r.intent.getAction());
17937
17938            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17939            if (!replaced) {
17940                queue.enqueueOrderedBroadcastLocked(r);
17941                queue.scheduleBroadcastsLocked();
17942            }
17943        }
17944
17945        return ActivityManager.BROADCAST_SUCCESS;
17946    }
17947
17948    final Intent verifyBroadcastLocked(Intent intent) {
17949        // Refuse possible leaked file descriptors
17950        if (intent != null && intent.hasFileDescriptors() == true) {
17951            throw new IllegalArgumentException("File descriptors passed in Intent");
17952        }
17953
17954        int flags = intent.getFlags();
17955
17956        if (!mProcessesReady) {
17957            // if the caller really truly claims to know what they're doing, go
17958            // ahead and allow the broadcast without launching any receivers
17959            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17960                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17961            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17962                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17963                        + " before boot completion");
17964                throw new IllegalStateException("Cannot broadcast before boot completed");
17965            }
17966        }
17967
17968        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17969            throw new IllegalArgumentException(
17970                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17971        }
17972
17973        return intent;
17974    }
17975
17976    public final int broadcastIntent(IApplicationThread caller,
17977            Intent intent, String resolvedType, IIntentReceiver resultTo,
17978            int resultCode, String resultData, Bundle resultExtras,
17979            String[] requiredPermissions, int appOp, Bundle bOptions,
17980            boolean serialized, boolean sticky, int userId) {
17981        enforceNotIsolatedCaller("broadcastIntent");
17982        synchronized(this) {
17983            intent = verifyBroadcastLocked(intent);
17984
17985            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17986            final int callingPid = Binder.getCallingPid();
17987            final int callingUid = Binder.getCallingUid();
17988            final long origId = Binder.clearCallingIdentity();
17989            int res = broadcastIntentLocked(callerApp,
17990                    callerApp != null ? callerApp.info.packageName : null,
17991                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17992                    requiredPermissions, appOp, bOptions, serialized, sticky,
17993                    callingPid, callingUid, userId);
17994            Binder.restoreCallingIdentity(origId);
17995            return res;
17996        }
17997    }
17998
17999
18000    int broadcastIntentInPackage(String packageName, int uid,
18001            Intent intent, String resolvedType, IIntentReceiver resultTo,
18002            int resultCode, String resultData, Bundle resultExtras,
18003            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18004            int userId) {
18005        synchronized(this) {
18006            intent = verifyBroadcastLocked(intent);
18007
18008            final long origId = Binder.clearCallingIdentity();
18009            String[] requiredPermissions = requiredPermission == null ? null
18010                    : new String[] {requiredPermission};
18011            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18012                    resultTo, resultCode, resultData, resultExtras,
18013                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18014                    sticky, -1, uid, userId);
18015            Binder.restoreCallingIdentity(origId);
18016            return res;
18017        }
18018    }
18019
18020    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18021        // Refuse possible leaked file descriptors
18022        if (intent != null && intent.hasFileDescriptors() == true) {
18023            throw new IllegalArgumentException("File descriptors passed in Intent");
18024        }
18025
18026        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18027                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18028
18029        synchronized(this) {
18030            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18031                    != PackageManager.PERMISSION_GRANTED) {
18032                String msg = "Permission Denial: unbroadcastIntent() from pid="
18033                        + Binder.getCallingPid()
18034                        + ", uid=" + Binder.getCallingUid()
18035                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18036                Slog.w(TAG, msg);
18037                throw new SecurityException(msg);
18038            }
18039            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18040            if (stickies != null) {
18041                ArrayList<Intent> list = stickies.get(intent.getAction());
18042                if (list != null) {
18043                    int N = list.size();
18044                    int i;
18045                    for (i=0; i<N; i++) {
18046                        if (intent.filterEquals(list.get(i))) {
18047                            list.remove(i);
18048                            break;
18049                        }
18050                    }
18051                    if (list.size() <= 0) {
18052                        stickies.remove(intent.getAction());
18053                    }
18054                }
18055                if (stickies.size() <= 0) {
18056                    mStickyBroadcasts.remove(userId);
18057                }
18058            }
18059        }
18060    }
18061
18062    void backgroundServicesFinishedLocked(int userId) {
18063        for (BroadcastQueue queue : mBroadcastQueues) {
18064            queue.backgroundServicesFinishedLocked(userId);
18065        }
18066    }
18067
18068    public void finishReceiver(IBinder who, int resultCode, String resultData,
18069            Bundle resultExtras, boolean resultAbort, int flags) {
18070        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18071
18072        // Refuse possible leaked file descriptors
18073        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18074            throw new IllegalArgumentException("File descriptors passed in Bundle");
18075        }
18076
18077        final long origId = Binder.clearCallingIdentity();
18078        try {
18079            boolean doNext = false;
18080            BroadcastRecord r;
18081
18082            synchronized(this) {
18083                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18084                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18085                r = queue.getMatchingOrderedReceiver(who);
18086                if (r != null) {
18087                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18088                        resultData, resultExtras, resultAbort, true);
18089                }
18090            }
18091
18092            if (doNext) {
18093                r.queue.processNextBroadcast(false);
18094            }
18095            trimApplications();
18096        } finally {
18097            Binder.restoreCallingIdentity(origId);
18098        }
18099    }
18100
18101    // =========================================================
18102    // INSTRUMENTATION
18103    // =========================================================
18104
18105    public boolean startInstrumentation(ComponentName className,
18106            String profileFile, int flags, Bundle arguments,
18107            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18108            int userId, String abiOverride) {
18109        enforceNotIsolatedCaller("startInstrumentation");
18110        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18111                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18112        // Refuse possible leaked file descriptors
18113        if (arguments != null && arguments.hasFileDescriptors()) {
18114            throw new IllegalArgumentException("File descriptors passed in Bundle");
18115        }
18116
18117        synchronized(this) {
18118            InstrumentationInfo ii = null;
18119            ApplicationInfo ai = null;
18120            try {
18121                ii = mContext.getPackageManager().getInstrumentationInfo(
18122                    className, STOCK_PM_FLAGS);
18123                ai = AppGlobals.getPackageManager().getApplicationInfo(
18124                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18125            } catch (PackageManager.NameNotFoundException e) {
18126            } catch (RemoteException e) {
18127            }
18128            if (ii == null) {
18129                reportStartInstrumentationFailureLocked(watcher, className,
18130                        "Unable to find instrumentation info for: " + className);
18131                return false;
18132            }
18133            if (ai == null) {
18134                reportStartInstrumentationFailureLocked(watcher, className,
18135                        "Unable to find instrumentation target package: " + ii.targetPackage);
18136                return false;
18137            }
18138            if (!ai.hasCode()) {
18139                reportStartInstrumentationFailureLocked(watcher, className,
18140                        "Instrumentation target has no code: " + ii.targetPackage);
18141                return false;
18142            }
18143
18144            int match = mContext.getPackageManager().checkSignatures(
18145                    ii.targetPackage, ii.packageName);
18146            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18147                String msg = "Permission Denial: starting instrumentation "
18148                        + className + " from pid="
18149                        + Binder.getCallingPid()
18150                        + ", uid=" + Binder.getCallingPid()
18151                        + " not allowed because package " + ii.packageName
18152                        + " does not have a signature matching the target "
18153                        + ii.targetPackage;
18154                reportStartInstrumentationFailureLocked(watcher, className, msg);
18155                throw new SecurityException(msg);
18156            }
18157
18158            final long origId = Binder.clearCallingIdentity();
18159            // Instrumentation can kill and relaunch even persistent processes
18160            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18161                    "start instr");
18162            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18163            app.instrumentationClass = className;
18164            app.instrumentationInfo = ai;
18165            app.instrumentationProfileFile = profileFile;
18166            app.instrumentationArguments = arguments;
18167            app.instrumentationWatcher = watcher;
18168            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18169            app.instrumentationResultClass = className;
18170            Binder.restoreCallingIdentity(origId);
18171        }
18172
18173        return true;
18174    }
18175
18176    /**
18177     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18178     * error to the logs, but if somebody is watching, send the report there too.  This enables
18179     * the "am" command to report errors with more information.
18180     *
18181     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18182     * @param cn The component name of the instrumentation.
18183     * @param report The error report.
18184     */
18185    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18186            ComponentName cn, String report) {
18187        Slog.w(TAG, report);
18188        if (watcher != null) {
18189            Bundle results = new Bundle();
18190            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18191            results.putString("Error", report);
18192            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18193        }
18194    }
18195
18196    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18197        if (app.instrumentationWatcher != null) {
18198            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18199                    app.instrumentationClass, resultCode, results);
18200        }
18201
18202        // Can't call out of the system process with a lock held, so post a message.
18203        if (app.instrumentationUiAutomationConnection != null) {
18204            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18205                    app.instrumentationUiAutomationConnection).sendToTarget();
18206        }
18207
18208        app.instrumentationWatcher = null;
18209        app.instrumentationUiAutomationConnection = null;
18210        app.instrumentationClass = null;
18211        app.instrumentationInfo = null;
18212        app.instrumentationProfileFile = null;
18213        app.instrumentationArguments = null;
18214
18215        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18216                "finished inst");
18217    }
18218
18219    public void finishInstrumentation(IApplicationThread target,
18220            int resultCode, Bundle results) {
18221        int userId = UserHandle.getCallingUserId();
18222        // Refuse possible leaked file descriptors
18223        if (results != null && results.hasFileDescriptors()) {
18224            throw new IllegalArgumentException("File descriptors passed in Intent");
18225        }
18226
18227        synchronized(this) {
18228            ProcessRecord app = getRecordForAppLocked(target);
18229            if (app == null) {
18230                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18231                return;
18232            }
18233            final long origId = Binder.clearCallingIdentity();
18234            finishInstrumentationLocked(app, resultCode, results);
18235            Binder.restoreCallingIdentity(origId);
18236        }
18237    }
18238
18239    // =========================================================
18240    // CONFIGURATION
18241    // =========================================================
18242
18243    public ConfigurationInfo getDeviceConfigurationInfo() {
18244        ConfigurationInfo config = new ConfigurationInfo();
18245        synchronized (this) {
18246            config.reqTouchScreen = mConfiguration.touchscreen;
18247            config.reqKeyboardType = mConfiguration.keyboard;
18248            config.reqNavigation = mConfiguration.navigation;
18249            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18250                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18251                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18252            }
18253            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18254                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18255                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18256            }
18257            config.reqGlEsVersion = GL_ES_VERSION;
18258        }
18259        return config;
18260    }
18261
18262    ActivityStack getFocusedStack() {
18263        return mStackSupervisor.getFocusedStack();
18264    }
18265
18266    @Override
18267    public int getFocusedStackId() throws RemoteException {
18268        ActivityStack focusedStack = getFocusedStack();
18269        if (focusedStack != null) {
18270            return focusedStack.getStackId();
18271        }
18272        return -1;
18273    }
18274
18275    public Configuration getConfiguration() {
18276        Configuration ci;
18277        synchronized(this) {
18278            ci = new Configuration(mConfiguration);
18279            ci.userSetLocale = false;
18280        }
18281        return ci;
18282    }
18283
18284    @Override
18285    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18286        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18287        synchronized (this) {
18288            mSuppressResizeConfigChanges = suppress;
18289        }
18290    }
18291
18292    @Override
18293    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18294        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18295        if (fromStackId == HOME_STACK_ID) {
18296            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18297        }
18298        synchronized (this) {
18299            final long origId = Binder.clearCallingIdentity();
18300            try {
18301                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18302            } finally {
18303                Binder.restoreCallingIdentity(origId);
18304            }
18305        }
18306    }
18307
18308    @Override
18309    public void updatePersistentConfiguration(Configuration values) {
18310        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18311                "updateConfiguration()");
18312        enforceWriteSettingsPermission("updateConfiguration()");
18313        if (values == null) {
18314            throw new NullPointerException("Configuration must not be null");
18315        }
18316
18317        int userId = UserHandle.getCallingUserId();
18318
18319        synchronized(this) {
18320            final long origId = Binder.clearCallingIdentity();
18321            updateConfigurationLocked(values, null, false, true, userId);
18322            Binder.restoreCallingIdentity(origId);
18323        }
18324    }
18325
18326    private void updateFontScaleIfNeeded() {
18327        final int currentUserId;
18328        synchronized(this) {
18329            currentUserId = mUserController.getCurrentUserIdLocked();
18330        }
18331        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18332                FONT_SCALE, 1.0f, currentUserId);
18333        if (mConfiguration.fontScale != scaleFactor) {
18334            final Configuration configuration = mWindowManager.computeNewConfiguration();
18335            configuration.fontScale = scaleFactor;
18336            updatePersistentConfiguration(configuration);
18337        }
18338    }
18339
18340    private void enforceWriteSettingsPermission(String func) {
18341        int uid = Binder.getCallingUid();
18342        if (uid == Process.ROOT_UID) {
18343            return;
18344        }
18345
18346        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18347                Settings.getPackageNameForUid(mContext, uid), false)) {
18348            return;
18349        }
18350
18351        String msg = "Permission Denial: " + func + " from pid="
18352                + Binder.getCallingPid()
18353                + ", uid=" + uid
18354                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18355        Slog.w(TAG, msg);
18356        throw new SecurityException(msg);
18357    }
18358
18359    public void updateConfiguration(Configuration values) {
18360        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18361                "updateConfiguration()");
18362
18363        synchronized(this) {
18364            if (values == null && mWindowManager != null) {
18365                // sentinel: fetch the current configuration from the window manager
18366                values = mWindowManager.computeNewConfiguration();
18367            }
18368
18369            if (mWindowManager != null) {
18370                mProcessList.applyDisplaySize(mWindowManager);
18371            }
18372
18373            final long origId = Binder.clearCallingIdentity();
18374            if (values != null) {
18375                Settings.System.clearConfiguration(values);
18376            }
18377            updateConfigurationLocked(values, null, false);
18378            Binder.restoreCallingIdentity(origId);
18379        }
18380    }
18381
18382    void updateUserConfigurationLocked() {
18383        Configuration configuration = new Configuration(mConfiguration);
18384        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18385                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18386        updateConfigurationLocked(configuration, null, false);
18387    }
18388
18389    boolean updateConfigurationLocked(Configuration values,
18390            ActivityRecord starting, boolean initLocale) {
18391        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18392        return updateConfigurationLocked(values, starting, initLocale, false,
18393                UserHandle.USER_NULL);
18394    }
18395
18396    // To cache the list of supported system locales
18397    private String[] mSupportedSystemLocales = null;
18398
18399    /**
18400     * Do either or both things: (1) change the current configuration, and (2)
18401     * make sure the given activity is running with the (now) current
18402     * configuration.  Returns true if the activity has been left running, or
18403     * false if <var>starting</var> is being destroyed to match the new
18404     * configuration.
18405     *
18406     * @param userId is only used when persistent parameter is set to true to persist configuration
18407     *               for that particular user
18408     */
18409    private boolean updateConfigurationLocked(Configuration values,
18410            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18411        int changes = 0;
18412
18413        if (mWindowManager != null) {
18414            mWindowManager.deferSurfaceLayout();
18415        }
18416        if (values != null) {
18417            Configuration newConfig = new Configuration(mConfiguration);
18418            changes = newConfig.updateFrom(values);
18419            if (changes != 0) {
18420                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18421                        "Updating configuration to: " + values);
18422
18423                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18424
18425                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18426                    final LocaleList locales = values.getLocales();
18427                    int bestLocaleIndex = 0;
18428                    if (locales.size() > 1) {
18429                        if (mSupportedSystemLocales == null) {
18430                            mSupportedSystemLocales =
18431                                    Resources.getSystem().getAssets().getLocales();
18432                        }
18433                        bestLocaleIndex = Math.max(0,
18434                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18435                    }
18436                    SystemProperties.set("persist.sys.locale",
18437                            locales.get(bestLocaleIndex).toLanguageTag());
18438                    LocaleList.setDefault(locales, bestLocaleIndex);
18439                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18440                            locales.get(bestLocaleIndex)));
18441                }
18442
18443                mConfigurationSeq++;
18444                if (mConfigurationSeq <= 0) {
18445                    mConfigurationSeq = 1;
18446                }
18447                newConfig.seq = mConfigurationSeq;
18448                mConfiguration = newConfig;
18449                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18450                mUsageStatsService.reportConfigurationChange(newConfig,
18451                        mUserController.getCurrentUserIdLocked());
18452                //mUsageStatsService.noteStartConfig(newConfig);
18453
18454                final Configuration configCopy = new Configuration(mConfiguration);
18455
18456                // TODO: If our config changes, should we auto dismiss any currently
18457                // showing dialogs?
18458                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18459
18460                AttributeCache ac = AttributeCache.instance();
18461                if (ac != null) {
18462                    ac.updateConfiguration(configCopy);
18463                }
18464
18465                // Make sure all resources in our process are updated
18466                // right now, so that anyone who is going to retrieve
18467                // resource values after we return will be sure to get
18468                // the new ones.  This is especially important during
18469                // boot, where the first config change needs to guarantee
18470                // all resources have that config before following boot
18471                // code is executed.
18472                mSystemThread.applyConfigurationToResources(configCopy);
18473
18474                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18475                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18476                    msg.obj = new Configuration(configCopy);
18477                    msg.arg1 = userId;
18478                    mHandler.sendMessage(msg);
18479                }
18480
18481                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18482                if (isDensityChange) {
18483                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18484                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18485                }
18486
18487                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18488                    ProcessRecord app = mLruProcesses.get(i);
18489                    try {
18490                        if (app.thread != null) {
18491                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18492                                    + app.processName + " new config " + mConfiguration);
18493                            app.thread.scheduleConfigurationChanged(configCopy);
18494                        }
18495                    } catch (Exception e) {
18496                    }
18497                }
18498                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18499                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18500                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18501                        | Intent.FLAG_RECEIVER_FOREGROUND);
18502                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18503                        null, AppOpsManager.OP_NONE, null, false, false,
18504                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18505                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18506                    // Tell the shortcut manager that the system locale changed.  It needs to know
18507                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18508                    // we "push" from here, rather than having the service listen to the broadcast.
18509                    final ShortcutServiceInternal shortcutService =
18510                            LocalServices.getService(ShortcutServiceInternal.class);
18511                    if (shortcutService != null) {
18512                        shortcutService.onSystemLocaleChangedNoLock();
18513                    }
18514
18515                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18516                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18517                    if (!mProcessesReady) {
18518                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18519                    }
18520                    broadcastIntentLocked(null, null, intent,
18521                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18522                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18523                }
18524            }
18525            // Update the configuration with WM first and check if any of the stacks need to be
18526            // resized due to the configuration change. If so, resize the stacks now and do any
18527            // relaunches if necessary. This way we don't need to relaunch again below in
18528            // ensureActivityConfigurationLocked().
18529            if (mWindowManager != null) {
18530                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18531                if (resizedStacks != null) {
18532                    for (int stackId : resizedStacks) {
18533                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18534                        mStackSupervisor.resizeStackLocked(
18535                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18536                    }
18537                }
18538            }
18539        }
18540
18541        boolean kept = true;
18542        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18543        // mainStack is null during startup.
18544        if (mainStack != null) {
18545            if (changes != 0 && starting == null) {
18546                // If the configuration changed, and the caller is not already
18547                // in the process of starting an activity, then find the top
18548                // activity to check if its configuration needs to change.
18549                starting = mainStack.topRunningActivityLocked();
18550            }
18551
18552            if (starting != null) {
18553                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18554                // And we need to make sure at this point that all other activities
18555                // are made visible with the correct configuration.
18556                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18557                        !PRESERVE_WINDOWS);
18558            }
18559        }
18560        if (mWindowManager != null) {
18561            mWindowManager.continueSurfaceLayout();
18562        }
18563        return kept;
18564    }
18565
18566    /**
18567     * Decide based on the configuration whether we should shouw the ANR,
18568     * crash, etc dialogs.  The idea is that if there is no affordnace to
18569     * press the on-screen buttons, we shouldn't show the dialog.
18570     *
18571     * A thought: SystemUI might also want to get told about this, the Power
18572     * dialog / global actions also might want different behaviors.
18573     */
18574    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18575        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18576                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18577                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18578        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18579                                    == Configuration.UI_MODE_TYPE_CAR);
18580        return inputMethodExists && uiIsNotCarType && !inVrMode;
18581    }
18582
18583    @Override
18584    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18585        synchronized (this) {
18586            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18587            if (srec != null) {
18588                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18589            }
18590        }
18591        return false;
18592    }
18593
18594    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18595            Intent resultData) {
18596
18597        synchronized (this) {
18598            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18599            if (r != null) {
18600                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18601            }
18602            return false;
18603        }
18604    }
18605
18606    public int getLaunchedFromUid(IBinder activityToken) {
18607        ActivityRecord srec;
18608        synchronized (this) {
18609            srec = ActivityRecord.forTokenLocked(activityToken);
18610        }
18611        if (srec == null) {
18612            return -1;
18613        }
18614        return srec.launchedFromUid;
18615    }
18616
18617    public String getLaunchedFromPackage(IBinder activityToken) {
18618        ActivityRecord srec;
18619        synchronized (this) {
18620            srec = ActivityRecord.forTokenLocked(activityToken);
18621        }
18622        if (srec == null) {
18623            return null;
18624        }
18625        return srec.launchedFromPackage;
18626    }
18627
18628    // =========================================================
18629    // LIFETIME MANAGEMENT
18630    // =========================================================
18631
18632    // Returns which broadcast queue the app is the current [or imminent] receiver
18633    // on, or 'null' if the app is not an active broadcast recipient.
18634    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18635        BroadcastRecord r = app.curReceiver;
18636        if (r != null) {
18637            return r.queue;
18638        }
18639
18640        // It's not the current receiver, but it might be starting up to become one
18641        synchronized (this) {
18642            for (BroadcastQueue queue : mBroadcastQueues) {
18643                r = queue.mPendingBroadcast;
18644                if (r != null && r.curApp == app) {
18645                    // found it; report which queue it's in
18646                    return queue;
18647                }
18648            }
18649        }
18650
18651        return null;
18652    }
18653
18654    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18655            int targetUid, ComponentName targetComponent, String targetProcess) {
18656        if (!mTrackingAssociations) {
18657            return null;
18658        }
18659        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18660                = mAssociations.get(targetUid);
18661        if (components == null) {
18662            components = new ArrayMap<>();
18663            mAssociations.put(targetUid, components);
18664        }
18665        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18666        if (sourceUids == null) {
18667            sourceUids = new SparseArray<>();
18668            components.put(targetComponent, sourceUids);
18669        }
18670        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18671        if (sourceProcesses == null) {
18672            sourceProcesses = new ArrayMap<>();
18673            sourceUids.put(sourceUid, sourceProcesses);
18674        }
18675        Association ass = sourceProcesses.get(sourceProcess);
18676        if (ass == null) {
18677            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18678                    targetProcess);
18679            sourceProcesses.put(sourceProcess, ass);
18680        }
18681        ass.mCount++;
18682        ass.mNesting++;
18683        if (ass.mNesting == 1) {
18684            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18685            ass.mLastState = sourceState;
18686        }
18687        return ass;
18688    }
18689
18690    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18691            ComponentName targetComponent) {
18692        if (!mTrackingAssociations) {
18693            return;
18694        }
18695        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18696                = mAssociations.get(targetUid);
18697        if (components == null) {
18698            return;
18699        }
18700        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18701        if (sourceUids == null) {
18702            return;
18703        }
18704        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18705        if (sourceProcesses == null) {
18706            return;
18707        }
18708        Association ass = sourceProcesses.get(sourceProcess);
18709        if (ass == null || ass.mNesting <= 0) {
18710            return;
18711        }
18712        ass.mNesting--;
18713        if (ass.mNesting == 0) {
18714            long uptime = SystemClock.uptimeMillis();
18715            ass.mTime += uptime - ass.mStartTime;
18716            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18717                    += uptime - ass.mLastStateUptime;
18718            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18719        }
18720    }
18721
18722    private void noteUidProcessState(final int uid, final int state) {
18723        mBatteryStatsService.noteUidProcessState(uid, state);
18724        if (mTrackingAssociations) {
18725            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18726                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18727                        = mAssociations.valueAt(i1);
18728                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18729                    SparseArray<ArrayMap<String, Association>> sourceUids
18730                            = targetComponents.valueAt(i2);
18731                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18732                    if (sourceProcesses != null) {
18733                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18734                            Association ass = sourceProcesses.valueAt(i4);
18735                            if (ass.mNesting >= 1) {
18736                                // currently associated
18737                                long uptime = SystemClock.uptimeMillis();
18738                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18739                                        += uptime - ass.mLastStateUptime;
18740                                ass.mLastState = state;
18741                                ass.mLastStateUptime = uptime;
18742                            }
18743                        }
18744                    }
18745                }
18746            }
18747        }
18748    }
18749
18750    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18751            boolean doingAll, long now) {
18752        if (mAdjSeq == app.adjSeq) {
18753            // This adjustment has already been computed.
18754            return app.curRawAdj;
18755        }
18756
18757        if (app.thread == null) {
18758            app.adjSeq = mAdjSeq;
18759            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18760            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18761            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18762        }
18763
18764        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18765        app.adjSource = null;
18766        app.adjTarget = null;
18767        app.empty = false;
18768        app.cached = false;
18769
18770        final int activitiesSize = app.activities.size();
18771
18772        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18773            // The max adjustment doesn't allow this app to be anything
18774            // below foreground, so it is not worth doing work for it.
18775            app.adjType = "fixed";
18776            app.adjSeq = mAdjSeq;
18777            app.curRawAdj = app.maxAdj;
18778            app.foregroundActivities = false;
18779            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18780            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18781            // System processes can do UI, and when they do we want to have
18782            // them trim their memory after the user leaves the UI.  To
18783            // facilitate this, here we need to determine whether or not it
18784            // is currently showing UI.
18785            app.systemNoUi = true;
18786            if (app == TOP_APP) {
18787                app.systemNoUi = false;
18788                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18789                app.adjType = "pers-top-activity";
18790            } else if (activitiesSize > 0) {
18791                for (int j = 0; j < activitiesSize; j++) {
18792                    final ActivityRecord r = app.activities.get(j);
18793                    if (r.visible) {
18794                        app.systemNoUi = false;
18795                    }
18796                }
18797            }
18798            if (!app.systemNoUi) {
18799                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18800            }
18801            return (app.curAdj=app.maxAdj);
18802        }
18803
18804        app.systemNoUi = false;
18805
18806        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18807
18808        // Determine the importance of the process, starting with most
18809        // important to least, and assign an appropriate OOM adjustment.
18810        int adj;
18811        int schedGroup;
18812        int procState;
18813        boolean foregroundActivities = false;
18814        BroadcastQueue queue;
18815        if (app == TOP_APP) {
18816            // The last app on the list is the foreground app.
18817            adj = ProcessList.FOREGROUND_APP_ADJ;
18818            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18819            app.adjType = "top-activity";
18820            foregroundActivities = true;
18821            procState = PROCESS_STATE_CUR_TOP;
18822        } else if (app.instrumentationClass != null) {
18823            // Don't want to kill running instrumentation.
18824            adj = ProcessList.FOREGROUND_APP_ADJ;
18825            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18826            app.adjType = "instrumentation";
18827            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18828        } else if ((queue = isReceivingBroadcast(app)) != null) {
18829            // An app that is currently receiving a broadcast also
18830            // counts as being in the foreground for OOM killer purposes.
18831            // It's placed in a sched group based on the nature of the
18832            // broadcast as reflected by which queue it's active in.
18833            adj = ProcessList.FOREGROUND_APP_ADJ;
18834            schedGroup = (queue == mFgBroadcastQueue)
18835                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18836            app.adjType = "broadcast";
18837            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18838        } else if (app.executingServices.size() > 0) {
18839            // An app that is currently executing a service callback also
18840            // counts as being in the foreground.
18841            adj = ProcessList.FOREGROUND_APP_ADJ;
18842            schedGroup = app.execServicesFg ?
18843                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18844            app.adjType = "exec-service";
18845            procState = ActivityManager.PROCESS_STATE_SERVICE;
18846            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18847        } else {
18848            // As far as we know the process is empty.  We may change our mind later.
18849            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18850            // At this point we don't actually know the adjustment.  Use the cached adj
18851            // value that the caller wants us to.
18852            adj = cachedAdj;
18853            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18854            app.cached = true;
18855            app.empty = true;
18856            app.adjType = "cch-empty";
18857        }
18858
18859        // Examine all activities if not already foreground.
18860        if (!foregroundActivities && activitiesSize > 0) {
18861            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18862            for (int j = 0; j < activitiesSize; j++) {
18863                final ActivityRecord r = app.activities.get(j);
18864                if (r.app != app) {
18865                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
18866                            + " instead of expected " + app);
18867                    if (r.app == null || (r.app.uid == app.uid)) {
18868                        // Only fix things up when they look sane
18869                        r.app = app;
18870                    } else {
18871                        continue;
18872                    }
18873                }
18874                if (r.visible) {
18875                    // App has a visible activity; only upgrade adjustment.
18876                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18877                        adj = ProcessList.VISIBLE_APP_ADJ;
18878                        app.adjType = "visible";
18879                    }
18880                    if (procState > PROCESS_STATE_CUR_TOP) {
18881                        procState = PROCESS_STATE_CUR_TOP;
18882                    }
18883                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18884                    app.cached = false;
18885                    app.empty = false;
18886                    foregroundActivities = true;
18887                    if (r.task != null && minLayer > 0) {
18888                        final int layer = r.task.mLayerRank;
18889                        if (layer >= 0 && minLayer > layer) {
18890                            minLayer = layer;
18891                        }
18892                    }
18893                    break;
18894                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18895                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18896                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18897                        app.adjType = "pausing";
18898                    }
18899                    if (procState > PROCESS_STATE_CUR_TOP) {
18900                        procState = PROCESS_STATE_CUR_TOP;
18901                    }
18902                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18903                    app.cached = false;
18904                    app.empty = false;
18905                    foregroundActivities = true;
18906                } else if (r.state == ActivityState.STOPPING) {
18907                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18908                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18909                        app.adjType = "stopping";
18910                    }
18911                    // For the process state, we will at this point consider the
18912                    // process to be cached.  It will be cached either as an activity
18913                    // or empty depending on whether the activity is finishing.  We do
18914                    // this so that we can treat the process as cached for purposes of
18915                    // memory trimming (determing current memory level, trim command to
18916                    // send to process) since there can be an arbitrary number of stopping
18917                    // processes and they should soon all go into the cached state.
18918                    if (!r.finishing) {
18919                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18920                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18921                        }
18922                    }
18923                    app.cached = false;
18924                    app.empty = false;
18925                    foregroundActivities = true;
18926                } else {
18927                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18928                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18929                        app.adjType = "cch-act";
18930                    }
18931                }
18932            }
18933            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18934                adj += minLayer;
18935            }
18936        }
18937
18938        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18939                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18940            if (app.foregroundServices) {
18941                // The user is aware of this app, so make it visible.
18942                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18943                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18944                app.cached = false;
18945                app.adjType = "fg-service";
18946                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18947            } else if (app.forcingToForeground != null) {
18948                // The user is aware of this app, so make it visible.
18949                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18950                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18951                app.cached = false;
18952                app.adjType = "force-fg";
18953                app.adjSource = app.forcingToForeground;
18954                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18955            }
18956        }
18957
18958        if (app == mHeavyWeightProcess) {
18959            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18960                // We don't want to kill the current heavy-weight process.
18961                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18962                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18963                app.cached = false;
18964                app.adjType = "heavy";
18965            }
18966            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18967                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18968            }
18969        }
18970
18971        if (app == mHomeProcess) {
18972            if (adj > ProcessList.HOME_APP_ADJ) {
18973                // This process is hosting what we currently consider to be the
18974                // home app, so we don't want to let it go into the background.
18975                adj = ProcessList.HOME_APP_ADJ;
18976                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18977                app.cached = false;
18978                app.adjType = "home";
18979            }
18980            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18981                procState = ActivityManager.PROCESS_STATE_HOME;
18982            }
18983        }
18984
18985        if (app == mPreviousProcess && app.activities.size() > 0) {
18986            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18987                // This was the previous process that showed UI to the user.
18988                // We want to try to keep it around more aggressively, to give
18989                // a good experience around switching between two apps.
18990                adj = ProcessList.PREVIOUS_APP_ADJ;
18991                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18992                app.cached = false;
18993                app.adjType = "previous";
18994            }
18995            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18996                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18997            }
18998        }
18999
19000        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19001                + " reason=" + app.adjType);
19002
19003        // By default, we use the computed adjustment.  It may be changed if
19004        // there are applications dependent on our services or providers, but
19005        // this gives us a baseline and makes sure we don't get into an
19006        // infinite recursion.
19007        app.adjSeq = mAdjSeq;
19008        app.curRawAdj = adj;
19009        app.hasStartedServices = false;
19010
19011        if (mBackupTarget != null && app == mBackupTarget.app) {
19012            // If possible we want to avoid killing apps while they're being backed up
19013            if (adj > ProcessList.BACKUP_APP_ADJ) {
19014                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19015                adj = ProcessList.BACKUP_APP_ADJ;
19016                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19017                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19018                }
19019                app.adjType = "backup";
19020                app.cached = false;
19021            }
19022            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19023                procState = ActivityManager.PROCESS_STATE_BACKUP;
19024            }
19025        }
19026
19027        boolean mayBeTop = false;
19028
19029        for (int is = app.services.size()-1;
19030                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19031                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19032                        || procState > ActivityManager.PROCESS_STATE_TOP);
19033                is--) {
19034            ServiceRecord s = app.services.valueAt(is);
19035            if (s.startRequested) {
19036                app.hasStartedServices = true;
19037                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19038                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19039                }
19040                if (app.hasShownUi && app != mHomeProcess) {
19041                    // If this process has shown some UI, let it immediately
19042                    // go to the LRU list because it may be pretty heavy with
19043                    // UI stuff.  We'll tag it with a label just to help
19044                    // debug and understand what is going on.
19045                    if (adj > ProcessList.SERVICE_ADJ) {
19046                        app.adjType = "cch-started-ui-services";
19047                    }
19048                } else {
19049                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19050                        // This service has seen some activity within
19051                        // recent memory, so we will keep its process ahead
19052                        // of the background processes.
19053                        if (adj > ProcessList.SERVICE_ADJ) {
19054                            adj = ProcessList.SERVICE_ADJ;
19055                            app.adjType = "started-services";
19056                            app.cached = false;
19057                        }
19058                    }
19059                    // If we have let the service slide into the background
19060                    // state, still have some text describing what it is doing
19061                    // even though the service no longer has an impact.
19062                    if (adj > ProcessList.SERVICE_ADJ) {
19063                        app.adjType = "cch-started-services";
19064                    }
19065                }
19066            }
19067
19068            app.whitelistManager = false;
19069
19070            for (int conni = s.connections.size()-1;
19071                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19072                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19073                            || procState > ActivityManager.PROCESS_STATE_TOP);
19074                    conni--) {
19075                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19076                for (int i = 0;
19077                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19078                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19079                                || procState > ActivityManager.PROCESS_STATE_TOP);
19080                        i++) {
19081                    // XXX should compute this based on the max of
19082                    // all connected clients.
19083                    ConnectionRecord cr = clist.get(i);
19084                    if (cr.binding.client == app) {
19085                        // Binding to ourself is not interesting.
19086                        continue;
19087                    }
19088                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19089                        app.whitelistManager = true;
19090                    }
19091
19092                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19093                        ProcessRecord client = cr.binding.client;
19094                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19095                                TOP_APP, doingAll, now);
19096                        int clientProcState = client.curProcState;
19097                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19098                            // If the other app is cached for any reason, for purposes here
19099                            // we are going to consider it empty.  The specific cached state
19100                            // doesn't propagate except under certain conditions.
19101                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19102                        }
19103                        String adjType = null;
19104                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19105                            // Not doing bind OOM management, so treat
19106                            // this guy more like a started service.
19107                            if (app.hasShownUi && app != mHomeProcess) {
19108                                // If this process has shown some UI, let it immediately
19109                                // go to the LRU list because it may be pretty heavy with
19110                                // UI stuff.  We'll tag it with a label just to help
19111                                // debug and understand what is going on.
19112                                if (adj > clientAdj) {
19113                                    adjType = "cch-bound-ui-services";
19114                                }
19115                                app.cached = false;
19116                                clientAdj = adj;
19117                                clientProcState = procState;
19118                            } else {
19119                                if (now >= (s.lastActivity
19120                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19121                                    // This service has not seen activity within
19122                                    // recent memory, so allow it to drop to the
19123                                    // LRU list if there is no other reason to keep
19124                                    // it around.  We'll also tag it with a label just
19125                                    // to help debug and undertand what is going on.
19126                                    if (adj > clientAdj) {
19127                                        adjType = "cch-bound-services";
19128                                    }
19129                                    clientAdj = adj;
19130                                }
19131                            }
19132                        }
19133                        if (adj > clientAdj) {
19134                            // If this process has recently shown UI, and
19135                            // the process that is binding to it is less
19136                            // important than being visible, then we don't
19137                            // care about the binding as much as we care
19138                            // about letting this process get into the LRU
19139                            // list to be killed and restarted if needed for
19140                            // memory.
19141                            if (app.hasShownUi && app != mHomeProcess
19142                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19143                                adjType = "cch-bound-ui-services";
19144                            } else {
19145                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19146                                        |Context.BIND_IMPORTANT)) != 0) {
19147                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19148                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19149                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19150                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19151                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19152                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19153                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19154                                    adj = clientAdj;
19155                                } else {
19156                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19157                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19158                                    }
19159                                }
19160                                if (!client.cached) {
19161                                    app.cached = false;
19162                                }
19163                                adjType = "service";
19164                            }
19165                        }
19166                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19167                            // This will treat important bound services identically to
19168                            // the top app, which may behave differently than generic
19169                            // foreground work.
19170                            if (client.curSchedGroup > schedGroup) {
19171                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19172                                    schedGroup = client.curSchedGroup;
19173                                } else {
19174                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19175                                }
19176                            }
19177                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19178                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19179                                    // Special handling of clients who are in the top state.
19180                                    // We *may* want to consider this process to be in the
19181                                    // top state as well, but only if there is not another
19182                                    // reason for it to be running.  Being on the top is a
19183                                    // special state, meaning you are specifically running
19184                                    // for the current top app.  If the process is already
19185                                    // running in the background for some other reason, it
19186                                    // is more important to continue considering it to be
19187                                    // in the background state.
19188                                    mayBeTop = true;
19189                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19190                                } else {
19191                                    // Special handling for above-top states (persistent
19192                                    // processes).  These should not bring the current process
19193                                    // into the top state, since they are not on top.  Instead
19194                                    // give them the best state after that.
19195                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19196                                        clientProcState =
19197                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19198                                    } else if (mWakefulness
19199                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19200                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19201                                                    != 0) {
19202                                        clientProcState =
19203                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19204                                    } else {
19205                                        clientProcState =
19206                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19207                                    }
19208                                }
19209                            }
19210                        } else {
19211                            if (clientProcState <
19212                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19213                                clientProcState =
19214                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19215                            }
19216                        }
19217                        if (procState > clientProcState) {
19218                            procState = clientProcState;
19219                        }
19220                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19221                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19222                            app.pendingUiClean = true;
19223                        }
19224                        if (adjType != null) {
19225                            app.adjType = adjType;
19226                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19227                                    .REASON_SERVICE_IN_USE;
19228                            app.adjSource = cr.binding.client;
19229                            app.adjSourceProcState = clientProcState;
19230                            app.adjTarget = s.name;
19231                        }
19232                    }
19233                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19234                        app.treatLikeActivity = true;
19235                    }
19236                    final ActivityRecord a = cr.activity;
19237                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19238                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19239                            (a.visible || a.state == ActivityState.RESUMED ||
19240                             a.state == ActivityState.PAUSING)) {
19241                            adj = ProcessList.FOREGROUND_APP_ADJ;
19242                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19243                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19244                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19245                                } else {
19246                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19247                                }
19248                            }
19249                            app.cached = false;
19250                            app.adjType = "service";
19251                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19252                                    .REASON_SERVICE_IN_USE;
19253                            app.adjSource = a;
19254                            app.adjSourceProcState = procState;
19255                            app.adjTarget = s.name;
19256                        }
19257                    }
19258                }
19259            }
19260        }
19261
19262        for (int provi = app.pubProviders.size()-1;
19263                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19264                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19265                        || procState > ActivityManager.PROCESS_STATE_TOP);
19266                provi--) {
19267            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19268            for (int i = cpr.connections.size()-1;
19269                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19270                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19271                            || procState > ActivityManager.PROCESS_STATE_TOP);
19272                    i--) {
19273                ContentProviderConnection conn = cpr.connections.get(i);
19274                ProcessRecord client = conn.client;
19275                if (client == app) {
19276                    // Being our own client is not interesting.
19277                    continue;
19278                }
19279                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19280                int clientProcState = client.curProcState;
19281                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19282                    // If the other app is cached for any reason, for purposes here
19283                    // we are going to consider it empty.
19284                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19285                }
19286                if (adj > clientAdj) {
19287                    if (app.hasShownUi && app != mHomeProcess
19288                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19289                        app.adjType = "cch-ui-provider";
19290                    } else {
19291                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19292                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19293                        app.adjType = "provider";
19294                    }
19295                    app.cached &= client.cached;
19296                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19297                            .REASON_PROVIDER_IN_USE;
19298                    app.adjSource = client;
19299                    app.adjSourceProcState = clientProcState;
19300                    app.adjTarget = cpr.name;
19301                }
19302                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19303                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19304                        // Special handling of clients who are in the top state.
19305                        // We *may* want to consider this process to be in the
19306                        // top state as well, but only if there is not another
19307                        // reason for it to be running.  Being on the top is a
19308                        // special state, meaning you are specifically running
19309                        // for the current top app.  If the process is already
19310                        // running in the background for some other reason, it
19311                        // is more important to continue considering it to be
19312                        // in the background state.
19313                        mayBeTop = true;
19314                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19315                    } else {
19316                        // Special handling for above-top states (persistent
19317                        // processes).  These should not bring the current process
19318                        // into the top state, since they are not on top.  Instead
19319                        // give them the best state after that.
19320                        clientProcState =
19321                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19322                    }
19323                }
19324                if (procState > clientProcState) {
19325                    procState = clientProcState;
19326                }
19327                if (client.curSchedGroup > schedGroup) {
19328                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19329                }
19330            }
19331            // If the provider has external (non-framework) process
19332            // dependencies, ensure that its adjustment is at least
19333            // FOREGROUND_APP_ADJ.
19334            if (cpr.hasExternalProcessHandles()) {
19335                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19336                    adj = ProcessList.FOREGROUND_APP_ADJ;
19337                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19338                    app.cached = false;
19339                    app.adjType = "provider";
19340                    app.adjTarget = cpr.name;
19341                }
19342                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19343                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19344                }
19345            }
19346        }
19347
19348        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19349            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19350                adj = ProcessList.PREVIOUS_APP_ADJ;
19351                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19352                app.cached = false;
19353                app.adjType = "provider";
19354            }
19355            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19356                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19357            }
19358        }
19359
19360        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19361            // A client of one of our services or providers is in the top state.  We
19362            // *may* want to be in the top state, but not if we are already running in
19363            // the background for some other reason.  For the decision here, we are going
19364            // to pick out a few specific states that we want to remain in when a client
19365            // is top (states that tend to be longer-term) and otherwise allow it to go
19366            // to the top state.
19367            switch (procState) {
19368                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19369                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19370                case ActivityManager.PROCESS_STATE_SERVICE:
19371                    // These all are longer-term states, so pull them up to the top
19372                    // of the background states, but not all the way to the top state.
19373                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19374                    break;
19375                default:
19376                    // Otherwise, top is a better choice, so take it.
19377                    procState = ActivityManager.PROCESS_STATE_TOP;
19378                    break;
19379            }
19380        }
19381
19382        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19383            if (app.hasClientActivities) {
19384                // This is a cached process, but with client activities.  Mark it so.
19385                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19386                app.adjType = "cch-client-act";
19387            } else if (app.treatLikeActivity) {
19388                // This is a cached process, but somebody wants us to treat it like it has
19389                // an activity, okay!
19390                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19391                app.adjType = "cch-as-act";
19392            }
19393        }
19394
19395        if (adj == ProcessList.SERVICE_ADJ) {
19396            if (doingAll) {
19397                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19398                mNewNumServiceProcs++;
19399                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19400                if (!app.serviceb) {
19401                    // This service isn't far enough down on the LRU list to
19402                    // normally be a B service, but if we are low on RAM and it
19403                    // is large we want to force it down since we would prefer to
19404                    // keep launcher over it.
19405                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19406                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19407                        app.serviceHighRam = true;
19408                        app.serviceb = true;
19409                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19410                    } else {
19411                        mNewNumAServiceProcs++;
19412                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19413                    }
19414                } else {
19415                    app.serviceHighRam = false;
19416                }
19417            }
19418            if (app.serviceb) {
19419                adj = ProcessList.SERVICE_B_ADJ;
19420            }
19421        }
19422
19423        app.curRawAdj = adj;
19424
19425        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19426        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19427        if (adj > app.maxAdj) {
19428            adj = app.maxAdj;
19429            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19430                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19431            }
19432        }
19433
19434        // Do final modification to adj.  Everything we do between here and applying
19435        // the final setAdj must be done in this function, because we will also use
19436        // it when computing the final cached adj later.  Note that we don't need to
19437        // worry about this for max adj above, since max adj will always be used to
19438        // keep it out of the cached vaues.
19439        app.curAdj = app.modifyRawOomAdj(adj);
19440        app.curSchedGroup = schedGroup;
19441        app.curProcState = procState;
19442        app.foregroundActivities = foregroundActivities;
19443
19444        return app.curRawAdj;
19445    }
19446
19447    /**
19448     * Record new PSS sample for a process.
19449     */
19450    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19451            long now) {
19452        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19453                swapPss * 1024);
19454        proc.lastPssTime = now;
19455        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19456        if (DEBUG_PSS) Slog.d(TAG_PSS,
19457                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19458                + " state=" + ProcessList.makeProcStateString(procState));
19459        if (proc.initialIdlePss == 0) {
19460            proc.initialIdlePss = pss;
19461        }
19462        proc.lastPss = pss;
19463        proc.lastSwapPss = swapPss;
19464        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19465            proc.lastCachedPss = pss;
19466            proc.lastCachedSwapPss = swapPss;
19467        }
19468
19469        final SparseArray<Pair<Long, String>> watchUids
19470                = mMemWatchProcesses.getMap().get(proc.processName);
19471        Long check = null;
19472        if (watchUids != null) {
19473            Pair<Long, String> val = watchUids.get(proc.uid);
19474            if (val == null) {
19475                val = watchUids.get(0);
19476            }
19477            if (val != null) {
19478                check = val.first;
19479            }
19480        }
19481        if (check != null) {
19482            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19483                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19484                if (!isDebuggable) {
19485                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19486                        isDebuggable = true;
19487                    }
19488                }
19489                if (isDebuggable) {
19490                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19491                    final ProcessRecord myProc = proc;
19492                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19493                    mMemWatchDumpProcName = proc.processName;
19494                    mMemWatchDumpFile = heapdumpFile.toString();
19495                    mMemWatchDumpPid = proc.pid;
19496                    mMemWatchDumpUid = proc.uid;
19497                    BackgroundThread.getHandler().post(new Runnable() {
19498                        @Override
19499                        public void run() {
19500                            revokeUriPermission(ActivityThread.currentActivityThread()
19501                                            .getApplicationThread(),
19502                                    DumpHeapActivity.JAVA_URI,
19503                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19504                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19505                                    UserHandle.myUserId());
19506                            ParcelFileDescriptor fd = null;
19507                            try {
19508                                heapdumpFile.delete();
19509                                fd = ParcelFileDescriptor.open(heapdumpFile,
19510                                        ParcelFileDescriptor.MODE_CREATE |
19511                                                ParcelFileDescriptor.MODE_TRUNCATE |
19512                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19513                                                ParcelFileDescriptor.MODE_APPEND);
19514                                IApplicationThread thread = myProc.thread;
19515                                if (thread != null) {
19516                                    try {
19517                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19518                                                "Requesting dump heap from "
19519                                                + myProc + " to " + heapdumpFile);
19520                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19521                                    } catch (RemoteException e) {
19522                                    }
19523                                }
19524                            } catch (FileNotFoundException e) {
19525                                e.printStackTrace();
19526                            } finally {
19527                                if (fd != null) {
19528                                    try {
19529                                        fd.close();
19530                                    } catch (IOException e) {
19531                                    }
19532                                }
19533                            }
19534                        }
19535                    });
19536                } else {
19537                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19538                            + ", but debugging not enabled");
19539                }
19540            }
19541        }
19542    }
19543
19544    /**
19545     * Schedule PSS collection of a process.
19546     */
19547    void requestPssLocked(ProcessRecord proc, int procState) {
19548        if (mPendingPssProcesses.contains(proc)) {
19549            return;
19550        }
19551        if (mPendingPssProcesses.size() == 0) {
19552            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19553        }
19554        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19555        proc.pssProcState = procState;
19556        mPendingPssProcesses.add(proc);
19557    }
19558
19559    /**
19560     * Schedule PSS collection of all processes.
19561     */
19562    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19563        if (!always) {
19564            if (now < (mLastFullPssTime +
19565                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19566                return;
19567            }
19568        }
19569        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19570        mLastFullPssTime = now;
19571        mFullPssPending = true;
19572        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19573        mPendingPssProcesses.clear();
19574        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19575            ProcessRecord app = mLruProcesses.get(i);
19576            if (app.thread == null
19577                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19578                continue;
19579            }
19580            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19581                app.pssProcState = app.setProcState;
19582                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19583                        mTestPssMode, isSleeping(), now);
19584                mPendingPssProcesses.add(app);
19585            }
19586        }
19587        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19588    }
19589
19590    public void setTestPssMode(boolean enabled) {
19591        synchronized (this) {
19592            mTestPssMode = enabled;
19593            if (enabled) {
19594                // Whenever we enable the mode, we want to take a snapshot all of current
19595                // process mem use.
19596                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19597            }
19598        }
19599    }
19600
19601    /**
19602     * Ask a given process to GC right now.
19603     */
19604    final void performAppGcLocked(ProcessRecord app) {
19605        try {
19606            app.lastRequestedGc = SystemClock.uptimeMillis();
19607            if (app.thread != null) {
19608                if (app.reportLowMemory) {
19609                    app.reportLowMemory = false;
19610                    app.thread.scheduleLowMemory();
19611                } else {
19612                    app.thread.processInBackground();
19613                }
19614            }
19615        } catch (Exception e) {
19616            // whatever.
19617        }
19618    }
19619
19620    /**
19621     * Returns true if things are idle enough to perform GCs.
19622     */
19623    private final boolean canGcNowLocked() {
19624        boolean processingBroadcasts = false;
19625        for (BroadcastQueue q : mBroadcastQueues) {
19626            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19627                processingBroadcasts = true;
19628            }
19629        }
19630        return !processingBroadcasts
19631                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19632    }
19633
19634    /**
19635     * Perform GCs on all processes that are waiting for it, but only
19636     * if things are idle.
19637     */
19638    final void performAppGcsLocked() {
19639        final int N = mProcessesToGc.size();
19640        if (N <= 0) {
19641            return;
19642        }
19643        if (canGcNowLocked()) {
19644            while (mProcessesToGc.size() > 0) {
19645                ProcessRecord proc = mProcessesToGc.remove(0);
19646                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19647                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19648                            <= SystemClock.uptimeMillis()) {
19649                        // To avoid spamming the system, we will GC processes one
19650                        // at a time, waiting a few seconds between each.
19651                        performAppGcLocked(proc);
19652                        scheduleAppGcsLocked();
19653                        return;
19654                    } else {
19655                        // It hasn't been long enough since we last GCed this
19656                        // process...  put it in the list to wait for its time.
19657                        addProcessToGcListLocked(proc);
19658                        break;
19659                    }
19660                }
19661            }
19662
19663            scheduleAppGcsLocked();
19664        }
19665    }
19666
19667    /**
19668     * If all looks good, perform GCs on all processes waiting for them.
19669     */
19670    final void performAppGcsIfAppropriateLocked() {
19671        if (canGcNowLocked()) {
19672            performAppGcsLocked();
19673            return;
19674        }
19675        // Still not idle, wait some more.
19676        scheduleAppGcsLocked();
19677    }
19678
19679    /**
19680     * Schedule the execution of all pending app GCs.
19681     */
19682    final void scheduleAppGcsLocked() {
19683        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19684
19685        if (mProcessesToGc.size() > 0) {
19686            // Schedule a GC for the time to the next process.
19687            ProcessRecord proc = mProcessesToGc.get(0);
19688            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19689
19690            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19691            long now = SystemClock.uptimeMillis();
19692            if (when < (now+GC_TIMEOUT)) {
19693                when = now + GC_TIMEOUT;
19694            }
19695            mHandler.sendMessageAtTime(msg, when);
19696        }
19697    }
19698
19699    /**
19700     * Add a process to the array of processes waiting to be GCed.  Keeps the
19701     * list in sorted order by the last GC time.  The process can't already be
19702     * on the list.
19703     */
19704    final void addProcessToGcListLocked(ProcessRecord proc) {
19705        boolean added = false;
19706        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19707            if (mProcessesToGc.get(i).lastRequestedGc <
19708                    proc.lastRequestedGc) {
19709                added = true;
19710                mProcessesToGc.add(i+1, proc);
19711                break;
19712            }
19713        }
19714        if (!added) {
19715            mProcessesToGc.add(0, proc);
19716        }
19717    }
19718
19719    /**
19720     * Set up to ask a process to GC itself.  This will either do it
19721     * immediately, or put it on the list of processes to gc the next
19722     * time things are idle.
19723     */
19724    final void scheduleAppGcLocked(ProcessRecord app) {
19725        long now = SystemClock.uptimeMillis();
19726        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19727            return;
19728        }
19729        if (!mProcessesToGc.contains(app)) {
19730            addProcessToGcListLocked(app);
19731            scheduleAppGcsLocked();
19732        }
19733    }
19734
19735    final void checkExcessivePowerUsageLocked(boolean doKills) {
19736        updateCpuStatsNow();
19737
19738        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19739        boolean doWakeKills = doKills;
19740        boolean doCpuKills = doKills;
19741        if (mLastPowerCheckRealtime == 0) {
19742            doWakeKills = false;
19743        }
19744        if (mLastPowerCheckUptime == 0) {
19745            doCpuKills = false;
19746        }
19747        if (stats.isScreenOn()) {
19748            doWakeKills = false;
19749        }
19750        final long curRealtime = SystemClock.elapsedRealtime();
19751        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19752        final long curUptime = SystemClock.uptimeMillis();
19753        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19754        mLastPowerCheckRealtime = curRealtime;
19755        mLastPowerCheckUptime = curUptime;
19756        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19757            doWakeKills = false;
19758        }
19759        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19760            doCpuKills = false;
19761        }
19762        int i = mLruProcesses.size();
19763        while (i > 0) {
19764            i--;
19765            ProcessRecord app = mLruProcesses.get(i);
19766            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19767                long wtime;
19768                synchronized (stats) {
19769                    wtime = stats.getProcessWakeTime(app.info.uid,
19770                            app.pid, curRealtime);
19771                }
19772                long wtimeUsed = wtime - app.lastWakeTime;
19773                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19774                if (DEBUG_POWER) {
19775                    StringBuilder sb = new StringBuilder(128);
19776                    sb.append("Wake for ");
19777                    app.toShortString(sb);
19778                    sb.append(": over ");
19779                    TimeUtils.formatDuration(realtimeSince, sb);
19780                    sb.append(" used ");
19781                    TimeUtils.formatDuration(wtimeUsed, sb);
19782                    sb.append(" (");
19783                    sb.append((wtimeUsed*100)/realtimeSince);
19784                    sb.append("%)");
19785                    Slog.i(TAG_POWER, sb.toString());
19786                    sb.setLength(0);
19787                    sb.append("CPU for ");
19788                    app.toShortString(sb);
19789                    sb.append(": over ");
19790                    TimeUtils.formatDuration(uptimeSince, sb);
19791                    sb.append(" used ");
19792                    TimeUtils.formatDuration(cputimeUsed, sb);
19793                    sb.append(" (");
19794                    sb.append((cputimeUsed*100)/uptimeSince);
19795                    sb.append("%)");
19796                    Slog.i(TAG_POWER, sb.toString());
19797                }
19798                // If a process has held a wake lock for more
19799                // than 50% of the time during this period,
19800                // that sounds bad.  Kill!
19801                if (doWakeKills && realtimeSince > 0
19802                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19803                    synchronized (stats) {
19804                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19805                                realtimeSince, wtimeUsed);
19806                    }
19807                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19808                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19809                } else if (doCpuKills && uptimeSince > 0
19810                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19811                    synchronized (stats) {
19812                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19813                                uptimeSince, cputimeUsed);
19814                    }
19815                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19816                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19817                } else {
19818                    app.lastWakeTime = wtime;
19819                    app.lastCpuTime = app.curCpuTime;
19820                }
19821            }
19822        }
19823    }
19824
19825    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19826            long nowElapsed) {
19827        boolean success = true;
19828
19829        if (app.curRawAdj != app.setRawAdj) {
19830            app.setRawAdj = app.curRawAdj;
19831        }
19832
19833        int changes = 0;
19834
19835        if (app.curAdj != app.setAdj) {
19836            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19837            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19838                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19839                    + app.adjType);
19840            app.setAdj = app.curAdj;
19841        }
19842
19843        if (app.setSchedGroup != app.curSchedGroup) {
19844            app.setSchedGroup = app.curSchedGroup;
19845            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19846                    "Setting sched group of " + app.processName
19847                    + " to " + app.curSchedGroup);
19848            if (app.waitingToKill != null && app.curReceiver == null
19849                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19850                app.kill(app.waitingToKill, true);
19851                success = false;
19852            } else {
19853                int processGroup;
19854                switch (app.curSchedGroup) {
19855                    case ProcessList.SCHED_GROUP_BACKGROUND:
19856                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19857                        break;
19858                    case ProcessList.SCHED_GROUP_TOP_APP:
19859                        processGroup = Process.THREAD_GROUP_TOP_APP;
19860                        break;
19861                    default:
19862                        processGroup = Process.THREAD_GROUP_DEFAULT;
19863                        break;
19864                }
19865                if (true) {
19866                    long oldId = Binder.clearCallingIdentity();
19867                    try {
19868                        Process.setProcessGroup(app.pid, processGroup);
19869                    } catch (Exception e) {
19870                        Slog.w(TAG, "Failed setting process group of " + app.pid
19871                                + " to " + app.curSchedGroup);
19872                        e.printStackTrace();
19873                    } finally {
19874                        Binder.restoreCallingIdentity(oldId);
19875                    }
19876                } else {
19877                    if (app.thread != null) {
19878                        try {
19879                            app.thread.setSchedulingGroup(processGroup);
19880                        } catch (RemoteException e) {
19881                        }
19882                    }
19883                }
19884            }
19885        }
19886        if (app.repForegroundActivities != app.foregroundActivities) {
19887            app.repForegroundActivities = app.foregroundActivities;
19888            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19889        }
19890        if (app.repProcState != app.curProcState) {
19891            app.repProcState = app.curProcState;
19892            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19893            if (app.thread != null) {
19894                try {
19895                    if (false) {
19896                        //RuntimeException h = new RuntimeException("here");
19897                        Slog.i(TAG, "Sending new process state " + app.repProcState
19898                                + " to " + app /*, h*/);
19899                    }
19900                    app.thread.setProcessState(app.repProcState);
19901                } catch (RemoteException e) {
19902                }
19903            }
19904        }
19905        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19906                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19907            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19908                // Experimental code to more aggressively collect pss while
19909                // running test...  the problem is that this tends to collect
19910                // the data right when a process is transitioning between process
19911                // states, which well tend to give noisy data.
19912                long start = SystemClock.uptimeMillis();
19913                long pss = Debug.getPss(app.pid, mTmpLong, null);
19914                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19915                mPendingPssProcesses.remove(app);
19916                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19917                        + " to " + app.curProcState + ": "
19918                        + (SystemClock.uptimeMillis()-start) + "ms");
19919            }
19920            app.lastStateTime = now;
19921            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19922                    mTestPssMode, isSleeping(), now);
19923            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19924                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19925                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19926                    + (app.nextPssTime-now) + ": " + app);
19927        } else {
19928            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19929                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19930                    mTestPssMode)))) {
19931                requestPssLocked(app, app.setProcState);
19932                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19933                        mTestPssMode, isSleeping(), now);
19934            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19935                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19936        }
19937        if (app.setProcState != app.curProcState) {
19938            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19939                    "Proc state change of " + app.processName
19940                            + " to " + app.curProcState);
19941            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19942            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19943            if (setImportant && !curImportant) {
19944                // This app is no longer something we consider important enough to allow to
19945                // use arbitrary amounts of battery power.  Note
19946                // its current wake lock time to later know to kill it if
19947                // it is not behaving well.
19948                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19949                synchronized (stats) {
19950                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19951                            app.pid, nowElapsed);
19952                }
19953                app.lastCpuTime = app.curCpuTime;
19954
19955            }
19956            // Inform UsageStats of important process state change
19957            // Must be called before updating setProcState
19958            maybeUpdateUsageStatsLocked(app, nowElapsed);
19959
19960            app.setProcState = app.curProcState;
19961            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19962                app.notCachedSinceIdle = false;
19963            }
19964            if (!doingAll) {
19965                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19966            } else {
19967                app.procStateChanged = true;
19968            }
19969        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19970                > USAGE_STATS_INTERACTION_INTERVAL) {
19971            // For apps that sit around for a long time in the interactive state, we need
19972            // to report this at least once a day so they don't go idle.
19973            maybeUpdateUsageStatsLocked(app, nowElapsed);
19974        }
19975
19976        if (changes != 0) {
19977            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19978                    "Changes in " + app + ": " + changes);
19979            int i = mPendingProcessChanges.size()-1;
19980            ProcessChangeItem item = null;
19981            while (i >= 0) {
19982                item = mPendingProcessChanges.get(i);
19983                if (item.pid == app.pid) {
19984                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19985                            "Re-using existing item: " + item);
19986                    break;
19987                }
19988                i--;
19989            }
19990            if (i < 0) {
19991                // No existing item in pending changes; need a new one.
19992                final int NA = mAvailProcessChanges.size();
19993                if (NA > 0) {
19994                    item = mAvailProcessChanges.remove(NA-1);
19995                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19996                            "Retrieving available item: " + item);
19997                } else {
19998                    item = new ProcessChangeItem();
19999                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20000                            "Allocating new item: " + item);
20001                }
20002                item.changes = 0;
20003                item.pid = app.pid;
20004                item.uid = app.info.uid;
20005                if (mPendingProcessChanges.size() == 0) {
20006                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20007                            "*** Enqueueing dispatch processes changed!");
20008                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20009                }
20010                mPendingProcessChanges.add(item);
20011            }
20012            item.changes |= changes;
20013            item.processState = app.repProcState;
20014            item.foregroundActivities = app.repForegroundActivities;
20015            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20016                    "Item " + Integer.toHexString(System.identityHashCode(item))
20017                    + " " + app.toShortString() + ": changes=" + item.changes
20018                    + " procState=" + item.processState
20019                    + " foreground=" + item.foregroundActivities
20020                    + " type=" + app.adjType + " source=" + app.adjSource
20021                    + " target=" + app.adjTarget);
20022        }
20023
20024        return success;
20025    }
20026
20027    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20028        final UidRecord.ChangeItem pendingChange;
20029        if (uidRec == null || uidRec.pendingChange == null) {
20030            if (mPendingUidChanges.size() == 0) {
20031                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20032                        "*** Enqueueing dispatch uid changed!");
20033                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20034            }
20035            final int NA = mAvailUidChanges.size();
20036            if (NA > 0) {
20037                pendingChange = mAvailUidChanges.remove(NA-1);
20038                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20039                        "Retrieving available item: " + pendingChange);
20040            } else {
20041                pendingChange = new UidRecord.ChangeItem();
20042                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20043                        "Allocating new item: " + pendingChange);
20044            }
20045            if (uidRec != null) {
20046                uidRec.pendingChange = pendingChange;
20047                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20048                    // If this uid is going away, and we haven't yet reported it is gone,
20049                    // then do so now.
20050                    change = UidRecord.CHANGE_GONE_IDLE;
20051                }
20052            } else if (uid < 0) {
20053                throw new IllegalArgumentException("No UidRecord or uid");
20054            }
20055            pendingChange.uidRecord = uidRec;
20056            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20057            mPendingUidChanges.add(pendingChange);
20058        } else {
20059            pendingChange = uidRec.pendingChange;
20060            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20061                change = UidRecord.CHANGE_GONE_IDLE;
20062            }
20063        }
20064        pendingChange.change = change;
20065        pendingChange.processState = uidRec != null
20066                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20067    }
20068
20069    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20070            String authority) {
20071        if (app == null) return;
20072        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20073            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20074            if (userState == null) return;
20075            final long now = SystemClock.elapsedRealtime();
20076            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20077            if (lastReported == null || lastReported < now - 60 * 1000L) {
20078                mUsageStatsService.reportContentProviderUsage(
20079                        authority, providerPkgName, app.userId);
20080                userState.mProviderLastReportedFg.put(authority, now);
20081            }
20082        }
20083    }
20084
20085    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20086        if (DEBUG_USAGE_STATS) {
20087            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20088                    + "] state changes: old = " + app.setProcState + ", new = "
20089                    + app.curProcState);
20090        }
20091        if (mUsageStatsService == null) {
20092            return;
20093        }
20094        boolean isInteraction;
20095        // To avoid some abuse patterns, we are going to be careful about what we consider
20096        // to be an app interaction.  Being the top activity doesn't count while the display
20097        // is sleeping, nor do short foreground services.
20098        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20099            isInteraction = true;
20100            app.fgInteractionTime = 0;
20101        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20102            if (app.fgInteractionTime == 0) {
20103                app.fgInteractionTime = nowElapsed;
20104                isInteraction = false;
20105            } else {
20106                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20107            }
20108        } else {
20109            isInteraction = app.curProcState
20110                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20111            app.fgInteractionTime = 0;
20112        }
20113        if (isInteraction && (!app.reportedInteraction
20114                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20115            app.interactionEventTime = nowElapsed;
20116            String[] packages = app.getPackageList();
20117            if (packages != null) {
20118                for (int i = 0; i < packages.length; i++) {
20119                    mUsageStatsService.reportEvent(packages[i], app.userId,
20120                            UsageEvents.Event.SYSTEM_INTERACTION);
20121                }
20122            }
20123        }
20124        app.reportedInteraction = isInteraction;
20125        if (!isInteraction) {
20126            app.interactionEventTime = 0;
20127        }
20128    }
20129
20130    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20131        if (proc.thread != null) {
20132            if (proc.baseProcessTracker != null) {
20133                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20134            }
20135        }
20136    }
20137
20138    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20139            ProcessRecord TOP_APP, boolean doingAll, long now) {
20140        if (app.thread == null) {
20141            return false;
20142        }
20143
20144        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20145
20146        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20147    }
20148
20149    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20150            boolean oomAdj) {
20151        if (isForeground != proc.foregroundServices) {
20152            proc.foregroundServices = isForeground;
20153            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20154                    proc.info.uid);
20155            if (isForeground) {
20156                if (curProcs == null) {
20157                    curProcs = new ArrayList<ProcessRecord>();
20158                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20159                }
20160                if (!curProcs.contains(proc)) {
20161                    curProcs.add(proc);
20162                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20163                            proc.info.packageName, proc.info.uid);
20164                }
20165            } else {
20166                if (curProcs != null) {
20167                    if (curProcs.remove(proc)) {
20168                        mBatteryStatsService.noteEvent(
20169                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20170                                proc.info.packageName, proc.info.uid);
20171                        if (curProcs.size() <= 0) {
20172                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20173                        }
20174                    }
20175                }
20176            }
20177            if (oomAdj) {
20178                updateOomAdjLocked();
20179            }
20180        }
20181    }
20182
20183    private final ActivityRecord resumedAppLocked() {
20184        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20185        String pkg;
20186        int uid;
20187        if (act != null) {
20188            pkg = act.packageName;
20189            uid = act.info.applicationInfo.uid;
20190        } else {
20191            pkg = null;
20192            uid = -1;
20193        }
20194        // Has the UID or resumed package name changed?
20195        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20196                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20197            if (mCurResumedPackage != null) {
20198                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20199                        mCurResumedPackage, mCurResumedUid);
20200            }
20201            mCurResumedPackage = pkg;
20202            mCurResumedUid = uid;
20203            if (mCurResumedPackage != null) {
20204                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20205                        mCurResumedPackage, mCurResumedUid);
20206            }
20207        }
20208        return act;
20209    }
20210
20211    final boolean updateOomAdjLocked(ProcessRecord app) {
20212        final ActivityRecord TOP_ACT = resumedAppLocked();
20213        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20214        final boolean wasCached = app.cached;
20215
20216        mAdjSeq++;
20217
20218        // This is the desired cached adjusment we want to tell it to use.
20219        // If our app is currently cached, we know it, and that is it.  Otherwise,
20220        // we don't know it yet, and it needs to now be cached we will then
20221        // need to do a complete oom adj.
20222        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20223                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20224        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20225                SystemClock.uptimeMillis());
20226        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20227            // Changed to/from cached state, so apps after it in the LRU
20228            // list may also be changed.
20229            updateOomAdjLocked();
20230        }
20231        return success;
20232    }
20233
20234    final void updateOomAdjLocked() {
20235        final ActivityRecord TOP_ACT = resumedAppLocked();
20236        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20237        final long now = SystemClock.uptimeMillis();
20238        final long nowElapsed = SystemClock.elapsedRealtime();
20239        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20240        final int N = mLruProcesses.size();
20241
20242        if (false) {
20243            RuntimeException e = new RuntimeException();
20244            e.fillInStackTrace();
20245            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20246        }
20247
20248        // Reset state in all uid records.
20249        for (int i=mActiveUids.size()-1; i>=0; i--) {
20250            final UidRecord uidRec = mActiveUids.valueAt(i);
20251            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20252                    "Starting update of " + uidRec);
20253            uidRec.reset();
20254        }
20255
20256        mStackSupervisor.rankTaskLayersIfNeeded();
20257
20258        mAdjSeq++;
20259        mNewNumServiceProcs = 0;
20260        mNewNumAServiceProcs = 0;
20261
20262        final int emptyProcessLimit;
20263        final int cachedProcessLimit;
20264        if (mProcessLimit <= 0) {
20265            emptyProcessLimit = cachedProcessLimit = 0;
20266        } else if (mProcessLimit == 1) {
20267            emptyProcessLimit = 1;
20268            cachedProcessLimit = 0;
20269        } else {
20270            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20271            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20272        }
20273
20274        // Let's determine how many processes we have running vs.
20275        // how many slots we have for background processes; we may want
20276        // to put multiple processes in a slot of there are enough of
20277        // them.
20278        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20279                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20280        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20281        if (numEmptyProcs > cachedProcessLimit) {
20282            // If there are more empty processes than our limit on cached
20283            // processes, then use the cached process limit for the factor.
20284            // This ensures that the really old empty processes get pushed
20285            // down to the bottom, so if we are running low on memory we will
20286            // have a better chance at keeping around more cached processes
20287            // instead of a gazillion empty processes.
20288            numEmptyProcs = cachedProcessLimit;
20289        }
20290        int emptyFactor = numEmptyProcs/numSlots;
20291        if (emptyFactor < 1) emptyFactor = 1;
20292        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20293        if (cachedFactor < 1) cachedFactor = 1;
20294        int stepCached = 0;
20295        int stepEmpty = 0;
20296        int numCached = 0;
20297        int numEmpty = 0;
20298        int numTrimming = 0;
20299
20300        mNumNonCachedProcs = 0;
20301        mNumCachedHiddenProcs = 0;
20302
20303        // First update the OOM adjustment for each of the
20304        // application processes based on their current state.
20305        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20306        int nextCachedAdj = curCachedAdj+1;
20307        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20308        int nextEmptyAdj = curEmptyAdj+2;
20309        for (int i=N-1; i>=0; i--) {
20310            ProcessRecord app = mLruProcesses.get(i);
20311            if (!app.killedByAm && app.thread != null) {
20312                app.procStateChanged = false;
20313                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20314
20315                // If we haven't yet assigned the final cached adj
20316                // to the process, do that now.
20317                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20318                    switch (app.curProcState) {
20319                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20320                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20321                            // This process is a cached process holding activities...
20322                            // assign it the next cached value for that type, and then
20323                            // step that cached level.
20324                            app.curRawAdj = curCachedAdj;
20325                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20326                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20327                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20328                                    + ")");
20329                            if (curCachedAdj != nextCachedAdj) {
20330                                stepCached++;
20331                                if (stepCached >= cachedFactor) {
20332                                    stepCached = 0;
20333                                    curCachedAdj = nextCachedAdj;
20334                                    nextCachedAdj += 2;
20335                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20336                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20337                                    }
20338                                }
20339                            }
20340                            break;
20341                        default:
20342                            // For everything else, assign next empty cached process
20343                            // level and bump that up.  Note that this means that
20344                            // long-running services that have dropped down to the
20345                            // cached level will be treated as empty (since their process
20346                            // state is still as a service), which is what we want.
20347                            app.curRawAdj = curEmptyAdj;
20348                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20349                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20350                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20351                                    + ")");
20352                            if (curEmptyAdj != nextEmptyAdj) {
20353                                stepEmpty++;
20354                                if (stepEmpty >= emptyFactor) {
20355                                    stepEmpty = 0;
20356                                    curEmptyAdj = nextEmptyAdj;
20357                                    nextEmptyAdj += 2;
20358                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20359                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20360                                    }
20361                                }
20362                            }
20363                            break;
20364                    }
20365                }
20366
20367                applyOomAdjLocked(app, true, now, nowElapsed);
20368
20369                // Count the number of process types.
20370                switch (app.curProcState) {
20371                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20372                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20373                        mNumCachedHiddenProcs++;
20374                        numCached++;
20375                        if (numCached > cachedProcessLimit) {
20376                            app.kill("cached #" + numCached, true);
20377                        }
20378                        break;
20379                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20380                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20381                                && app.lastActivityTime < oldTime) {
20382                            app.kill("empty for "
20383                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20384                                    / 1000) + "s", true);
20385                        } else {
20386                            numEmpty++;
20387                            if (numEmpty > emptyProcessLimit) {
20388                                app.kill("empty #" + numEmpty, true);
20389                            }
20390                        }
20391                        break;
20392                    default:
20393                        mNumNonCachedProcs++;
20394                        break;
20395                }
20396
20397                if (app.isolated && app.services.size() <= 0) {
20398                    // If this is an isolated process, and there are no
20399                    // services running in it, then the process is no longer
20400                    // needed.  We agressively kill these because we can by
20401                    // definition not re-use the same process again, and it is
20402                    // good to avoid having whatever code was running in them
20403                    // left sitting around after no longer needed.
20404                    app.kill("isolated not needed", true);
20405                } else {
20406                    // Keeping this process, update its uid.
20407                    final UidRecord uidRec = app.uidRecord;
20408                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20409                        uidRec.curProcState = app.curProcState;
20410                    }
20411                }
20412
20413                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20414                        && !app.killedByAm) {
20415                    numTrimming++;
20416                }
20417            }
20418        }
20419
20420        mNumServiceProcs = mNewNumServiceProcs;
20421
20422        // Now determine the memory trimming level of background processes.
20423        // Unfortunately we need to start at the back of the list to do this
20424        // properly.  We only do this if the number of background apps we
20425        // are managing to keep around is less than half the maximum we desire;
20426        // if we are keeping a good number around, we'll let them use whatever
20427        // memory they want.
20428        final int numCachedAndEmpty = numCached + numEmpty;
20429        int memFactor;
20430        if (numCached <= ProcessList.TRIM_CACHED_APPS
20431                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20432            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20433                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20434            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20435                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20436            } else {
20437                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20438            }
20439        } else {
20440            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20441        }
20442        // We always allow the memory level to go up (better).  We only allow it to go
20443        // down if we are in a state where that is allowed, *and* the total number of processes
20444        // has gone down since last time.
20445        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20446                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20447                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20448        if (memFactor > mLastMemoryLevel) {
20449            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20450                memFactor = mLastMemoryLevel;
20451                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20452            }
20453        }
20454        if (memFactor != mLastMemoryLevel) {
20455            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20456        }
20457        mLastMemoryLevel = memFactor;
20458        mLastNumProcesses = mLruProcesses.size();
20459        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20460        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20461        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20462            if (mLowRamStartTime == 0) {
20463                mLowRamStartTime = now;
20464            }
20465            int step = 0;
20466            int fgTrimLevel;
20467            switch (memFactor) {
20468                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20469                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20470                    break;
20471                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20472                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20473                    break;
20474                default:
20475                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20476                    break;
20477            }
20478            int factor = numTrimming/3;
20479            int minFactor = 2;
20480            if (mHomeProcess != null) minFactor++;
20481            if (mPreviousProcess != null) minFactor++;
20482            if (factor < minFactor) factor = minFactor;
20483            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20484            for (int i=N-1; i>=0; i--) {
20485                ProcessRecord app = mLruProcesses.get(i);
20486                if (allChanged || app.procStateChanged) {
20487                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20488                    app.procStateChanged = false;
20489                }
20490                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20491                        && !app.killedByAm) {
20492                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20493                        try {
20494                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20495                                    "Trimming memory of " + app.processName + " to " + curLevel);
20496                            app.thread.scheduleTrimMemory(curLevel);
20497                        } catch (RemoteException e) {
20498                        }
20499                        if (false) {
20500                            // For now we won't do this; our memory trimming seems
20501                            // to be good enough at this point that destroying
20502                            // activities causes more harm than good.
20503                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20504                                    && app != mHomeProcess && app != mPreviousProcess) {
20505                                // Need to do this on its own message because the stack may not
20506                                // be in a consistent state at this point.
20507                                // For these apps we will also finish their activities
20508                                // to help them free memory.
20509                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20510                            }
20511                        }
20512                    }
20513                    app.trimMemoryLevel = curLevel;
20514                    step++;
20515                    if (step >= factor) {
20516                        step = 0;
20517                        switch (curLevel) {
20518                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20519                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20520                                break;
20521                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20522                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20523                                break;
20524                        }
20525                    }
20526                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20527                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20528                            && app.thread != null) {
20529                        try {
20530                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20531                                    "Trimming memory of heavy-weight " + app.processName
20532                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20533                            app.thread.scheduleTrimMemory(
20534                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20535                        } catch (RemoteException e) {
20536                        }
20537                    }
20538                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20539                } else {
20540                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20541                            || app.systemNoUi) && app.pendingUiClean) {
20542                        // If this application is now in the background and it
20543                        // had done UI, then give it the special trim level to
20544                        // have it free UI resources.
20545                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20546                        if (app.trimMemoryLevel < level && app.thread != null) {
20547                            try {
20548                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20549                                        "Trimming memory of bg-ui " + app.processName
20550                                        + " to " + level);
20551                                app.thread.scheduleTrimMemory(level);
20552                            } catch (RemoteException e) {
20553                            }
20554                        }
20555                        app.pendingUiClean = false;
20556                    }
20557                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20558                        try {
20559                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20560                                    "Trimming memory of fg " + app.processName
20561                                    + " to " + fgTrimLevel);
20562                            app.thread.scheduleTrimMemory(fgTrimLevel);
20563                        } catch (RemoteException e) {
20564                        }
20565                    }
20566                    app.trimMemoryLevel = fgTrimLevel;
20567                }
20568            }
20569        } else {
20570            if (mLowRamStartTime != 0) {
20571                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20572                mLowRamStartTime = 0;
20573            }
20574            for (int i=N-1; i>=0; i--) {
20575                ProcessRecord app = mLruProcesses.get(i);
20576                if (allChanged || app.procStateChanged) {
20577                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20578                    app.procStateChanged = false;
20579                }
20580                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20581                        || app.systemNoUi) && app.pendingUiClean) {
20582                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20583                            && app.thread != null) {
20584                        try {
20585                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20586                                    "Trimming memory of ui hidden " + app.processName
20587                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20588                            app.thread.scheduleTrimMemory(
20589                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20590                        } catch (RemoteException e) {
20591                        }
20592                    }
20593                    app.pendingUiClean = false;
20594                }
20595                app.trimMemoryLevel = 0;
20596            }
20597        }
20598
20599        if (mAlwaysFinishActivities) {
20600            // Need to do this on its own message because the stack may not
20601            // be in a consistent state at this point.
20602            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20603        }
20604
20605        if (allChanged) {
20606            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20607        }
20608
20609        // Update from any uid changes.
20610        for (int i=mActiveUids.size()-1; i>=0; i--) {
20611            final UidRecord uidRec = mActiveUids.valueAt(i);
20612            int uidChange = UidRecord.CHANGE_PROCSTATE;
20613            if (uidRec.setProcState != uidRec.curProcState) {
20614                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20615                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20616                        + " to " + uidRec.curProcState);
20617                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20618                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20619                        uidRec.lastBackgroundTime = nowElapsed;
20620                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20621                            // Note: the background settle time is in elapsed realtime, while
20622                            // the handler time base is uptime.  All this means is that we may
20623                            // stop background uids later than we had intended, but that only
20624                            // happens because the device was sleeping so we are okay anyway.
20625                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20626                        }
20627                    }
20628                } else {
20629                    if (uidRec.idle) {
20630                        uidChange = UidRecord.CHANGE_ACTIVE;
20631                        uidRec.idle = false;
20632                    }
20633                    uidRec.lastBackgroundTime = 0;
20634                }
20635                uidRec.setProcState = uidRec.curProcState;
20636                enqueueUidChangeLocked(uidRec, -1, uidChange);
20637                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20638            }
20639        }
20640
20641        if (mProcessStats.shouldWriteNowLocked(now)) {
20642            mHandler.post(new Runnable() {
20643                @Override public void run() {
20644                    synchronized (ActivityManagerService.this) {
20645                        mProcessStats.writeStateAsyncLocked();
20646                    }
20647                }
20648            });
20649        }
20650
20651        if (DEBUG_OOM_ADJ) {
20652            final long duration = SystemClock.uptimeMillis() - now;
20653            if (false) {
20654                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20655                        new RuntimeException("here").fillInStackTrace());
20656            } else {
20657                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20658            }
20659        }
20660    }
20661
20662    final void idleUids() {
20663        synchronized (this) {
20664            final long nowElapsed = SystemClock.elapsedRealtime();
20665            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20666            long nextTime = 0;
20667            for (int i=mActiveUids.size()-1; i>=0; i--) {
20668                final UidRecord uidRec = mActiveUids.valueAt(i);
20669                final long bgTime = uidRec.lastBackgroundTime;
20670                if (bgTime > 0 && !uidRec.idle) {
20671                    if (bgTime <= maxBgTime) {
20672                        uidRec.idle = true;
20673                        doStopUidLocked(uidRec.uid, uidRec);
20674                    } else {
20675                        if (nextTime == 0 || nextTime > bgTime) {
20676                            nextTime = bgTime;
20677                        }
20678                    }
20679                }
20680            }
20681            if (nextTime > 0) {
20682                mHandler.removeMessages(IDLE_UIDS_MSG);
20683                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20684                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20685            }
20686        }
20687    }
20688
20689    final void runInBackgroundDisabled(int uid) {
20690        synchronized (this) {
20691            UidRecord uidRec = mActiveUids.get(uid);
20692            if (uidRec != null) {
20693                // This uid is actually running...  should it be considered background now?
20694                if (uidRec.idle) {
20695                    doStopUidLocked(uidRec.uid, uidRec);
20696                }
20697            } else {
20698                // This uid isn't actually running...  still send a report about it being "stopped".
20699                doStopUidLocked(uid, null);
20700            }
20701        }
20702    }
20703
20704    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20705        mServices.stopInBackgroundLocked(uid);
20706        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20707    }
20708
20709    final void trimApplications() {
20710        synchronized (this) {
20711            int i;
20712
20713            // First remove any unused application processes whose package
20714            // has been removed.
20715            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20716                final ProcessRecord app = mRemovedProcesses.get(i);
20717                if (app.activities.size() == 0
20718                        && app.curReceiver == null && app.services.size() == 0) {
20719                    Slog.i(
20720                        TAG, "Exiting empty application process "
20721                        + app.toShortString() + " ("
20722                        + (app.thread != null ? app.thread.asBinder() : null)
20723                        + ")\n");
20724                    if (app.pid > 0 && app.pid != MY_PID) {
20725                        app.kill("empty", false);
20726                    } else {
20727                        try {
20728                            app.thread.scheduleExit();
20729                        } catch (Exception e) {
20730                            // Ignore exceptions.
20731                        }
20732                    }
20733                    cleanUpApplicationRecordLocked(app, false, true, -1);
20734                    mRemovedProcesses.remove(i);
20735
20736                    if (app.persistent) {
20737                        addAppLocked(app.info, false, null /* ABI override */);
20738                    }
20739                }
20740            }
20741
20742            // Now update the oom adj for all processes.
20743            updateOomAdjLocked();
20744        }
20745    }
20746
20747    /** This method sends the specified signal to each of the persistent apps */
20748    public void signalPersistentProcesses(int sig) throws RemoteException {
20749        if (sig != Process.SIGNAL_USR1) {
20750            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20751        }
20752
20753        synchronized (this) {
20754            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20755                    != PackageManager.PERMISSION_GRANTED) {
20756                throw new SecurityException("Requires permission "
20757                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20758            }
20759
20760            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20761                ProcessRecord r = mLruProcesses.get(i);
20762                if (r.thread != null && r.persistent) {
20763                    Process.sendSignal(r.pid, sig);
20764                }
20765            }
20766        }
20767    }
20768
20769    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20770        if (proc == null || proc == mProfileProc) {
20771            proc = mProfileProc;
20772            profileType = mProfileType;
20773            clearProfilerLocked();
20774        }
20775        if (proc == null) {
20776            return;
20777        }
20778        try {
20779            proc.thread.profilerControl(false, null, profileType);
20780        } catch (RemoteException e) {
20781            throw new IllegalStateException("Process disappeared");
20782        }
20783    }
20784
20785    private void clearProfilerLocked() {
20786        if (mProfileFd != null) {
20787            try {
20788                mProfileFd.close();
20789            } catch (IOException e) {
20790            }
20791        }
20792        mProfileApp = null;
20793        mProfileProc = null;
20794        mProfileFile = null;
20795        mProfileType = 0;
20796        mAutoStopProfiler = false;
20797        mSamplingInterval = 0;
20798    }
20799
20800    public boolean profileControl(String process, int userId, boolean start,
20801            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20802
20803        try {
20804            synchronized (this) {
20805                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20806                // its own permission.
20807                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20808                        != PackageManager.PERMISSION_GRANTED) {
20809                    throw new SecurityException("Requires permission "
20810                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20811                }
20812
20813                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20814                    throw new IllegalArgumentException("null profile info or fd");
20815                }
20816
20817                ProcessRecord proc = null;
20818                if (process != null) {
20819                    proc = findProcessLocked(process, userId, "profileControl");
20820                }
20821
20822                if (start && (proc == null || proc.thread == null)) {
20823                    throw new IllegalArgumentException("Unknown process: " + process);
20824                }
20825
20826                if (start) {
20827                    stopProfilerLocked(null, 0);
20828                    setProfileApp(proc.info, proc.processName, profilerInfo);
20829                    mProfileProc = proc;
20830                    mProfileType = profileType;
20831                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20832                    try {
20833                        fd = fd.dup();
20834                    } catch (IOException e) {
20835                        fd = null;
20836                    }
20837                    profilerInfo.profileFd = fd;
20838                    proc.thread.profilerControl(start, profilerInfo, profileType);
20839                    fd = null;
20840                    mProfileFd = null;
20841                } else {
20842                    stopProfilerLocked(proc, profileType);
20843                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20844                        try {
20845                            profilerInfo.profileFd.close();
20846                        } catch (IOException e) {
20847                        }
20848                    }
20849                }
20850
20851                return true;
20852            }
20853        } catch (RemoteException e) {
20854            throw new IllegalStateException("Process disappeared");
20855        } finally {
20856            if (profilerInfo != null && profilerInfo.profileFd != null) {
20857                try {
20858                    profilerInfo.profileFd.close();
20859                } catch (IOException e) {
20860                }
20861            }
20862        }
20863    }
20864
20865    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20866        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20867                userId, true, ALLOW_FULL_ONLY, callName, null);
20868        ProcessRecord proc = null;
20869        try {
20870            int pid = Integer.parseInt(process);
20871            synchronized (mPidsSelfLocked) {
20872                proc = mPidsSelfLocked.get(pid);
20873            }
20874        } catch (NumberFormatException e) {
20875        }
20876
20877        if (proc == null) {
20878            ArrayMap<String, SparseArray<ProcessRecord>> all
20879                    = mProcessNames.getMap();
20880            SparseArray<ProcessRecord> procs = all.get(process);
20881            if (procs != null && procs.size() > 0) {
20882                proc = procs.valueAt(0);
20883                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20884                    for (int i=1; i<procs.size(); i++) {
20885                        ProcessRecord thisProc = procs.valueAt(i);
20886                        if (thisProc.userId == userId) {
20887                            proc = thisProc;
20888                            break;
20889                        }
20890                    }
20891                }
20892            }
20893        }
20894
20895        return proc;
20896    }
20897
20898    public boolean dumpHeap(String process, int userId, boolean managed,
20899            String path, ParcelFileDescriptor fd) throws RemoteException {
20900
20901        try {
20902            synchronized (this) {
20903                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20904                // its own permission (same as profileControl).
20905                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20906                        != PackageManager.PERMISSION_GRANTED) {
20907                    throw new SecurityException("Requires permission "
20908                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20909                }
20910
20911                if (fd == null) {
20912                    throw new IllegalArgumentException("null fd");
20913                }
20914
20915                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20916                if (proc == null || proc.thread == null) {
20917                    throw new IllegalArgumentException("Unknown process: " + process);
20918                }
20919
20920                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20921                if (!isDebuggable) {
20922                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20923                        throw new SecurityException("Process not debuggable: " + proc);
20924                    }
20925                }
20926
20927                proc.thread.dumpHeap(managed, path, fd);
20928                fd = null;
20929                return true;
20930            }
20931        } catch (RemoteException e) {
20932            throw new IllegalStateException("Process disappeared");
20933        } finally {
20934            if (fd != null) {
20935                try {
20936                    fd.close();
20937                } catch (IOException e) {
20938                }
20939            }
20940        }
20941    }
20942
20943    @Override
20944    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20945            String reportPackage) {
20946        if (processName != null) {
20947            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20948                    "setDumpHeapDebugLimit()");
20949        } else {
20950            synchronized (mPidsSelfLocked) {
20951                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20952                if (proc == null) {
20953                    throw new SecurityException("No process found for calling pid "
20954                            + Binder.getCallingPid());
20955                }
20956                if (!Build.IS_DEBUGGABLE
20957                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20958                    throw new SecurityException("Not running a debuggable build");
20959                }
20960                processName = proc.processName;
20961                uid = proc.uid;
20962                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20963                    throw new SecurityException("Package " + reportPackage + " is not running in "
20964                            + proc);
20965                }
20966            }
20967        }
20968        synchronized (this) {
20969            if (maxMemSize > 0) {
20970                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20971            } else {
20972                if (uid != 0) {
20973                    mMemWatchProcesses.remove(processName, uid);
20974                } else {
20975                    mMemWatchProcesses.getMap().remove(processName);
20976                }
20977            }
20978        }
20979    }
20980
20981    @Override
20982    public void dumpHeapFinished(String path) {
20983        synchronized (this) {
20984            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20985                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20986                        + " does not match last pid " + mMemWatchDumpPid);
20987                return;
20988            }
20989            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20990                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20991                        + " does not match last path " + mMemWatchDumpFile);
20992                return;
20993            }
20994            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20995            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20996        }
20997    }
20998
20999    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21000    public void monitor() {
21001        synchronized (this) { }
21002    }
21003
21004    void onCoreSettingsChange(Bundle settings) {
21005        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21006            ProcessRecord processRecord = mLruProcesses.get(i);
21007            try {
21008                if (processRecord.thread != null) {
21009                    processRecord.thread.setCoreSettings(settings);
21010                }
21011            } catch (RemoteException re) {
21012                /* ignore */
21013            }
21014        }
21015    }
21016
21017    // Multi-user methods
21018
21019    /**
21020     * Start user, if its not already running, but don't bring it to foreground.
21021     */
21022    @Override
21023    public boolean startUserInBackground(final int userId) {
21024        return mUserController.startUser(userId, /* foreground */ false);
21025    }
21026
21027    @Override
21028    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21029        return mUserController.unlockUser(userId, token, secret, listener);
21030    }
21031
21032    @Override
21033    public boolean switchUser(final int targetUserId) {
21034        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21035        UserInfo currentUserInfo;
21036        UserInfo targetUserInfo;
21037        synchronized (this) {
21038            int currentUserId = mUserController.getCurrentUserIdLocked();
21039            currentUserInfo = mUserController.getUserInfo(currentUserId);
21040            targetUserInfo = mUserController.getUserInfo(targetUserId);
21041            if (targetUserInfo == null) {
21042                Slog.w(TAG, "No user info for user #" + targetUserId);
21043                return false;
21044            }
21045            if (!targetUserInfo.supportsSwitchTo()) {
21046                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21047                return false;
21048            }
21049            if (targetUserInfo.isManagedProfile()) {
21050                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21051                return false;
21052            }
21053            mUserController.setTargetUserIdLocked(targetUserId);
21054        }
21055        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21056        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21057        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21058        return true;
21059    }
21060
21061    void scheduleStartProfilesLocked() {
21062        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21063            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21064                    DateUtils.SECOND_IN_MILLIS);
21065        }
21066    }
21067
21068    @Override
21069    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21070        return mUserController.stopUser(userId, force, callback);
21071    }
21072
21073    @Override
21074    public UserInfo getCurrentUser() {
21075        return mUserController.getCurrentUser();
21076    }
21077
21078    @Override
21079    public boolean isUserRunning(int userId, int flags) {
21080        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21081                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21082            String msg = "Permission Denial: isUserRunning() from pid="
21083                    + Binder.getCallingPid()
21084                    + ", uid=" + Binder.getCallingUid()
21085                    + " requires " + INTERACT_ACROSS_USERS;
21086            Slog.w(TAG, msg);
21087            throw new SecurityException(msg);
21088        }
21089        synchronized (this) {
21090            return mUserController.isUserRunningLocked(userId, flags);
21091        }
21092    }
21093
21094    @Override
21095    public int[] getRunningUserIds() {
21096        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21097                != PackageManager.PERMISSION_GRANTED) {
21098            String msg = "Permission Denial: isUserRunning() from pid="
21099                    + Binder.getCallingPid()
21100                    + ", uid=" + Binder.getCallingUid()
21101                    + " requires " + INTERACT_ACROSS_USERS;
21102            Slog.w(TAG, msg);
21103            throw new SecurityException(msg);
21104        }
21105        synchronized (this) {
21106            return mUserController.getStartedUserArrayLocked();
21107        }
21108    }
21109
21110    @Override
21111    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21112        mUserController.registerUserSwitchObserver(observer);
21113    }
21114
21115    @Override
21116    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21117        mUserController.unregisterUserSwitchObserver(observer);
21118    }
21119
21120    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21121        if (info == null) return null;
21122        ApplicationInfo newInfo = new ApplicationInfo(info);
21123        newInfo.initForUser(userId);
21124        return newInfo;
21125    }
21126
21127    public boolean isUserStopped(int userId) {
21128        synchronized (this) {
21129            return mUserController.getStartedUserStateLocked(userId) == null;
21130        }
21131    }
21132
21133    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21134        if (aInfo == null
21135                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21136            return aInfo;
21137        }
21138
21139        ActivityInfo info = new ActivityInfo(aInfo);
21140        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21141        return info;
21142    }
21143
21144    private boolean processSanityChecksLocked(ProcessRecord process) {
21145        if (process == null || process.thread == null) {
21146            return false;
21147        }
21148
21149        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21150        if (!isDebuggable) {
21151            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21152                return false;
21153            }
21154        }
21155
21156        return true;
21157    }
21158
21159    public boolean startBinderTracking() throws RemoteException {
21160        synchronized (this) {
21161            mBinderTransactionTrackingEnabled = true;
21162            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21163            // permission (same as profileControl).
21164            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21165                    != PackageManager.PERMISSION_GRANTED) {
21166                throw new SecurityException("Requires permission "
21167                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21168            }
21169
21170            for (int i = 0; i < mLruProcesses.size(); i++) {
21171                ProcessRecord process = mLruProcesses.get(i);
21172                if (!processSanityChecksLocked(process)) {
21173                    continue;
21174                }
21175                try {
21176                    process.thread.startBinderTracking();
21177                } catch (RemoteException e) {
21178                    Log.v(TAG, "Process disappared");
21179                }
21180            }
21181            return true;
21182        }
21183    }
21184
21185    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21186        try {
21187            synchronized (this) {
21188                mBinderTransactionTrackingEnabled = false;
21189                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21190                // permission (same as profileControl).
21191                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21192                        != PackageManager.PERMISSION_GRANTED) {
21193                    throw new SecurityException("Requires permission "
21194                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21195                }
21196
21197                if (fd == null) {
21198                    throw new IllegalArgumentException("null fd");
21199                }
21200
21201                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21202                pw.println("Binder transaction traces for all processes.\n");
21203                for (ProcessRecord process : mLruProcesses) {
21204                    if (!processSanityChecksLocked(process)) {
21205                        continue;
21206                    }
21207
21208                    pw.println("Traces for process: " + process.processName);
21209                    pw.flush();
21210                    try {
21211                        TransferPipe tp = new TransferPipe();
21212                        try {
21213                            process.thread.stopBinderTrackingAndDump(
21214                                    tp.getWriteFd().getFileDescriptor());
21215                            tp.go(fd.getFileDescriptor());
21216                        } finally {
21217                            tp.kill();
21218                        }
21219                    } catch (IOException e) {
21220                        pw.println("Failure while dumping IPC traces from " + process +
21221                                ".  Exception: " + e);
21222                        pw.flush();
21223                    } catch (RemoteException e) {
21224                        pw.println("Got a RemoteException while dumping IPC traces from " +
21225                                process + ".  Exception: " + e);
21226                        pw.flush();
21227                    }
21228                }
21229                fd = null;
21230                return true;
21231            }
21232        } finally {
21233            if (fd != null) {
21234                try {
21235                    fd.close();
21236                } catch (IOException e) {
21237                }
21238            }
21239        }
21240    }
21241
21242    private final class LocalService extends ActivityManagerInternal {
21243        @Override
21244        public void onWakefulnessChanged(int wakefulness) {
21245            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21246        }
21247
21248        @Override
21249        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21250                String processName, String abiOverride, int uid, Runnable crashHandler) {
21251            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21252                    processName, abiOverride, uid, crashHandler);
21253        }
21254
21255        @Override
21256        public SleepToken acquireSleepToken(String tag) {
21257            Preconditions.checkNotNull(tag);
21258
21259            synchronized (ActivityManagerService.this) {
21260                SleepTokenImpl token = new SleepTokenImpl(tag);
21261                mSleepTokens.add(token);
21262                updateSleepIfNeededLocked();
21263                applyVrModeIfNeededLocked(mFocusedActivity, false);
21264                return token;
21265            }
21266        }
21267
21268        @Override
21269        public ComponentName getHomeActivityForUser(int userId) {
21270            synchronized (ActivityManagerService.this) {
21271                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21272                return homeActivity == null ? null : homeActivity.realActivity;
21273            }
21274        }
21275
21276        @Override
21277        public void onUserRemoved(int userId) {
21278            synchronized (ActivityManagerService.this) {
21279                ActivityManagerService.this.onUserStoppedLocked(userId);
21280            }
21281        }
21282
21283        @Override
21284        public void onLocalVoiceInteractionStarted(IBinder activity,
21285                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21286            synchronized (ActivityManagerService.this) {
21287                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21288                        voiceSession, voiceInteractor);
21289            }
21290        }
21291
21292        @Override
21293        public void notifyStartingWindowDrawn() {
21294            synchronized (ActivityManagerService.this) {
21295                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21296            }
21297        }
21298
21299        @Override
21300        public void notifyAppTransitionStarting(int reason) {
21301            synchronized (ActivityManagerService.this) {
21302                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21303            }
21304        }
21305
21306        @Override
21307        public void notifyAppTransitionFinished() {
21308            synchronized (ActivityManagerService.this) {
21309                mStackSupervisor.notifyAppTransitionDone();
21310            }
21311        }
21312
21313        @Override
21314        public void notifyAppTransitionCancelled() {
21315            synchronized (ActivityManagerService.this) {
21316                mStackSupervisor.notifyAppTransitionDone();
21317            }
21318        }
21319
21320        @Override
21321        public List<IBinder> getTopVisibleActivities() {
21322            synchronized (ActivityManagerService.this) {
21323                return mStackSupervisor.getTopVisibleActivities();
21324            }
21325        }
21326
21327        @Override
21328        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21329            synchronized (ActivityManagerService.this) {
21330                mStackSupervisor.setDockedStackMinimized(minimized);
21331            }
21332        }
21333
21334        @Override
21335        public void killForegroundAppsForUser(int userHandle) {
21336            synchronized (ActivityManagerService.this) {
21337                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21338                final int NP = mProcessNames.getMap().size();
21339                for (int ip = 0; ip < NP; ip++) {
21340                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21341                    final int NA = apps.size();
21342                    for (int ia = 0; ia < NA; ia++) {
21343                        final ProcessRecord app = apps.valueAt(ia);
21344                        if (app.persistent) {
21345                            // We don't kill persistent processes.
21346                            continue;
21347                        }
21348                        if (app.removed) {
21349                            procs.add(app);
21350                        } else if (app.userId == userHandle && app.foregroundActivities) {
21351                            app.removed = true;
21352                            procs.add(app);
21353                        }
21354                    }
21355                }
21356
21357                final int N = procs.size();
21358                for (int i = 0; i < N; i++) {
21359                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21360                }
21361            }
21362        }
21363
21364        @Override
21365        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21366            if (!(target instanceof PendingIntentRecord)) {
21367                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21368                return;
21369            }
21370            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21371        }
21372    }
21373
21374    private final class SleepTokenImpl extends SleepToken {
21375        private final String mTag;
21376        private final long mAcquireTime;
21377
21378        public SleepTokenImpl(String tag) {
21379            mTag = tag;
21380            mAcquireTime = SystemClock.uptimeMillis();
21381        }
21382
21383        @Override
21384        public void release() {
21385            synchronized (ActivityManagerService.this) {
21386                if (mSleepTokens.remove(this)) {
21387                    updateSleepIfNeededLocked();
21388                }
21389            }
21390        }
21391
21392        @Override
21393        public String toString() {
21394            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21395        }
21396    }
21397
21398    /**
21399     * An implementation of IAppTask, that allows an app to manage its own tasks via
21400     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21401     * only the process that calls getAppTasks() can call the AppTask methods.
21402     */
21403    class AppTaskImpl extends IAppTask.Stub {
21404        private int mTaskId;
21405        private int mCallingUid;
21406
21407        public AppTaskImpl(int taskId, int callingUid) {
21408            mTaskId = taskId;
21409            mCallingUid = callingUid;
21410        }
21411
21412        private void checkCaller() {
21413            if (mCallingUid != Binder.getCallingUid()) {
21414                throw new SecurityException("Caller " + mCallingUid
21415                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21416            }
21417        }
21418
21419        @Override
21420        public void finishAndRemoveTask() {
21421            checkCaller();
21422
21423            synchronized (ActivityManagerService.this) {
21424                long origId = Binder.clearCallingIdentity();
21425                try {
21426                    // We remove the task from recents to preserve backwards
21427                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21428                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21429                    }
21430                } finally {
21431                    Binder.restoreCallingIdentity(origId);
21432                }
21433            }
21434        }
21435
21436        @Override
21437        public ActivityManager.RecentTaskInfo getTaskInfo() {
21438            checkCaller();
21439
21440            synchronized (ActivityManagerService.this) {
21441                long origId = Binder.clearCallingIdentity();
21442                try {
21443                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21444                    if (tr == null) {
21445                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21446                    }
21447                    return createRecentTaskInfoFromTaskRecord(tr);
21448                } finally {
21449                    Binder.restoreCallingIdentity(origId);
21450                }
21451            }
21452        }
21453
21454        @Override
21455        public void moveToFront() {
21456            checkCaller();
21457            // Will bring task to front if it already has a root activity.
21458            final long origId = Binder.clearCallingIdentity();
21459            try {
21460                synchronized (this) {
21461                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21462                }
21463            } finally {
21464                Binder.restoreCallingIdentity(origId);
21465            }
21466        }
21467
21468        @Override
21469        public int startActivity(IBinder whoThread, String callingPackage,
21470                Intent intent, String resolvedType, Bundle bOptions) {
21471            checkCaller();
21472
21473            int callingUser = UserHandle.getCallingUserId();
21474            TaskRecord tr;
21475            IApplicationThread appThread;
21476            synchronized (ActivityManagerService.this) {
21477                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21478                if (tr == null) {
21479                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21480                }
21481                appThread = ApplicationThreadNative.asInterface(whoThread);
21482                if (appThread == null) {
21483                    throw new IllegalArgumentException("Bad app thread " + appThread);
21484                }
21485            }
21486            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21487                    resolvedType, null, null, null, null, 0, 0, null, null,
21488                    null, bOptions, false, callingUser, null, tr);
21489        }
21490
21491        @Override
21492        public void setExcludeFromRecents(boolean exclude) {
21493            checkCaller();
21494
21495            synchronized (ActivityManagerService.this) {
21496                long origId = Binder.clearCallingIdentity();
21497                try {
21498                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21499                    if (tr == null) {
21500                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21501                    }
21502                    Intent intent = tr.getBaseIntent();
21503                    if (exclude) {
21504                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21505                    } else {
21506                        intent.setFlags(intent.getFlags()
21507                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21508                    }
21509                } finally {
21510                    Binder.restoreCallingIdentity(origId);
21511                }
21512            }
21513        }
21514    }
21515
21516    /**
21517     * Kill processes for the user with id userId and that depend on the package named packageName
21518     */
21519    @Override
21520    public void killPackageDependents(String packageName, int userId) {
21521        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21522        if (packageName == null) {
21523            throw new NullPointerException(
21524                    "Cannot kill the dependents of a package without its name.");
21525        }
21526
21527        long callingId = Binder.clearCallingIdentity();
21528        IPackageManager pm = AppGlobals.getPackageManager();
21529        int pkgUid = -1;
21530        try {
21531            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21532        } catch (RemoteException e) {
21533        }
21534        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21535            throw new IllegalArgumentException(
21536                    "Cannot kill dependents of non-existing package " + packageName);
21537        }
21538        try {
21539            synchronized(this) {
21540                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21541                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21542                        "dep: " + packageName);
21543            }
21544        } finally {
21545            Binder.restoreCallingIdentity(callingId);
21546        }
21547    }
21548}
21549