ActivityManagerService.java revision af9f004f99d81bdc81a05e179ff04d6b3fcb1041
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastStats mLastBroadcastStats;
571    BroadcastStats mCurBroadcastStats;
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519    static final int FIRST_COMPAT_MODE_MSG = 300;
1520    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522    static ServiceThread sKillThread = null;
1523    static KillHandler sKillHandler = null;
1524
1525    CompatModeDialog mCompatModeDialog;
1526    long mLastMemUsageReportTime = 0;
1527
1528    /**
1529     * Flag whether the current user is a "monkey", i.e. whether
1530     * the UI is driven by a UI automation tool.
1531     */
1532    private boolean mUserIsMonkey;
1533
1534    /** Flag whether the device has a Recents UI */
1535    boolean mHasRecents;
1536
1537    /** The dimensions of the thumbnails in the Recents UI. */
1538    int mThumbnailWidth;
1539    int mThumbnailHeight;
1540    float mFullscreenThumbnailScale;
1541
1542    final ServiceThread mHandlerThread;
1543    final MainHandler mHandler;
1544    final UiHandler mUiHandler;
1545
1546    PackageManagerInternal mPackageManagerInt;
1547
1548    // VoiceInteraction session ID that changes for each new request except when
1549    // being called for multiwindow assist in a single session.
1550    private int mViSessionId = 1000;
1551
1552    final class KillHandler extends Handler {
1553        static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555        public KillHandler(Looper looper) {
1556            super(looper, null, true);
1557        }
1558
1559        @Override
1560        public void handleMessage(Message msg) {
1561            switch (msg.what) {
1562                case KILL_PROCESS_GROUP_MSG:
1563                {
1564                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                }
1568                break;
1569
1570                default:
1571                    super.handleMessage(msg);
1572            }
1573        }
1574    }
1575
1576    final class UiHandler extends Handler {
1577        public UiHandler() {
1578            super(com.android.server.UiThread.get().getLooper(), null, true);
1579        }
1580
1581        @Override
1582        public void handleMessage(Message msg) {
1583            switch (msg.what) {
1584            case SHOW_ERROR_UI_MSG: {
1585                mAppErrors.handleShowAppErrorUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_NOT_RESPONDING_UI_MSG: {
1589                mAppErrors.handleShowAnrUi(msg);
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord proc = (ProcessRecord) data.get("app");
1596                    if (proc == null) {
1597                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                        break;
1599                    }
1600                    if (proc.crashDialog != null) {
1601                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                        return;
1603                    }
1604                    AppErrorResult res = (AppErrorResult) data.get("result");
1605                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                        Dialog d = new StrictModeViolationDialog(mContext,
1607                                ActivityManagerService.this, res, proc);
1608                        d.show();
1609                        proc.crashDialog = d;
1610                    } else {
1611                        // The device is asleep, so just pretend that the user
1612                        // saw a crash dialog and hit "force quit".
1613                        res.set(0);
1614                    }
1615                }
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_FACTORY_ERROR_UI_MSG: {
1619                Dialog d = new FactoryErrorDialog(
1620                    mContext, msg.getData().getCharSequence("msg"));
1621                d.show();
1622                ensureBootCompleted();
1623            } break;
1624            case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ProcessRecord app = (ProcessRecord)msg.obj;
1627                    if (msg.arg1 != 0) {
1628                        if (!app.waitedForDebugger) {
1629                            Dialog d = new AppWaitingForDebuggerDialog(
1630                                    ActivityManagerService.this,
1631                                    mContext, app);
1632                            app.waitDialog = d;
1633                            app.waitedForDebugger = true;
1634                            d.show();
1635                        }
1636                    } else {
1637                        if (app.waitDialog != null) {
1638                            app.waitDialog.dismiss();
1639                            app.waitDialog = null;
1640                        }
1641                    }
1642                }
1643            } break;
1644            case SHOW_UID_ERROR_UI_MSG: {
1645                if (mShowDialogs) {
1646                    AlertDialog d = new BaseErrorDialog(mContext);
1647                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                    d.setCancelable(false);
1649                    d.setTitle(mContext.getText(R.string.android_system_label));
1650                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                    d.show();
1654                }
1655            } break;
1656            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                if (mShowDialogs) {
1658                    AlertDialog d = new BaseErrorDialog(mContext);
1659                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                    d.setCancelable(false);
1661                    d.setTitle(mContext.getText(R.string.android_system_label));
1662                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                    d.show();
1666                }
1667            } break;
1668            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                synchronized (ActivityManagerService.this) {
1670                    ActivityRecord ar = (ActivityRecord) msg.obj;
1671                    if (mCompatModeDialog != null) {
1672                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                ar.info.applicationInfo.packageName)) {
1674                            return;
1675                        }
1676                        mCompatModeDialog.dismiss();
1677                        mCompatModeDialog = null;
1678                    }
1679                    if (ar != null && false) {
1680                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                ar.packageName)) {
1682                            int mode = mCompatModePackages.computeCompatModeLocked(
1683                                    ar.info.applicationInfo);
1684                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                mCompatModeDialog = new CompatModeDialog(
1687                                        ActivityManagerService.this, mContext,
1688                                        ar.info.applicationInfo);
1689                                mCompatModeDialog.show();
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case START_USER_SWITCH_UI_MSG: {
1697                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                break;
1699            }
1700            case DISMISS_DIALOG_UI_MSG: {
1701                final Dialog d = (Dialog) msg.obj;
1702                d.dismiss();
1703                break;
1704            }
1705            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                dispatchProcessesChanged();
1707                break;
1708            }
1709            case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                final int pid = msg.arg1;
1711                final int uid = msg.arg2;
1712                dispatchProcessDied(pid, uid);
1713                break;
1714            }
1715            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                dispatchUidsChanged();
1717            } break;
1718            }
1719        }
1720    }
1721
1722    final class MainHandler extends Handler {
1723        public MainHandler(Looper looper) {
1724            super(looper, null, true);
1725        }
1726
1727        @Override
1728        public void handleMessage(Message msg) {
1729            switch (msg.what) {
1730            case UPDATE_CONFIGURATION_MSG: {
1731                final ContentResolver resolver = mContext.getContentResolver();
1732                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                        msg.arg1);
1734            } break;
1735            case GC_BACKGROUND_PROCESSES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    performAppGcsIfAppropriateLocked();
1738                }
1739            } break;
1740            case SERVICE_TIMEOUT_MSG: {
1741                if (mDidDexOpt) {
1742                    mDidDexOpt = false;
1743                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                    nmsg.obj = msg.obj;
1745                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                    return;
1747                }
1748                mServices.serviceTimeout((ProcessRecord)msg.obj);
1749            } break;
1750            case UPDATE_TIME_ZONE: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimeZone();
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763            } break;
1764            case CLEAR_DNS_CACHE_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.clearDnsCache();
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case UPDATE_HTTP_PROXY_MSG: {
1779                ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                String host = "";
1781                String port = "";
1782                String exclList = "";
1783                Uri pacFileUrl = Uri.EMPTY;
1784                if (proxy != null) {
1785                    host = proxy.getHost();
1786                    port = Integer.toString(proxy.getPort());
1787                    exclList = proxy.getExclusionListAsString();
1788                    pacFileUrl = proxy.getPacFileUrl();
1789                }
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update http proxy for: " +
1798                                        r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case PROC_START_TIMEOUT_MSG: {
1805                if (mDidDexOpt) {
1806                    mDidDexOpt = false;
1807                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                    nmsg.obj = msg.obj;
1809                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                    return;
1811                }
1812                ProcessRecord app = (ProcessRecord)msg.obj;
1813                synchronized (ActivityManagerService.this) {
1814                    processStartTimedOutLocked(app);
1815                }
1816            } break;
1817            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                ProcessRecord app = (ProcessRecord)msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    processContentProviderPublishTimedOutLocked(app);
1821                }
1822            } break;
1823            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                }
1827            } break;
1828            case KILL_APPLICATION_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    int appid = msg.arg1;
1831                    boolean restart = (msg.arg2 == 1);
1832                    Bundle bundle = (Bundle)msg.obj;
1833                    String pkg = bundle.getString("pkg");
1834                    String reason = bundle.getString("reason");
1835                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                            false, UserHandle.USER_ALL, reason);
1837                }
1838            } break;
1839            case FINALIZE_PENDING_INTENT_MSG: {
1840                ((PendingIntentRecord)msg.obj).completeFinalize();
1841            } break;
1842            case POST_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847
1848                ActivityRecord root = (ActivityRecord)msg.obj;
1849                ProcessRecord process = root.app;
1850                if (process == null) {
1851                    return;
1852                }
1853
1854                try {
1855                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                    String text = mContext.getString(R.string.heavy_weight_notification,
1857                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                    Notification notification = new Notification.Builder(context)
1859                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                            .setWhen(0)
1861                            .setOngoing(true)
1862                            .setTicker(text)
1863                            .setColor(mContext.getColor(
1864                                    com.android.internal.R.color.system_notification_accent_color))
1865                            .setContentTitle(text)
1866                            .setContentText(
1867                                    mContext.getText(R.string.heavy_weight_notification_detail))
1868                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                    new UserHandle(root.userId)))
1871                            .build();
1872                    try {
1873                        int[] outId = new int[1];
1874                        inm.enqueueNotificationWithTag("android", "android", null,
1875                                R.string.heavy_weight_notification,
1876                                notification, outId, root.userId);
1877                    } catch (RuntimeException e) {
1878                        Slog.w(ActivityManagerService.TAG,
1879                                "Error showing notification for heavy-weight app", e);
1880                    } catch (RemoteException e) {
1881                    }
1882                } catch (NameNotFoundException e) {
1883                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                }
1885            } break;
1886            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891                try {
1892                    inm.cancelNotificationWithTag("android", null,
1893                            R.string.heavy_weight_notification,  msg.arg1);
1894                } catch (RuntimeException e) {
1895                    Slog.w(ActivityManagerService.TAG,
1896                            "Error canceling notification for service", e);
1897                } catch (RemoteException e) {
1898                }
1899            } break;
1900            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    checkExcessivePowerUsageLocked(true);
1903                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                }
1907            } break;
1908            case REPORT_MEM_USAGE_MSG: {
1909                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                Thread thread = new Thread() {
1911                    @Override public void run() {
1912                        reportMemUsage(memInfos);
1913                    }
1914                };
1915                thread.start();
1916                break;
1917            }
1918            case REPORT_USER_SWITCH_MSG: {
1919                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case CONTINUE_USER_SWITCH_MSG: {
1923                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case USER_SWITCH_TIMEOUT_MSG: {
1927                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                break;
1929            }
1930            case IMMERSIVE_MODE_LOCK_MSG: {
1931                final boolean nextState = (msg.arg1 != 0);
1932                if (mUpdateLock.isHeld() != nextState) {
1933                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                            "Applying new update lock state '" + nextState
1935                            + "' for " + (ActivityRecord)msg.obj);
1936                    if (nextState) {
1937                        mUpdateLock.acquire();
1938                    } else {
1939                        mUpdateLock.release();
1940                    }
1941                }
1942                break;
1943            }
1944            case PERSIST_URI_GRANTS_MSG: {
1945                writeGrantedUriPermissions();
1946                break;
1947            }
1948            case REQUEST_ALL_PSS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                }
1952                break;
1953            }
1954            case START_PROFILES_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    mUserController.startProfilesLocked();
1957                }
1958                break;
1959            }
1960            case UPDATE_TIME: {
1961                synchronized (ActivityManagerService.this) {
1962                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                        ProcessRecord r = mLruProcesses.get(i);
1964                        if (r.thread != null) {
1965                            try {
1966                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                            } catch (RemoteException ex) {
1968                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                            }
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case SYSTEM_USER_START_MSG: {
1976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                        Integer.toString(msg.arg1), msg.arg1);
1978                mSystemServiceManager.startUser(msg.arg1);
1979                break;
1980            }
1981            case SYSTEM_USER_UNLOCK_MSG: {
1982                final int userId = msg.arg1;
1983                mSystemServiceManager.unlockUser(userId);
1984                synchronized (ActivityManagerService.this) {
1985                    mRecentTasks.loadUserRecentsLocked(userId);
1986                }
1987                if (userId == UserHandle.USER_SYSTEM) {
1988                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                }
1990                installEncryptionUnawareProviders(userId);
1991                mUserController.finishUserUnlocked((UserState) msg.obj);
1992                break;
1993            }
1994            case SYSTEM_USER_CURRENT_MSG: {
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                        Integer.toString(msg.arg2), msg.arg2);
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                        Integer.toString(msg.arg1), msg.arg1);
2001                mSystemServiceManager.switchUser(msg.arg1);
2002                break;
2003            }
2004            case ENTER_ANIMATION_COMPLETE_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                    if (r != null && r.app != null && r.app.thread != null) {
2008                        try {
2009                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                        } catch (RemoteException e) {
2011                        }
2012                    }
2013                }
2014                break;
2015            }
2016            case FINISH_BOOTING_MSG: {
2017                if (msg.arg1 != 0) {
2018                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                    finishBooting();
2020                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                }
2022                if (msg.arg2 != 0) {
2023                    enableScreenAfterBoot();
2024                }
2025                break;
2026            }
2027            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                try {
2029                    Locale l = (Locale) msg.obj;
2030                    IBinder service = ServiceManager.getService("mount");
2031                    IMountService mountService = IMountService.Stub.asInterface(service);
2032                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                } catch (RemoteException e) {
2035                    Log.e(TAG, "Error storing locale for decryption UI", e);
2036                }
2037                break;
2038            }
2039            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                        } catch (RemoteException e){
2060                            // Handled by the RemoteCallbackList
2061                        }
2062                    }
2063                    mTaskStackListeners.finishBroadcast();
2064                }
2065                break;
2066            }
2067            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                        try {
2071                            // Make a one-way callback to the listener
2072                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                        } catch (RemoteException e){
2074                            // Handled by the RemoteCallbackList
2075                        }
2076                    }
2077                    mTaskStackListeners.finishBroadcast();
2078                }
2079                break;
2080            }
2081            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                    (String) msg.obj, msg.arg1);
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                    synchronized (ActivityManagerService.this) {
2112                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                            try {
2114                                // Make a one-way callback to the listener
2115                                mTaskStackListeners.getBroadcastItem(i)
2116                                        .onActivityDismissingDockedStack();
2117                            } catch (RemoteException e){
2118                                // Handled by the RemoteCallbackList
2119                            }
2120                        }
2121                        mTaskStackListeners.finishBroadcast();
2122                    }
2123                    break;
2124                }
2125            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                final int uid = msg.arg1;
2127                final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                synchronized (mPidsSelfLocked) {
2130                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                        if (p.uid == uid) {
2133                            try {
2134                                p.thread.notifyCleartextNetwork(firstPacket);
2135                            } catch (RemoteException ignored) {
2136                            }
2137                        }
2138                    }
2139                }
2140                break;
2141            }
2142            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                final String procName;
2144                final int uid;
2145                final long memLimit;
2146                final String reportPackage;
2147                synchronized (ActivityManagerService.this) {
2148                    procName = mMemWatchDumpProcName;
2149                    uid = mMemWatchDumpUid;
2150                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                    if (val == null) {
2152                        val = mMemWatchProcesses.get(procName, 0);
2153                    }
2154                    if (val != null) {
2155                        memLimit = val.first;
2156                        reportPackage = val.second;
2157                    } else {
2158                        memLimit = 0;
2159                        reportPackage = null;
2160                    }
2161                }
2162                if (procName == null) {
2163                    return;
2164                }
2165
2166                if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                        "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                INotificationManager inm = NotificationManager.getService();
2170                if (inm == null) {
2171                    return;
2172                }
2173
2174                String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                Intent deleteIntent = new Intent();
2178                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                Intent intent = new Intent();
2180                intent.setClassName("android", DumpHeapActivity.class.getName());
2181                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                if (reportPackage != null) {
2184                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                }
2186                int userId = UserHandle.getUserId(uid);
2187                Notification notification = new Notification.Builder(mContext)
2188                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                        .setWhen(0)
2190                        .setOngoing(true)
2191                        .setAutoCancel(true)
2192                        .setTicker(text)
2193                        .setColor(mContext.getColor(
2194                                com.android.internal.R.color.system_notification_accent_color))
2195                        .setContentTitle(text)
2196                        .setContentText(
2197                                mContext.getText(R.string.dump_heap_notification_detail))
2198                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                new UserHandle(userId)))
2201                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                deleteIntent, 0, UserHandle.SYSTEM))
2203                        .build();
2204
2205                try {
2206                    int[] outId = new int[1];
2207                    inm.enqueueNotificationWithTag("android", "android", null,
2208                            R.string.dump_heap_notification,
2209                            notification, outId, userId);
2210                } catch (RuntimeException e) {
2211                    Slog.w(ActivityManagerService.TAG,
2212                            "Error showing notification for dump heap", e);
2213                } catch (RemoteException e) {
2214                }
2215            } break;
2216            case DELETE_DUMPHEAP_MSG: {
2217                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                        DumpHeapActivity.JAVA_URI,
2219                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                        UserHandle.myUserId());
2222                synchronized (ActivityManagerService.this) {
2223                    mMemWatchDumpFile = null;
2224                    mMemWatchDumpProcName = null;
2225                    mMemWatchDumpPid = -1;
2226                    mMemWatchDumpUid = -1;
2227                }
2228            } break;
2229            case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231            } break;
2232            case REPORT_TIME_TRACKER_MSG: {
2233                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                tracker.deliverResult(mContext);
2235            } break;
2236            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                mUserController.dispatchUserSwitchComplete(msg.arg1);
2238            } break;
2239            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                try {
2242                    connection.shutdown();
2243                } catch (RemoteException e) {
2244                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                }
2246                // Only a UiAutomation can set this flag and now that
2247                // it is finished we make sure it is reset to its default.
2248                mUserIsMonkey = false;
2249            } break;
2250            case APP_BOOST_DEACTIVATE_MSG: {
2251                synchronized(ActivityManagerService.this) {
2252                    if (mIsBoosted) {
2253                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                            nativeMigrateFromBoost();
2255                            mIsBoosted = false;
2256                            mBoostStartTime = 0;
2257                        } else {
2258                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                        }
2261                    }
2262                }
2263            } break;
2264            case IDLE_UIDS_MSG: {
2265                idleUids();
2266            } break;
2267            case LOG_STACK_STATE: {
2268                synchronized (ActivityManagerService.this) {
2269                    mStackSupervisor.logStackState();
2270                }
2271            } break;
2272            case VR_MODE_CHANGE_MSG: {
2273                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                    }
2288                }
2289                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290            } break;
2291            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                if (needsVrMode) {
2295                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2296                            r.info.getComponentName(), false);
2297                }
2298            } break;
2299            }
2300        }
2301    };
2302
2303    static final int COLLECT_PSS_BG_MSG = 1;
2304
2305    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306        @Override
2307        public void handleMessage(Message msg) {
2308            switch (msg.what) {
2309            case COLLECT_PSS_BG_MSG: {
2310                long start = SystemClock.uptimeMillis();
2311                MemInfoReader memInfo = null;
2312                synchronized (ActivityManagerService.this) {
2313                    if (mFullPssPending) {
2314                        mFullPssPending = false;
2315                        memInfo = new MemInfoReader();
2316                    }
2317                }
2318                if (memInfo != null) {
2319                    updateCpuStatsNow();
2320                    long nativeTotalPss = 0;
2321                    synchronized (mProcessCpuTracker) {
2322                        final int N = mProcessCpuTracker.countStats();
2323                        for (int j=0; j<N; j++) {
2324                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                // This is definitely an application process; skip it.
2327                                continue;
2328                            }
2329                            synchronized (mPidsSelfLocked) {
2330                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                    // This is one of our own processes; skip it.
2332                                    continue;
2333                                }
2334                            }
2335                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                        }
2337                    }
2338                    memInfo.readMemInfo();
2339                    synchronized (ActivityManagerService.this) {
2340                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                + (SystemClock.uptimeMillis()-start) + "ms");
2342                        final long cachedKb = memInfo.getCachedSizeKb();
2343                        final long freeKb = memInfo.getFreeSizeKb();
2344                        final long zramKb = memInfo.getZramTotalSizeKb();
2345                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                kernelKb*1024, nativeTotalPss*1024);
2348                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                nativeTotalPss);
2350                    }
2351                }
2352
2353                int num = 0;
2354                long[] tmp = new long[2];
2355                do {
2356                    ProcessRecord proc;
2357                    int procState;
2358                    int pid;
2359                    long lastPssTime;
2360                    synchronized (ActivityManagerService.this) {
2361                        if (mPendingPssProcesses.size() <= 0) {
2362                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                    "Collected PSS of " + num + " processes in "
2364                                    + (SystemClock.uptimeMillis() - start) + "ms");
2365                            mPendingPssProcesses.clear();
2366                            return;
2367                        }
2368                        proc = mPendingPssProcesses.remove(0);
2369                        procState = proc.pssProcState;
2370                        lastPssTime = proc.lastPssTime;
2371                        if (proc.thread != null && procState == proc.setProcState
2372                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                        < SystemClock.uptimeMillis()) {
2374                            pid = proc.pid;
2375                        } else {
2376                            proc = null;
2377                            pid = 0;
2378                        }
2379                    }
2380                    if (proc != null) {
2381                        long pss = Debug.getPss(pid, tmp, null);
2382                        synchronized (ActivityManagerService.this) {
2383                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                num++;
2386                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                        SystemClock.uptimeMillis());
2388                            }
2389                        }
2390                    }
2391                } while (true);
2392            }
2393            }
2394        }
2395    };
2396
2397    public void setSystemProcess() {
2398        try {
2399            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401            ServiceManager.addService("meminfo", new MemBinder(this));
2402            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403            ServiceManager.addService("dbinfo", new DbBinder(this));
2404            if (MONITOR_CPU_USAGE) {
2405                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406            }
2407            ServiceManager.addService("permission", new PermissionController(this));
2408            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414            synchronized (this) {
2415                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                app.persistent = true;
2417                app.pid = MY_PID;
2418                app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                synchronized (mPidsSelfLocked) {
2421                    mPidsSelfLocked.put(app.pid, app);
2422                }
2423                updateLruProcessLocked(app, false, null);
2424                updateOomAdjLocked();
2425            }
2426        } catch (PackageManager.NameNotFoundException e) {
2427            throw new RuntimeException(
2428                    "Unable to find android system package", e);
2429        }
2430    }
2431
2432    public void setWindowManager(WindowManagerService wm) {
2433        mWindowManager = wm;
2434        mStackSupervisor.setWindowManager(wm);
2435        mActivityStarter.setWindowManager(wm);
2436    }
2437
2438    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439        mUsageStatsService = usageStatsManager;
2440    }
2441
2442    public void startObservingNativeCrashes() {
2443        final NativeCrashListener ncl = new NativeCrashListener(this);
2444        ncl.start();
2445    }
2446
2447    public IAppOpsService getAppOpsService() {
2448        return mAppOpsService;
2449    }
2450
2451    static class MemBinder extends Binder {
2452        ActivityManagerService mActivityManagerService;
2453        MemBinder(ActivityManagerService activityManagerService) {
2454            mActivityManagerService = activityManagerService;
2455        }
2456
2457        @Override
2458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                    != PackageManager.PERMISSION_GRANTED) {
2461                pw.println("Permission Denial: can't dump meminfo from from pid="
2462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                        + " without permission " + android.Manifest.permission.DUMP);
2464                return;
2465            }
2466
2467            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468        }
2469    }
2470
2471    static class GraphicsBinder extends Binder {
2472        ActivityManagerService mActivityManagerService;
2473        GraphicsBinder(ActivityManagerService activityManagerService) {
2474            mActivityManagerService = activityManagerService;
2475        }
2476
2477        @Override
2478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                    != PackageManager.PERMISSION_GRANTED) {
2481                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                        + " without permission " + android.Manifest.permission.DUMP);
2484                return;
2485            }
2486
2487            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488        }
2489    }
2490
2491    static class DbBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        DbBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpDbInfo(fd, pw, args);
2508        }
2509    }
2510
2511    static class CpuBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        CpuBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                        SystemClock.uptimeMillis()));
2531            }
2532        }
2533    }
2534
2535    public static final class Lifecycle extends SystemService {
2536        private final ActivityManagerService mService;
2537
2538        public Lifecycle(Context context) {
2539            super(context);
2540            mService = new ActivityManagerService(context);
2541        }
2542
2543        @Override
2544        public void onStart() {
2545            mService.start();
2546        }
2547
2548        public ActivityManagerService getService() {
2549            return mService;
2550        }
2551    }
2552
2553    // Note: This method is invoked on the main thread but may need to attach various
2554    // handlers to other threads.  So take care to be explicit about the looper.
2555    public ActivityManagerService(Context systemContext) {
2556        mContext = systemContext;
2557        mFactoryTest = FactoryTest.getMode();
2558        mSystemThread = ActivityThread.currentActivityThread();
2559
2560        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562        mHandlerThread = new ServiceThread(TAG,
2563                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564        mHandlerThread.start();
2565        mHandler = new MainHandler(mHandlerThread.getLooper());
2566        mUiHandler = new UiHandler();
2567
2568        /* static; one-time init here */
2569        if (sKillHandler == null) {
2570            sKillThread = new ServiceThread(TAG + ":kill",
2571                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572            sKillThread.start();
2573            sKillHandler = new KillHandler(sKillThread.getLooper());
2574        }
2575
2576        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "foreground", BROADCAST_FG_TIMEOUT, false);
2578        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "background", BROADCAST_BG_TIMEOUT, true);
2580        mBroadcastQueues[0] = mFgBroadcastQueue;
2581        mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583        mServices = new ActiveServices(this);
2584        mProviderMap = new ProviderMap(this);
2585        mAppErrors = new AppErrors(mContext, this);
2586
2587        // TODO: Move creation of battery stats service outside of activity manager service.
2588        File dataDir = Environment.getDataDirectory();
2589        File systemDir = new File(dataDir, "system");
2590        systemDir.mkdirs();
2591        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592        mBatteryStatsService.getActiveStatistics().readLocked();
2593        mBatteryStatsService.scheduleWriteToDisk();
2594        mOnBattery = DEBUG_POWER ? true
2595                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596        mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                new IAppOpsCallback.Stub() {
2603                    @Override public void opChanged(int op, int uid, String packageName) {
2604                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                            if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                    != AppOpsManager.MODE_ALLOWED) {
2607                                runInBackgroundDisabled(uid);
2608                            }
2609                        }
2610                    }
2611                });
2612
2613        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615        mUserController = new UserController(this);
2616
2617        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mConfiguration.setToDefaults();
2623        mConfiguration.setLocales(LocaleList.getDefault());
2624
2625        mConfigurationSeq = mConfiguration.seq = 1;
2626        mProcessCpuTracker.init();
2627
2628        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630        mStackSupervisor = new ActivityStackSupervisor(this);
2631        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634        mProcessCpuThread = new Thread("CpuTracker") {
2635            @Override
2636            public void run() {
2637                while (true) {
2638                    try {
2639                        try {
2640                            synchronized(this) {
2641                                final long now = SystemClock.uptimeMillis();
2642                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                //        + ", write delay=" + nextWriteDelay);
2646                                if (nextWriteDelay < nextCpuDelay) {
2647                                    nextCpuDelay = nextWriteDelay;
2648                                }
2649                                if (nextCpuDelay > 0) {
2650                                    mProcessCpuMutexFree.set(true);
2651                                    this.wait(nextCpuDelay);
2652                                }
2653                            }
2654                        } catch (InterruptedException e) {
2655                        }
2656                        updateCpuStatsNow();
2657                    } catch (Exception e) {
2658                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                    }
2660                }
2661            }
2662        };
2663
2664        Watchdog.getInstance().addMonitor(this);
2665        Watchdog.getInstance().addThread(mHandler);
2666    }
2667
2668    public void setSystemServiceManager(SystemServiceManager mgr) {
2669        mSystemServiceManager = mgr;
2670    }
2671
2672    public void setInstaller(Installer installer) {
2673        mInstaller = installer;
2674    }
2675
2676    private void start() {
2677        Process.removeAllProcessGroups();
2678        mProcessCpuThread.start();
2679
2680        mBatteryStatsService.publish(mContext);
2681        mAppOpsService.publish(mContext);
2682        Slog.d("AppOps", "AppOpsService published");
2683        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684    }
2685
2686    void onUserStoppedLocked(int userId) {
2687        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688    }
2689
2690    public void initPowerManagement() {
2691        mStackSupervisor.initPowerManagement();
2692        mBatteryStatsService.initPowerManagement();
2693        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696        mVoiceWakeLock.setReferenceCounted(false);
2697    }
2698
2699    @Override
2700    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701            throws RemoteException {
2702        if (code == SYSPROPS_TRANSACTION) {
2703            // We need to tell all apps about the system property change.
2704            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705            synchronized(this) {
2706                final int NP = mProcessNames.getMap().size();
2707                for (int ip=0; ip<NP; ip++) {
2708                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                    final int NA = apps.size();
2710                    for (int ia=0; ia<NA; ia++) {
2711                        ProcessRecord app = apps.valueAt(ia);
2712                        if (app.thread != null) {
2713                            procs.add(app.thread.asBinder());
2714                        }
2715                    }
2716                }
2717            }
2718
2719            int N = procs.size();
2720            for (int i=0; i<N; i++) {
2721                Parcel data2 = Parcel.obtain();
2722                try {
2723                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                } catch (RemoteException e) {
2725                }
2726                data2.recycle();
2727            }
2728        }
2729        try {
2730            return super.onTransact(code, data, reply, flags);
2731        } catch (RuntimeException e) {
2732            // The activity manager only throws security exceptions, so let's
2733            // log all others.
2734            if (!(e instanceof SecurityException)) {
2735                Slog.wtf(TAG, "Activity Manager Crash", e);
2736            }
2737            throw e;
2738        }
2739    }
2740
2741    void updateCpuStats() {
2742        final long now = SystemClock.uptimeMillis();
2743        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744            return;
2745        }
2746        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747            synchronized (mProcessCpuThread) {
2748                mProcessCpuThread.notify();
2749            }
2750        }
2751    }
2752
2753    void updateCpuStatsNow() {
2754        synchronized (mProcessCpuTracker) {
2755            mProcessCpuMutexFree.set(false);
2756            final long now = SystemClock.uptimeMillis();
2757            boolean haveNewCpuStats = false;
2758
2759            if (MONITOR_CPU_USAGE &&
2760                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                mLastCpuTime.set(now);
2762                mProcessCpuTracker.update();
2763                if (mProcessCpuTracker.hasGoodLastStats()) {
2764                    haveNewCpuStats = true;
2765                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                    //Slog.i(TAG, "Total CPU usage: "
2767                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                    // Slog the cpu usage if the property is set.
2770                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                        int user = mProcessCpuTracker.getLastUserTime();
2772                        int system = mProcessCpuTracker.getLastSystemTime();
2773                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                        int irq = mProcessCpuTracker.getLastIrqTime();
2775                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                        int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                        int total = user + system + iowait + irq + softIrq + idle;
2779                        if (total == 0) total = 1;
2780
2781                        EventLog.writeEvent(EventLogTags.CPU,
2782                                ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                (user * 100) / total,
2784                                (system * 100) / total,
2785                                (iowait * 100) / total,
2786                                (irq * 100) / total,
2787                                (softIrq * 100) / total);
2788                    }
2789                }
2790            }
2791
2792            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793            synchronized(bstats) {
2794                synchronized(mPidsSelfLocked) {
2795                    if (haveNewCpuStats) {
2796                        if (bstats.startAddingCpuLocked()) {
2797                            int totalUTime = 0;
2798                            int totalSTime = 0;
2799                            final int N = mProcessCpuTracker.countStats();
2800                            for (int i=0; i<N; i++) {
2801                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                if (!st.working) {
2803                                    continue;
2804                                }
2805                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                totalUTime += st.rel_utime;
2807                                totalSTime += st.rel_stime;
2808                                if (pr != null) {
2809                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                    if (ps == null || !ps.isActive()) {
2811                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                pr.info.uid, pr.processName);
2813                                    }
2814                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                } else {
2817                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                    if (ps == null || !ps.isActive()) {
2819                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                bstats.mapUid(st.uid), st.name);
2821                                    }
2822                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                }
2824                            }
2825                            final int userTime = mProcessCpuTracker.getLastUserTime();
2826                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                        }
2834                    }
2835                }
2836
2837                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                    mLastWriteTime = now;
2839                    mBatteryStatsService.scheduleWriteToDisk();
2840                }
2841            }
2842        }
2843    }
2844
2845    @Override
2846    public void batteryNeedsCpuUpdate() {
2847        updateCpuStatsNow();
2848    }
2849
2850    @Override
2851    public void batteryPowerChanged(boolean onBattery) {
2852        // When plugging in, update the CPU stats first before changing
2853        // the plug state.
2854        updateCpuStatsNow();
2855        synchronized (this) {
2856            synchronized(mPidsSelfLocked) {
2857                mOnBattery = DEBUG_POWER ? true : onBattery;
2858            }
2859        }
2860    }
2861
2862    @Override
2863    public void batterySendBroadcast(Intent intent) {
2864        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                AppOpsManager.OP_NONE, null, false, false,
2866                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867    }
2868
2869    /**
2870     * Initialize the application bind args. These are passed to each
2871     * process when the bindApplication() IPC is sent to the process. They're
2872     * lazily setup to make sure the services are running when they're asked for.
2873     */
2874    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875        if (mAppBindArgs == null) {
2876            mAppBindArgs = new HashMap<>();
2877
2878            // Isolated processes won't get this optimization, so that we don't
2879            // violate the rules about which services they have access to.
2880            if (!isolated) {
2881                // Setup the application init args
2882                mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                mAppBindArgs.put(Context.ALARM_SERVICE,
2885                        ServiceManager.getService(Context.ALARM_SERVICE));
2886            }
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892        if (r == null || mFocusedActivity == r) {
2893            return false;
2894        }
2895
2896        if (!r.isFocusable()) {
2897            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898            return false;
2899        }
2900
2901        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906        mDoingSetFocusedActivity = true;
2907
2908        final ActivityRecord last = mFocusedActivity;
2909        mFocusedActivity = r;
2910        if (r.task.isApplicationTask()) {
2911            if (mCurAppTimeTracker != r.appTimeTracker) {
2912                // We are switching app tracking.  Complete the current one.
2913                if (mCurAppTimeTracker != null) {
2914                    mCurAppTimeTracker.stop();
2915                    mHandler.obtainMessage(
2916                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                    mCurAppTimeTracker = null;
2919                }
2920                if (r.appTimeTracker != null) {
2921                    mCurAppTimeTracker = r.appTimeTracker;
2922                    startTimeTrackingFocusedActivityLocked();
2923                }
2924            } else {
2925                startTimeTrackingFocusedActivityLocked();
2926            }
2927        } else {
2928            r.appTimeTracker = null;
2929        }
2930        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931        // TODO: Probably not, because we don't want to resume voice on switching
2932        // back to this activity
2933        if (r.task.voiceInteractor != null) {
2934            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935        } else {
2936            finishRunningVoiceLocked();
2937            IVoiceInteractionSession session;
2938            if (last != null && ((session = last.task.voiceSession) != null
2939                    || (session = last.voiceSession) != null)) {
2940                // We had been in a voice interaction session, but now focused has
2941                // move to something different.  Just finish the session, we can't
2942                // return to it and retain the proper state and synchronization with
2943                // the voice interaction service.
2944                finishVoiceTask(session);
2945            }
2946        }
2947        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948            mWindowManager.setFocusedApp(r.appToken, true);
2949        }
2950        applyUpdateLockStateLocked(r);
2951        applyUpdateVrModeLocked(r);
2952        if (mFocusedActivity.userId != mLastFocusedUserId) {
2953            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954            mHandler.obtainMessage(
2955                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956            mLastFocusedUserId = mFocusedActivity.userId;
2957        }
2958
2959        // Log a warning if the focused app is changed during the process. This could
2960        // indicate a problem of the focus setting logic!
2961        if (mFocusedActivity != r) Slog.w(TAG,
2962                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965        EventLogTags.writeAmFocusedActivity(
2966                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                reason);
2969        return true;
2970    }
2971
2972    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973        if (mFocusedActivity != goingAway) {
2974            return;
2975        }
2976
2977        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978        if (focusedStack != null) {
2979            final ActivityRecord top = focusedStack.topActivity();
2980            if (top != null && top.userId != mLastFocusedUserId) {
2981                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                mHandler.sendMessage(
2983                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                mLastFocusedUserId = top.userId;
2985            }
2986        }
2987
2988        // Try to move focus to another activity if possible.
2989        if (setFocusedActivityLocked(
2990                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991            return;
2992        }
2993
2994        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996        mFocusedActivity = null;
2997        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998    }
2999
3000    @Override
3001    public void setFocusedStack(int stackId) {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004        final long callingId = Binder.clearCallingIdentity();
3005        try {
3006            synchronized (this) {
3007                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                if (stack == null) {
3009                    return;
3010                }
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                }
3015            }
3016        } finally {
3017            Binder.restoreCallingIdentity(callingId);
3018        }
3019    }
3020
3021    @Override
3022    public void setFocusedTask(int taskId) {
3023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025        final long callingId = Binder.clearCallingIdentity();
3026        try {
3027            synchronized (this) {
3028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                if (task == null) {
3030                    return;
3031                }
3032                final ActivityRecord r = task.topRunningActivityLocked();
3033                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                }
3036            }
3037        } finally {
3038            Binder.restoreCallingIdentity(callingId);
3039        }
3040    }
3041
3042    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043    @Override
3044    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046        synchronized (this) {
3047            if (listener != null) {
3048                mTaskStackListeners.register(listener);
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.task.stack.notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082    }
3083
3084    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3085            ComponentName callingPackage, boolean immediate) {
3086        VrManagerInternal vrService =
3087                LocalServices.getService(VrManagerInternal.class);
3088        if (immediate) {
3089            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3090        } else {
3091            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3092        }
3093    }
3094
3095    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3096        Message msg = Message.obtain();
3097        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3098        msg.obj = r.task.askedCompatMode ? null : r;
3099        mUiHandler.sendMessage(msg);
3100    }
3101
3102    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3103            String what, Object obj, ProcessRecord srcApp) {
3104        app.lastActivityTime = now;
3105
3106        if (app.activities.size() > 0) {
3107            // Don't want to touch dependent processes that are hosting activities.
3108            return index;
3109        }
3110
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui < 0) {
3113            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3114                    + what + " " + obj + " from " + srcApp);
3115            return index;
3116        }
3117
3118        if (lrui >= index) {
3119            // Don't want to cause this to move dependent processes *back* in the
3120            // list as if they were less frequently used.
3121            return index;
3122        }
3123
3124        if (lrui >= mLruProcessActivityStart) {
3125            // Don't want to touch dependent processes that are hosting activities.
3126            return index;
3127        }
3128
3129        mLruProcesses.remove(lrui);
3130        if (index > 0) {
3131            index--;
3132        }
3133        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3134                + " in LRU list: " + app);
3135        mLruProcesses.add(index, app);
3136        return index;
3137    }
3138
3139    static void killProcessGroup(int uid, int pid) {
3140        if (sKillHandler != null) {
3141            sKillHandler.sendMessage(
3142                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3143        } else {
3144            Slog.w(TAG, "Asked to kill process group before system bringup!");
3145            Process.killProcessGroup(uid, pid);
3146        }
3147    }
3148
3149    final void removeLruProcessLocked(ProcessRecord app) {
3150        int lrui = mLruProcesses.lastIndexOf(app);
3151        if (lrui >= 0) {
3152            if (!app.killed) {
3153                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3154                Process.killProcessQuiet(app.pid);
3155                killProcessGroup(app.uid, app.pid);
3156            }
3157            if (lrui <= mLruProcessActivityStart) {
3158                mLruProcessActivityStart--;
3159            }
3160            if (lrui <= mLruProcessServiceStart) {
3161                mLruProcessServiceStart--;
3162            }
3163            mLruProcesses.remove(lrui);
3164        }
3165    }
3166
3167    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3168            ProcessRecord client) {
3169        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3170                || app.treatLikeActivity;
3171        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3172        if (!activityChange && hasActivity) {
3173            // The process has activities, so we are only allowing activity-based adjustments
3174            // to move it.  It should be kept in the front of the list with other
3175            // processes that have activities, and we don't want those to change their
3176            // order except due to activity operations.
3177            return;
3178        }
3179
3180        mLruSeq++;
3181        final long now = SystemClock.uptimeMillis();
3182        app.lastActivityTime = now;
3183
3184        // First a quick reject: if the app is already at the position we will
3185        // put it, then there is nothing to do.
3186        if (hasActivity) {
3187            final int N = mLruProcesses.size();
3188            if (N > 0 && mLruProcesses.get(N-1) == app) {
3189                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3190                return;
3191            }
3192        } else {
3193            if (mLruProcessServiceStart > 0
3194                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3195                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3196                return;
3197            }
3198        }
3199
3200        int lrui = mLruProcesses.lastIndexOf(app);
3201
3202        if (app.persistent && lrui >= 0) {
3203            // We don't care about the position of persistent processes, as long as
3204            // they are in the list.
3205            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3206            return;
3207        }
3208
3209        /* In progress: compute new position first, so we can avoid doing work
3210           if the process is not actually going to move.  Not yet working.
3211        int addIndex;
3212        int nextIndex;
3213        boolean inActivity = false, inService = false;
3214        if (hasActivity) {
3215            // Process has activities, put it at the very tipsy-top.
3216            addIndex = mLruProcesses.size();
3217            nextIndex = mLruProcessServiceStart;
3218            inActivity = true;
3219        } else if (hasService) {
3220            // Process has services, put it at the top of the service list.
3221            addIndex = mLruProcessActivityStart;
3222            nextIndex = mLruProcessServiceStart;
3223            inActivity = true;
3224            inService = true;
3225        } else  {
3226            // Process not otherwise of interest, it goes to the top of the non-service area.
3227            addIndex = mLruProcessServiceStart;
3228            if (client != null) {
3229                int clientIndex = mLruProcesses.lastIndexOf(client);
3230                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3231                        + app);
3232                if (clientIndex >= 0 && addIndex > clientIndex) {
3233                    addIndex = clientIndex;
3234                }
3235            }
3236            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3237        }
3238
3239        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3240                + mLruProcessActivityStart + "): " + app);
3241        */
3242
3243        if (lrui >= 0) {
3244            if (lrui < mLruProcessActivityStart) {
3245                mLruProcessActivityStart--;
3246            }
3247            if (lrui < mLruProcessServiceStart) {
3248                mLruProcessServiceStart--;
3249            }
3250            /*
3251            if (addIndex > lrui) {
3252                addIndex--;
3253            }
3254            if (nextIndex > lrui) {
3255                nextIndex--;
3256            }
3257            */
3258            mLruProcesses.remove(lrui);
3259        }
3260
3261        /*
3262        mLruProcesses.add(addIndex, app);
3263        if (inActivity) {
3264            mLruProcessActivityStart++;
3265        }
3266        if (inService) {
3267            mLruProcessActivityStart++;
3268        }
3269        */
3270
3271        int nextIndex;
3272        if (hasActivity) {
3273            final int N = mLruProcesses.size();
3274            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3275                // Process doesn't have activities, but has clients with
3276                // activities...  move it up, but one below the top (the top
3277                // should always have a real activity).
3278                if (DEBUG_LRU) Slog.d(TAG_LRU,
3279                        "Adding to second-top of LRU activity list: " + app);
3280                mLruProcesses.add(N - 1, app);
3281                // To keep it from spamming the LRU list (by making a bunch of clients),
3282                // we will push down any other entries owned by the app.
3283                final int uid = app.info.uid;
3284                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3285                    ProcessRecord subProc = mLruProcesses.get(i);
3286                    if (subProc.info.uid == uid) {
3287                        // We want to push this one down the list.  If the process after
3288                        // it is for the same uid, however, don't do so, because we don't
3289                        // want them internally to be re-ordered.
3290                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3291                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3292                                    "Pushing uid " + uid + " swapping at " + i + ": "
3293                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3294                            ProcessRecord tmp = mLruProcesses.get(i);
3295                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3296                            mLruProcesses.set(i - 1, tmp);
3297                            i--;
3298                        }
3299                    } else {
3300                        // A gap, we can stop here.
3301                        break;
3302                    }
3303                }
3304            } else {
3305                // Process has activities, put it at the very tipsy-top.
3306                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3307                mLruProcesses.add(app);
3308            }
3309            nextIndex = mLruProcessServiceStart;
3310        } else if (hasService) {
3311            // Process has services, put it at the top of the service list.
3312            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3313            mLruProcesses.add(mLruProcessActivityStart, app);
3314            nextIndex = mLruProcessServiceStart;
3315            mLruProcessActivityStart++;
3316        } else  {
3317            // Process not otherwise of interest, it goes to the top of the non-service area.
3318            int index = mLruProcessServiceStart;
3319            if (client != null) {
3320                // If there is a client, don't allow the process to be moved up higher
3321                // in the list than that client.
3322                int clientIndex = mLruProcesses.lastIndexOf(client);
3323                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3324                        + " when updating " + app);
3325                if (clientIndex <= lrui) {
3326                    // Don't allow the client index restriction to push it down farther in the
3327                    // list than it already is.
3328                    clientIndex = lrui;
3329                }
3330                if (clientIndex >= 0 && index > clientIndex) {
3331                    index = clientIndex;
3332                }
3333            }
3334            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3335            mLruProcesses.add(index, app);
3336            nextIndex = index-1;
3337            mLruProcessActivityStart++;
3338            mLruProcessServiceStart++;
3339        }
3340
3341        // If the app is currently using a content provider or service,
3342        // bump those processes as well.
3343        for (int j=app.connections.size()-1; j>=0; j--) {
3344            ConnectionRecord cr = app.connections.valueAt(j);
3345            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3346                    && cr.binding.service.app != null
3347                    && cr.binding.service.app.lruSeq != mLruSeq
3348                    && !cr.binding.service.app.persistent) {
3349                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3350                        "service connection", cr, app);
3351            }
3352        }
3353        for (int j=app.conProviders.size()-1; j>=0; j--) {
3354            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3355            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3356                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3357                        "provider reference", cpr, app);
3358            }
3359        }
3360    }
3361
3362    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3363        if (uid == Process.SYSTEM_UID) {
3364            // The system gets to run in any process.  If there are multiple
3365            // processes with the same uid, just pick the first (this
3366            // should never happen).
3367            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3368            if (procs == null) return null;
3369            final int procCount = procs.size();
3370            for (int i = 0; i < procCount; i++) {
3371                final int procUid = procs.keyAt(i);
3372                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3373                    // Don't use an app process or different user process for system component.
3374                    continue;
3375                }
3376                return procs.valueAt(i);
3377            }
3378        }
3379        ProcessRecord proc = mProcessNames.get(processName, uid);
3380        if (false && proc != null && !keepIfLarge
3381                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3382                && proc.lastCachedPss >= 4000) {
3383            // Turn this condition on to cause killing to happen regularly, for testing.
3384            if (proc.baseProcessTracker != null) {
3385                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3386            }
3387            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3388        } else if (proc != null && !keepIfLarge
3389                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3390                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3391            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3392            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3393                if (proc.baseProcessTracker != null) {
3394                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3395                }
3396                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3397            }
3398        }
3399        return proc;
3400    }
3401
3402    void notifyPackageUse(String packageName, int reason) {
3403        IPackageManager pm = AppGlobals.getPackageManager();
3404        try {
3405            pm.notifyPackageUse(packageName, reason);
3406        } catch (RemoteException e) {
3407        }
3408    }
3409
3410    boolean isNextTransitionForward() {
3411        int transit = mWindowManager.getPendingAppTransition();
3412        return transit == TRANSIT_ACTIVITY_OPEN
3413                || transit == TRANSIT_TASK_OPEN
3414                || transit == TRANSIT_TASK_TO_FRONT;
3415    }
3416
3417    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3418            String processName, String abiOverride, int uid, Runnable crashHandler) {
3419        synchronized(this) {
3420            ApplicationInfo info = new ApplicationInfo();
3421            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3422            // For isolated processes, the former contains the parent's uid and the latter the
3423            // actual uid of the isolated process.
3424            // In the special case introduced by this method (which is, starting an isolated
3425            // process directly from the SystemServer without an actual parent app process) the
3426            // closest thing to a parent's uid is SYSTEM_UID.
3427            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3428            // the |isolated| logic in the ProcessRecord constructor.
3429            info.uid = Process.SYSTEM_UID;
3430            info.processName = processName;
3431            info.className = entryPoint;
3432            info.packageName = "android";
3433            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3434                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3435                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3436                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3437                    crashHandler);
3438            return proc != null ? proc.pid : 0;
3439        }
3440    }
3441
3442    final ProcessRecord startProcessLocked(String processName,
3443            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3444            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3445            boolean isolated, boolean keepIfLarge) {
3446        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3447                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3448                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3449                null /* crashHandler */);
3450    }
3451
3452    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3453            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3454            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3455            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3456        long startTime = SystemClock.elapsedRealtime();
3457        ProcessRecord app;
3458        if (!isolated) {
3459            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3460            checkTime(startTime, "startProcess: after getProcessRecord");
3461
3462            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3463                // If we are in the background, then check to see if this process
3464                // is bad.  If so, we will just silently fail.
3465                if (mAppErrors.isBadProcessLocked(info)) {
3466                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3467                            + "/" + info.processName);
3468                    return null;
3469                }
3470            } else {
3471                // When the user is explicitly starting a process, then clear its
3472                // crash count so that we won't make it bad until they see at
3473                // least one crash dialog again, and make the process good again
3474                // if it had been bad.
3475                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3476                        + "/" + info.processName);
3477                mAppErrors.resetProcessCrashTimeLocked(info);
3478                if (mAppErrors.isBadProcessLocked(info)) {
3479                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3480                            UserHandle.getUserId(info.uid), info.uid,
3481                            info.processName);
3482                    mAppErrors.clearBadProcessLocked(info);
3483                    if (app != null) {
3484                        app.bad = false;
3485                    }
3486                }
3487            }
3488        } else {
3489            // If this is an isolated process, it can't re-use an existing process.
3490            app = null;
3491        }
3492
3493        // app launch boost for big.little configurations
3494        // use cpusets to migrate freshly launched tasks to big cores
3495        synchronized(ActivityManagerService.this) {
3496            nativeMigrateToBoost();
3497            mIsBoosted = true;
3498            mBoostStartTime = SystemClock.uptimeMillis();
3499            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3500            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3501        }
3502
3503        // We don't have to do anything more if:
3504        // (1) There is an existing application record; and
3505        // (2) The caller doesn't think it is dead, OR there is no thread
3506        //     object attached to it so we know it couldn't have crashed; and
3507        // (3) There is a pid assigned to it, so it is either starting or
3508        //     already running.
3509        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3510                + " app=" + app + " knownToBeDead=" + knownToBeDead
3511                + " thread=" + (app != null ? app.thread : null)
3512                + " pid=" + (app != null ? app.pid : -1));
3513        if (app != null && app.pid > 0) {
3514            if (!knownToBeDead || app.thread == null) {
3515                // We already have the app running, or are waiting for it to
3516                // come up (we have a pid but not yet its thread), so keep it.
3517                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3518                // If this is a new package in the process, add the package to the list
3519                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3520                checkTime(startTime, "startProcess: done, added package to proc");
3521                return app;
3522            }
3523
3524            // An application record is attached to a previous process,
3525            // clean it up now.
3526            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3527            checkTime(startTime, "startProcess: bad proc running, killing");
3528            killProcessGroup(app.uid, app.pid);
3529            handleAppDiedLocked(app, true, true);
3530            checkTime(startTime, "startProcess: done killing old proc");
3531        }
3532
3533        String hostingNameStr = hostingName != null
3534                ? hostingName.flattenToShortString() : null;
3535
3536        if (app == null) {
3537            checkTime(startTime, "startProcess: creating new process record");
3538            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3539            if (app == null) {
3540                Slog.w(TAG, "Failed making new process record for "
3541                        + processName + "/" + info.uid + " isolated=" + isolated);
3542                return null;
3543            }
3544            app.crashHandler = crashHandler;
3545            checkTime(startTime, "startProcess: done creating new process record");
3546        } else {
3547            // If this is a new package in the process, add the package to the list
3548            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3549            checkTime(startTime, "startProcess: added package to existing proc");
3550        }
3551
3552        // If the system is not ready yet, then hold off on starting this
3553        // process until it is.
3554        if (!mProcessesReady
3555                && !isAllowedWhileBooting(info)
3556                && !allowWhileBooting) {
3557            if (!mProcessesOnHold.contains(app)) {
3558                mProcessesOnHold.add(app);
3559            }
3560            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3561                    "System not ready, putting on hold: " + app);
3562            checkTime(startTime, "startProcess: returning with proc on hold");
3563            return app;
3564        }
3565
3566        checkTime(startTime, "startProcess: stepping in to startProcess");
3567        startProcessLocked(
3568                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3569        checkTime(startTime, "startProcess: done starting proc!");
3570        return (app.pid != 0) ? app : null;
3571    }
3572
3573    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3574        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3575    }
3576
3577    private final void startProcessLocked(ProcessRecord app,
3578            String hostingType, String hostingNameStr) {
3579        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3580                null /* entryPoint */, null /* entryPointArgs */);
3581    }
3582
3583    private final void startProcessLocked(ProcessRecord app, String hostingType,
3584            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3585        long startTime = SystemClock.elapsedRealtime();
3586        if (app.pid > 0 && app.pid != MY_PID) {
3587            checkTime(startTime, "startProcess: removing from pids map");
3588            synchronized (mPidsSelfLocked) {
3589                mPidsSelfLocked.remove(app.pid);
3590                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3591            }
3592            checkTime(startTime, "startProcess: done removing from pids map");
3593            app.setPid(0);
3594        }
3595
3596        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3597                "startProcessLocked removing on hold: " + app);
3598        mProcessesOnHold.remove(app);
3599
3600        checkTime(startTime, "startProcess: starting to update cpu stats");
3601        updateCpuStats();
3602        checkTime(startTime, "startProcess: done updating cpu stats");
3603
3604        try {
3605            try {
3606                final int userId = UserHandle.getUserId(app.uid);
3607                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3608            } catch (RemoteException e) {
3609                throw e.rethrowAsRuntimeException();
3610            }
3611
3612            int uid = app.uid;
3613            int[] gids = null;
3614            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3615            if (!app.isolated) {
3616                int[] permGids = null;
3617                try {
3618                    checkTime(startTime, "startProcess: getting gids from package manager");
3619                    final IPackageManager pm = AppGlobals.getPackageManager();
3620                    permGids = pm.getPackageGids(app.info.packageName,
3621                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3622                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3623                            MountServiceInternal.class);
3624                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3625                            app.info.packageName);
3626                } catch (RemoteException e) {
3627                    throw e.rethrowAsRuntimeException();
3628                }
3629
3630                /*
3631                 * Add shared application and profile GIDs so applications can share some
3632                 * resources like shared libraries and access user-wide resources
3633                 */
3634                if (ArrayUtils.isEmpty(permGids)) {
3635                    gids = new int[2];
3636                } else {
3637                    gids = new int[permGids.length + 2];
3638                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3639                }
3640                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3641                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3642            }
3643            checkTime(startTime, "startProcess: building args");
3644            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3645                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3646                        && mTopComponent != null
3647                        && app.processName.equals(mTopComponent.getPackageName())) {
3648                    uid = 0;
3649                }
3650                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3651                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3652                    uid = 0;
3653                }
3654            }
3655            int debugFlags = 0;
3656            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3658                // Also turn on CheckJNI for debuggable apps. It's quite
3659                // awkward to turn on otherwise.
3660                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3661            }
3662            // Run the app in safe mode if its manifest requests so or the
3663            // system is booted in safe mode.
3664            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3665                mSafeMode == true) {
3666                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3667            }
3668            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3669                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3670            }
3671            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3672            if ("true".equals(genDebugInfoProperty)) {
3673                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3674            }
3675            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3676                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3677            }
3678            if ("1".equals(SystemProperties.get("debug.assert"))) {
3679                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3680            }
3681            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3682                // Enable all debug flags required by the native debugger.
3683                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3684                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3685                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3686                mNativeDebuggingApp = null;
3687            }
3688
3689            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3690            if (requiredAbi == null) {
3691                requiredAbi = Build.SUPPORTED_ABIS[0];
3692            }
3693
3694            String instructionSet = null;
3695            if (app.info.primaryCpuAbi != null) {
3696                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3697            }
3698
3699            app.gids = gids;
3700            app.requiredAbi = requiredAbi;
3701            app.instructionSet = instructionSet;
3702
3703            // Start the process.  It will either succeed and return a result containing
3704            // the PID of the new process, or else throw a RuntimeException.
3705            boolean isActivityProcess = (entryPoint == null);
3706            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3707            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3708                    app.processName);
3709            checkTime(startTime, "startProcess: asking zygote to start proc");
3710            Process.ProcessStartResult startResult = Process.start(entryPoint,
3711                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3712                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3713                    app.info.dataDir, entryPointArgs);
3714            checkTime(startTime, "startProcess: returned from zygote!");
3715            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3716
3717            if (app.isolated) {
3718                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3719            }
3720            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3721            checkTime(startTime, "startProcess: done updating battery stats");
3722
3723            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3724                    UserHandle.getUserId(uid), startResult.pid, uid,
3725                    app.processName, hostingType,
3726                    hostingNameStr != null ? hostingNameStr : "");
3727
3728            try {
3729                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3730                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3731            } catch (RemoteException ex) {
3732                // Ignore
3733            }
3734
3735            if (app.persistent) {
3736                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3737            }
3738
3739            checkTime(startTime, "startProcess: building log message");
3740            StringBuilder buf = mStringBuilder;
3741            buf.setLength(0);
3742            buf.append("Start proc ");
3743            buf.append(startResult.pid);
3744            buf.append(':');
3745            buf.append(app.processName);
3746            buf.append('/');
3747            UserHandle.formatUid(buf, uid);
3748            if (!isActivityProcess) {
3749                buf.append(" [");
3750                buf.append(entryPoint);
3751                buf.append("]");
3752            }
3753            buf.append(" for ");
3754            buf.append(hostingType);
3755            if (hostingNameStr != null) {
3756                buf.append(" ");
3757                buf.append(hostingNameStr);
3758            }
3759            Slog.i(TAG, buf.toString());
3760            app.setPid(startResult.pid);
3761            app.usingWrapper = startResult.usingWrapper;
3762            app.removed = false;
3763            app.killed = false;
3764            app.killedByAm = false;
3765            checkTime(startTime, "startProcess: starting to update pids map");
3766            synchronized (mPidsSelfLocked) {
3767                this.mPidsSelfLocked.put(startResult.pid, app);
3768                if (isActivityProcess) {
3769                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3770                    msg.obj = app;
3771                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3772                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3773                }
3774            }
3775            checkTime(startTime, "startProcess: done updating pids map");
3776        } catch (RuntimeException e) {
3777            Slog.e(TAG, "Failure starting process " + app.processName, e);
3778
3779            // Something went very wrong while trying to start this process; one
3780            // common case is when the package is frozen due to an active
3781            // upgrade. To recover, clean up any active bookkeeping related to
3782            // starting this process. (We already invoked this method once when
3783            // the package was initially frozen through KILL_APPLICATION_MSG, so
3784            // it doesn't hurt to use it again.)
3785            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3786                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3787        }
3788    }
3789
3790    void updateUsageStats(ActivityRecord component, boolean resumed) {
3791        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3792                "updateUsageStats: comp=" + component + "res=" + resumed);
3793        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3794        if (resumed) {
3795            if (mUsageStatsService != null) {
3796                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3798            }
3799            synchronized (stats) {
3800                stats.noteActivityResumedLocked(component.app.uid);
3801            }
3802        } else {
3803            if (mUsageStatsService != null) {
3804                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3805                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3806            }
3807            synchronized (stats) {
3808                stats.noteActivityPausedLocked(component.app.uid);
3809            }
3810        }
3811    }
3812
3813    Intent getHomeIntent() {
3814        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3815        intent.setComponent(mTopComponent);
3816        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3817        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3818            intent.addCategory(Intent.CATEGORY_HOME);
3819        }
3820        return intent;
3821    }
3822
3823    boolean startHomeActivityLocked(int userId, String reason) {
3824        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3825                && mTopAction == null) {
3826            // We are running in factory test mode, but unable to find
3827            // the factory test app, so just sit around displaying the
3828            // error message and don't try to start anything.
3829            return false;
3830        }
3831        Intent intent = getHomeIntent();
3832        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3833        if (aInfo != null) {
3834            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3835            // Don't do this if the home app is currently being
3836            // instrumented.
3837            aInfo = new ActivityInfo(aInfo);
3838            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3839            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3840                    aInfo.applicationInfo.uid, true);
3841            if (app == null || app.instrumentationClass == null) {
3842                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3843                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3844            }
3845        } else {
3846            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3847        }
3848
3849        return true;
3850    }
3851
3852    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3853        ActivityInfo ai = null;
3854        ComponentName comp = intent.getComponent();
3855        try {
3856            if (comp != null) {
3857                // Factory test.
3858                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3859            } else {
3860                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3861                        intent,
3862                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3863                        flags, userId);
3864
3865                if (info != null) {
3866                    ai = info.activityInfo;
3867                }
3868            }
3869        } catch (RemoteException e) {
3870            // ignore
3871        }
3872
3873        return ai;
3874    }
3875
3876    /**
3877     * Starts the "new version setup screen" if appropriate.
3878     */
3879    void startSetupActivityLocked() {
3880        // Only do this once per boot.
3881        if (mCheckedForSetup) {
3882            return;
3883        }
3884
3885        // We will show this screen if the current one is a different
3886        // version than the last one shown, and we are not running in
3887        // low-level factory test mode.
3888        final ContentResolver resolver = mContext.getContentResolver();
3889        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3890                Settings.Global.getInt(resolver,
3891                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3892            mCheckedForSetup = true;
3893
3894            // See if we should be showing the platform update setup UI.
3895            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3896            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3897                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3898            if (!ris.isEmpty()) {
3899                final ResolveInfo ri = ris.get(0);
3900                String vers = ri.activityInfo.metaData != null
3901                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3902                        : null;
3903                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3904                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3905                            Intent.METADATA_SETUP_VERSION);
3906                }
3907                String lastVers = Settings.Secure.getString(
3908                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3909                if (vers != null && !vers.equals(lastVers)) {
3910                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3911                    intent.setComponent(new ComponentName(
3912                            ri.activityInfo.packageName, ri.activityInfo.name));
3913                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3914                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3915                            null, 0, 0, 0, null, false, false, null, null, null);
3916                }
3917            }
3918        }
3919    }
3920
3921    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3922        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3923    }
3924
3925    void enforceNotIsolatedCaller(String caller) {
3926        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3927            throw new SecurityException("Isolated process not allowed to call " + caller);
3928        }
3929    }
3930
3931    void enforceShellRestriction(String restriction, int userHandle) {
3932        if (Binder.getCallingUid() == Process.SHELL_UID) {
3933            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3934                throw new SecurityException("Shell does not have permission to access user "
3935                        + userHandle);
3936            }
3937        }
3938    }
3939
3940    @Override
3941    public int getFrontActivityScreenCompatMode() {
3942        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3943        synchronized (this) {
3944            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3945        }
3946    }
3947
3948    @Override
3949    public void setFrontActivityScreenCompatMode(int mode) {
3950        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3951                "setFrontActivityScreenCompatMode");
3952        synchronized (this) {
3953            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3954        }
3955    }
3956
3957    @Override
3958    public int getPackageScreenCompatMode(String packageName) {
3959        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3960        synchronized (this) {
3961            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3962        }
3963    }
3964
3965    @Override
3966    public void setPackageScreenCompatMode(String packageName, int mode) {
3967        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3968                "setPackageScreenCompatMode");
3969        synchronized (this) {
3970            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3971        }
3972    }
3973
3974    @Override
3975    public boolean getPackageAskScreenCompat(String packageName) {
3976        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3977        synchronized (this) {
3978            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3979        }
3980    }
3981
3982    @Override
3983    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3984        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3985                "setPackageAskScreenCompat");
3986        synchronized (this) {
3987            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3988        }
3989    }
3990
3991    private boolean hasUsageStatsPermission(String callingPackage) {
3992        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3993                Binder.getCallingUid(), callingPackage);
3994        if (mode == AppOpsManager.MODE_DEFAULT) {
3995            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3996                    == PackageManager.PERMISSION_GRANTED;
3997        }
3998        return mode == AppOpsManager.MODE_ALLOWED;
3999    }
4000
4001    @Override
4002    public int getPackageProcessState(String packageName, String callingPackage) {
4003        if (!hasUsageStatsPermission(callingPackage)) {
4004            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4005                    "getPackageProcessState");
4006        }
4007
4008        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4009        synchronized (this) {
4010            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4011                final ProcessRecord proc = mLruProcesses.get(i);
4012                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4013                        || procState > proc.setProcState) {
4014                    boolean found = false;
4015                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4016                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4017                            procState = proc.setProcState;
4018                            found = true;
4019                        }
4020                    }
4021                    if (proc.pkgDeps != null && !found) {
4022                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4023                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4024                                procState = proc.setProcState;
4025                                break;
4026                            }
4027                        }
4028                    }
4029                }
4030            }
4031        }
4032        return procState;
4033    }
4034
4035    @Override
4036    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4037        synchronized (this) {
4038            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4039            if (app == null) {
4040                return false;
4041            }
4042            if (app.trimMemoryLevel < level && app.thread != null &&
4043                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4044                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4045                try {
4046                    app.thread.scheduleTrimMemory(level);
4047                    app.trimMemoryLevel = level;
4048                    return true;
4049                } catch (RemoteException e) {
4050                    // Fallthrough to failure case.
4051                }
4052            }
4053        }
4054        return false;
4055    }
4056
4057    private void dispatchProcessesChanged() {
4058        int N;
4059        synchronized (this) {
4060            N = mPendingProcessChanges.size();
4061            if (mActiveProcessChanges.length < N) {
4062                mActiveProcessChanges = new ProcessChangeItem[N];
4063            }
4064            mPendingProcessChanges.toArray(mActiveProcessChanges);
4065            mPendingProcessChanges.clear();
4066            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4067                    "*** Delivering " + N + " process changes");
4068        }
4069
4070        int i = mProcessObservers.beginBroadcast();
4071        while (i > 0) {
4072            i--;
4073            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4074            if (observer != null) {
4075                try {
4076                    for (int j=0; j<N; j++) {
4077                        ProcessChangeItem item = mActiveProcessChanges[j];
4078                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4079                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4080                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4081                                    + item.uid + ": " + item.foregroundActivities);
4082                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4083                                    item.foregroundActivities);
4084                        }
4085                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4086                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4087                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4088                                    + ": " + item.processState);
4089                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4090                        }
4091                    }
4092                } catch (RemoteException e) {
4093                }
4094            }
4095        }
4096        mProcessObservers.finishBroadcast();
4097
4098        synchronized (this) {
4099            for (int j=0; j<N; j++) {
4100                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4101            }
4102        }
4103    }
4104
4105    private void dispatchProcessDied(int pid, int uid) {
4106        int i = mProcessObservers.beginBroadcast();
4107        while (i > 0) {
4108            i--;
4109            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4110            if (observer != null) {
4111                try {
4112                    observer.onProcessDied(pid, uid);
4113                } catch (RemoteException e) {
4114                }
4115            }
4116        }
4117        mProcessObservers.finishBroadcast();
4118    }
4119
4120    private void dispatchUidsChanged() {
4121        int N;
4122        synchronized (this) {
4123            N = mPendingUidChanges.size();
4124            if (mActiveUidChanges.length < N) {
4125                mActiveUidChanges = new UidRecord.ChangeItem[N];
4126            }
4127            for (int i=0; i<N; i++) {
4128                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4129                mActiveUidChanges[i] = change;
4130                if (change.uidRecord != null) {
4131                    change.uidRecord.pendingChange = null;
4132                    change.uidRecord = null;
4133                }
4134            }
4135            mPendingUidChanges.clear();
4136            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4137                    "*** Delivering " + N + " uid changes");
4138        }
4139
4140        if (mLocalPowerManager != null) {
4141            for (int j=0; j<N; j++) {
4142                UidRecord.ChangeItem item = mActiveUidChanges[j];
4143                if (item.change == UidRecord.CHANGE_GONE
4144                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4145                    mLocalPowerManager.uidGone(item.uid);
4146                } else {
4147                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4148                }
4149            }
4150        }
4151
4152        int i = mUidObservers.beginBroadcast();
4153        while (i > 0) {
4154            i--;
4155            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4156            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4157            if (observer != null) {
4158                try {
4159                    for (int j=0; j<N; j++) {
4160                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4161                        final int change = item.change;
4162                        UidRecord validateUid = null;
4163                        if (VALIDATE_UID_STATES && i == 0) {
4164                            validateUid = mValidateUids.get(item.uid);
4165                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4166                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4167                                validateUid = new UidRecord(item.uid);
4168                                mValidateUids.put(item.uid, validateUid);
4169                            }
4170                        }
4171                        if (change == UidRecord.CHANGE_IDLE
4172                                || change == UidRecord.CHANGE_GONE_IDLE) {
4173                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4174                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                                        "UID idle uid=" + item.uid);
4176                                observer.onUidIdle(item.uid);
4177                            }
4178                            if (VALIDATE_UID_STATES && i == 0) {
4179                                if (validateUid != null) {
4180                                    validateUid.idle = true;
4181                                }
4182                            }
4183                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4184                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4185                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186                                        "UID active uid=" + item.uid);
4187                                observer.onUidActive(item.uid);
4188                            }
4189                            if (VALIDATE_UID_STATES && i == 0) {
4190                                validateUid.idle = false;
4191                            }
4192                        }
4193                        if (change == UidRecord.CHANGE_GONE
4194                                || change == UidRecord.CHANGE_GONE_IDLE) {
4195                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4196                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                        "UID gone uid=" + item.uid);
4198                                observer.onUidGone(item.uid);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                if (validateUid != null) {
4202                                    mValidateUids.remove(item.uid);
4203                                }
4204                            }
4205                        } else {
4206                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID CHANGED uid=" + item.uid
4209                                                + ": " + item.processState);
4210                                observer.onUidStateChanged(item.uid, item.processState);
4211                            }
4212                            if (VALIDATE_UID_STATES && i == 0) {
4213                                validateUid.curProcState = validateUid.setProcState
4214                                        = item.processState;
4215                            }
4216                        }
4217                    }
4218                } catch (RemoteException e) {
4219                }
4220            }
4221        }
4222        mUidObservers.finishBroadcast();
4223
4224        synchronized (this) {
4225            for (int j=0; j<N; j++) {
4226                mAvailUidChanges.add(mActiveUidChanges[j]);
4227            }
4228        }
4229    }
4230
4231    @Override
4232    public final int startActivity(IApplicationThread caller, String callingPackage,
4233            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4234            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4235        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4236                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4237                UserHandle.getCallingUserId());
4238    }
4239
4240    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4241        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4242        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4243                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4244                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4245
4246        // TODO: Switch to user app stacks here.
4247        String mimeType = intent.getType();
4248        final Uri data = intent.getData();
4249        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4250            mimeType = getProviderMimeType(data, userId);
4251        }
4252        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4253
4254        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4255        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4256                null, 0, 0, null, null, null, null, false, userId, container, null);
4257    }
4258
4259    @Override
4260    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4261            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4262            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4263        enforceNotIsolatedCaller("startActivity");
4264        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4265                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4266        // TODO: Switch to user app stacks here.
4267        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4268                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4269                profilerInfo, null, null, bOptions, false, userId, null, null);
4270    }
4271
4272    @Override
4273    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4274            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4275            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4276            int userId) {
4277
4278        // This is very dangerous -- it allows you to perform a start activity (including
4279        // permission grants) as any app that may launch one of your own activities.  So
4280        // we will only allow this to be done from activities that are part of the core framework,
4281        // and then only when they are running as the system.
4282        final ActivityRecord sourceRecord;
4283        final int targetUid;
4284        final String targetPackage;
4285        synchronized (this) {
4286            if (resultTo == null) {
4287                throw new SecurityException("Must be called from an activity");
4288            }
4289            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4290            if (sourceRecord == null) {
4291                throw new SecurityException("Called with bad activity token: " + resultTo);
4292            }
4293            if (!sourceRecord.info.packageName.equals("android")) {
4294                throw new SecurityException(
4295                        "Must be called from an activity that is declared in the android package");
4296            }
4297            if (sourceRecord.app == null) {
4298                throw new SecurityException("Called without a process attached to activity");
4299            }
4300            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4301                // This is still okay, as long as this activity is running under the
4302                // uid of the original calling activity.
4303                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4304                    throw new SecurityException(
4305                            "Calling activity in uid " + sourceRecord.app.uid
4306                                    + " must be system uid or original calling uid "
4307                                    + sourceRecord.launchedFromUid);
4308                }
4309            }
4310            if (ignoreTargetSecurity) {
4311                if (intent.getComponent() == null) {
4312                    throw new SecurityException(
4313                            "Component must be specified with ignoreTargetSecurity");
4314                }
4315                if (intent.getSelector() != null) {
4316                    throw new SecurityException(
4317                            "Selector not allowed with ignoreTargetSecurity");
4318                }
4319            }
4320            targetUid = sourceRecord.launchedFromUid;
4321            targetPackage = sourceRecord.launchedFromPackage;
4322        }
4323
4324        if (userId == UserHandle.USER_NULL) {
4325            userId = UserHandle.getUserId(sourceRecord.app.uid);
4326        }
4327
4328        // TODO: Switch to user app stacks here.
4329        try {
4330            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4331                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4332                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4333            return ret;
4334        } catch (SecurityException e) {
4335            // XXX need to figure out how to propagate to original app.
4336            // A SecurityException here is generally actually a fault of the original
4337            // calling activity (such as a fairly granting permissions), so propagate it
4338            // back to them.
4339            /*
4340            StringBuilder msg = new StringBuilder();
4341            msg.append("While launching");
4342            msg.append(intent.toString());
4343            msg.append(": ");
4344            msg.append(e.getMessage());
4345            */
4346            throw e;
4347        }
4348    }
4349
4350    @Override
4351    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4352            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4353            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4354        enforceNotIsolatedCaller("startActivityAndWait");
4355        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4356                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4357        WaitResult res = new WaitResult();
4358        // TODO: Switch to user app stacks here.
4359        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4360                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4361                bOptions, false, userId, null, null);
4362        return res;
4363    }
4364
4365    @Override
4366    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4367            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4368            int startFlags, Configuration config, Bundle bOptions, int userId) {
4369        enforceNotIsolatedCaller("startActivityWithConfig");
4370        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4371                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4372        // TODO: Switch to user app stacks here.
4373        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4374                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4375                null, null, config, bOptions, false, userId, null, null);
4376        return ret;
4377    }
4378
4379    @Override
4380    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4381            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4382            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4383            throws TransactionTooLargeException {
4384        enforceNotIsolatedCaller("startActivityIntentSender");
4385        // Refuse possible leaked file descriptors
4386        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4387            throw new IllegalArgumentException("File descriptors passed in Intent");
4388        }
4389
4390        IIntentSender sender = intent.getTarget();
4391        if (!(sender instanceof PendingIntentRecord)) {
4392            throw new IllegalArgumentException("Bad PendingIntent object");
4393        }
4394
4395        PendingIntentRecord pir = (PendingIntentRecord)sender;
4396
4397        synchronized (this) {
4398            // If this is coming from the currently resumed activity, it is
4399            // effectively saying that app switches are allowed at this point.
4400            final ActivityStack stack = getFocusedStack();
4401            if (stack.mResumedActivity != null &&
4402                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4403                mAppSwitchesAllowedTime = 0;
4404            }
4405        }
4406        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4407                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4408        return ret;
4409    }
4410
4411    @Override
4412    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4413            Intent intent, String resolvedType, IVoiceInteractionSession session,
4414            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4415            Bundle bOptions, int userId) {
4416        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4417                != PackageManager.PERMISSION_GRANTED) {
4418            String msg = "Permission Denial: startVoiceActivity() from pid="
4419                    + Binder.getCallingPid()
4420                    + ", uid=" + Binder.getCallingUid()
4421                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4422            Slog.w(TAG, msg);
4423            throw new SecurityException(msg);
4424        }
4425        if (session == null || interactor == null) {
4426            throw new NullPointerException("null session or interactor");
4427        }
4428        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4429                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4430        // TODO: Switch to user app stacks here.
4431        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4432                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4433                null, bOptions, false, userId, null, null);
4434    }
4435
4436    @Override
4437    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4438            throws RemoteException {
4439        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4440        synchronized (this) {
4441            ActivityRecord activity = getFocusedStack().topActivity();
4442            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4443                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4444            }
4445            if (mRunningVoice != null || activity.task.voiceSession != null
4446                    || activity.voiceSession != null) {
4447                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4448                return;
4449            }
4450            if (activity.pendingVoiceInteractionStart) {
4451                Slog.w(TAG, "Pending start of voice interaction already.");
4452                return;
4453            }
4454            activity.pendingVoiceInteractionStart = true;
4455        }
4456        LocalServices.getService(VoiceInteractionManagerInternal.class)
4457                .startLocalVoiceInteraction(callingActivity, options);
4458    }
4459
4460    @Override
4461    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4462        LocalServices.getService(VoiceInteractionManagerInternal.class)
4463                .stopLocalVoiceInteraction(callingActivity);
4464    }
4465
4466    @Override
4467    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4468        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4469                .supportsLocalVoiceInteraction();
4470    }
4471
4472    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4473            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4474        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4475        if (activityToCallback == null) return;
4476        activityToCallback.setVoiceSessionLocked(voiceSession);
4477
4478        // Inform the activity
4479        try {
4480            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4481                    voiceInteractor);
4482            long token = Binder.clearCallingIdentity();
4483            try {
4484                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4485            } finally {
4486                Binder.restoreCallingIdentity(token);
4487            }
4488            // TODO: VI Should we cache the activity so that it's easier to find later
4489            // rather than scan through all the stacks and activities?
4490        } catch (RemoteException re) {
4491            activityToCallback.clearVoiceSessionLocked();
4492            // TODO: VI Should this terminate the voice session?
4493        }
4494    }
4495
4496    @Override
4497    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4498        synchronized (this) {
4499            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4500                if (keepAwake) {
4501                    mVoiceWakeLock.acquire();
4502                } else {
4503                    mVoiceWakeLock.release();
4504                }
4505            }
4506        }
4507    }
4508
4509    @Override
4510    public boolean startNextMatchingActivity(IBinder callingActivity,
4511            Intent intent, Bundle bOptions) {
4512        // Refuse possible leaked file descriptors
4513        if (intent != null && intent.hasFileDescriptors() == true) {
4514            throw new IllegalArgumentException("File descriptors passed in Intent");
4515        }
4516        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4517
4518        synchronized (this) {
4519            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4520            if (r == null) {
4521                ActivityOptions.abort(options);
4522                return false;
4523            }
4524            if (r.app == null || r.app.thread == null) {
4525                // The caller is not running...  d'oh!
4526                ActivityOptions.abort(options);
4527                return false;
4528            }
4529            intent = new Intent(intent);
4530            // The caller is not allowed to change the data.
4531            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4532            // And we are resetting to find the next component...
4533            intent.setComponent(null);
4534
4535            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4536
4537            ActivityInfo aInfo = null;
4538            try {
4539                List<ResolveInfo> resolves =
4540                    AppGlobals.getPackageManager().queryIntentActivities(
4541                            intent, r.resolvedType,
4542                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4543                            UserHandle.getCallingUserId()).getList();
4544
4545                // Look for the original activity in the list...
4546                final int N = resolves != null ? resolves.size() : 0;
4547                for (int i=0; i<N; i++) {
4548                    ResolveInfo rInfo = resolves.get(i);
4549                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4550                            && rInfo.activityInfo.name.equals(r.info.name)) {
4551                        // We found the current one...  the next matching is
4552                        // after it.
4553                        i++;
4554                        if (i<N) {
4555                            aInfo = resolves.get(i).activityInfo;
4556                        }
4557                        if (debug) {
4558                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4559                                    + "/" + r.info.name);
4560                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4561                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4562                        }
4563                        break;
4564                    }
4565                }
4566            } catch (RemoteException e) {
4567            }
4568
4569            if (aInfo == null) {
4570                // Nobody who is next!
4571                ActivityOptions.abort(options);
4572                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4573                return false;
4574            }
4575
4576            intent.setComponent(new ComponentName(
4577                    aInfo.applicationInfo.packageName, aInfo.name));
4578            intent.setFlags(intent.getFlags()&~(
4579                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4580                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4581                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4582                    Intent.FLAG_ACTIVITY_NEW_TASK));
4583
4584            // Okay now we need to start the new activity, replacing the
4585            // currently running activity.  This is a little tricky because
4586            // we want to start the new one as if the current one is finished,
4587            // but not finish the current one first so that there is no flicker.
4588            // And thus...
4589            final boolean wasFinishing = r.finishing;
4590            r.finishing = true;
4591
4592            // Propagate reply information over to the new activity.
4593            final ActivityRecord resultTo = r.resultTo;
4594            final String resultWho = r.resultWho;
4595            final int requestCode = r.requestCode;
4596            r.resultTo = null;
4597            if (resultTo != null) {
4598                resultTo.removeResultsLocked(r, resultWho, requestCode);
4599            }
4600
4601            final long origId = Binder.clearCallingIdentity();
4602            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4603                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4604                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4605                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4606                    false, false, null, null, null);
4607            Binder.restoreCallingIdentity(origId);
4608
4609            r.finishing = wasFinishing;
4610            if (res != ActivityManager.START_SUCCESS) {
4611                return false;
4612            }
4613            return true;
4614        }
4615    }
4616
4617    @Override
4618    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4619        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: startActivityFromRecents called without " +
4621                    START_TASKS_FROM_RECENTS;
4622            Slog.w(TAG, msg);
4623            throw new SecurityException(msg);
4624        }
4625        final long origId = Binder.clearCallingIdentity();
4626        try {
4627            synchronized (this) {
4628                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4629            }
4630        } finally {
4631            Binder.restoreCallingIdentity(origId);
4632        }
4633    }
4634
4635    final int startActivityInPackage(int uid, String callingPackage,
4636            Intent intent, String resolvedType, IBinder resultTo,
4637            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4638            IActivityContainer container, TaskRecord inTask) {
4639
4640        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4641                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4642
4643        // TODO: Switch to user app stacks here.
4644        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4645                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4646                null, null, null, bOptions, false, userId, container, inTask);
4647        return ret;
4648    }
4649
4650    @Override
4651    public final int startActivities(IApplicationThread caller, String callingPackage,
4652            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4653            int userId) {
4654        enforceNotIsolatedCaller("startActivities");
4655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4656                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4657        // TODO: Switch to user app stacks here.
4658        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4659                resolvedTypes, resultTo, bOptions, userId);
4660        return ret;
4661    }
4662
4663    final int startActivitiesInPackage(int uid, String callingPackage,
4664            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4665            Bundle bOptions, int userId) {
4666
4667        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4668                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4669        // TODO: Switch to user app stacks here.
4670        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4671                resultTo, bOptions, userId);
4672        return ret;
4673    }
4674
4675    @Override
4676    public void reportActivityFullyDrawn(IBinder token) {
4677        synchronized (this) {
4678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679            if (r == null) {
4680                return;
4681            }
4682            r.reportFullyDrawnLocked();
4683        }
4684    }
4685
4686    @Override
4687    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4688        synchronized (this) {
4689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4690            if (r == null) {
4691                return;
4692            }
4693            TaskRecord task = r.task;
4694            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4695                // Fixed screen orientation isn't supported when activities aren't in full screen
4696                // mode.
4697                return;
4698            }
4699            final long origId = Binder.clearCallingIdentity();
4700            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4701            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4702                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4703            if (config != null) {
4704                r.frozenBeforeDestroy = true;
4705                if (!updateConfigurationLocked(config, r, false)) {
4706                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4707                }
4708            }
4709            Binder.restoreCallingIdentity(origId);
4710        }
4711    }
4712
4713    @Override
4714    public int getRequestedOrientation(IBinder token) {
4715        synchronized (this) {
4716            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4717            if (r == null) {
4718                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4719            }
4720            return mWindowManager.getAppOrientation(r.appToken);
4721        }
4722    }
4723
4724    /**
4725     * This is the internal entry point for handling Activity.finish().
4726     *
4727     * @param token The Binder token referencing the Activity we want to finish.
4728     * @param resultCode Result code, if any, from this Activity.
4729     * @param resultData Result data (Intent), if any, from this Activity.
4730     * @param finishTask Whether to finish the task associated with this Activity.
4731     *
4732     * @return Returns true if the activity successfully finished, or false if it is still running.
4733     */
4734    @Override
4735    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4736            int finishTask) {
4737        // Refuse possible leaked file descriptors
4738        if (resultData != null && resultData.hasFileDescriptors() == true) {
4739            throw new IllegalArgumentException("File descriptors passed in Intent");
4740        }
4741
4742        synchronized(this) {
4743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4744            if (r == null) {
4745                return true;
4746            }
4747            // Keep track of the root activity of the task before we finish it
4748            TaskRecord tr = r.task;
4749            ActivityRecord rootR = tr.getRootActivity();
4750            if (rootR == null) {
4751                Slog.w(TAG, "Finishing task with all activities already finished");
4752            }
4753            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4754            // finish.
4755            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4756                    mStackSupervisor.isLastLockedTask(tr)) {
4757                Slog.i(TAG, "Not finishing task in lock task mode");
4758                mStackSupervisor.showLockTaskToast();
4759                return false;
4760            }
4761            if (mController != null) {
4762                // Find the first activity that is not finishing.
4763                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4764                if (next != null) {
4765                    // ask watcher if this is allowed
4766                    boolean resumeOK = true;
4767                    try {
4768                        resumeOK = mController.activityResuming(next.packageName);
4769                    } catch (RemoteException e) {
4770                        mController = null;
4771                        Watchdog.getInstance().setActivityController(null);
4772                    }
4773
4774                    if (!resumeOK) {
4775                        Slog.i(TAG, "Not finishing activity because controller resumed");
4776                        return false;
4777                    }
4778                }
4779            }
4780            final long origId = Binder.clearCallingIdentity();
4781            try {
4782                boolean res;
4783                final boolean finishWithRootActivity =
4784                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4785                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4786                        || (finishWithRootActivity && r == rootR)) {
4787                    // If requested, remove the task that is associated to this activity only if it
4788                    // was the root activity in the task. The result code and data is ignored
4789                    // because we don't support returning them across task boundaries. Also, to
4790                    // keep backwards compatibility we remove the task from recents when finishing
4791                    // task with root activity.
4792                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4793                    if (!res) {
4794                        Slog.i(TAG, "Removing task failed to finish activity");
4795                    }
4796                } else {
4797                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4798                            resultData, "app-request", true);
4799                    if (!res) {
4800                        Slog.i(TAG, "Failed to finish by app-request");
4801                    }
4802                }
4803                return res;
4804            } finally {
4805                Binder.restoreCallingIdentity(origId);
4806            }
4807        }
4808    }
4809
4810    @Override
4811    public final void finishHeavyWeightApp() {
4812        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4813                != PackageManager.PERMISSION_GRANTED) {
4814            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4815                    + Binder.getCallingPid()
4816                    + ", uid=" + Binder.getCallingUid()
4817                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4818            Slog.w(TAG, msg);
4819            throw new SecurityException(msg);
4820        }
4821
4822        synchronized(this) {
4823            if (mHeavyWeightProcess == null) {
4824                return;
4825            }
4826
4827            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4828            for (int i = 0; i < activities.size(); i++) {
4829                ActivityRecord r = activities.get(i);
4830                if (!r.finishing && r.isInStackLocked()) {
4831                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4832                            null, "finish-heavy", true);
4833                }
4834            }
4835
4836            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4837                    mHeavyWeightProcess.userId, 0));
4838            mHeavyWeightProcess = null;
4839        }
4840    }
4841
4842    @Override
4843    public void crashApplication(int uid, int initialPid, String packageName,
4844            String message) {
4845        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4846                != PackageManager.PERMISSION_GRANTED) {
4847            String msg = "Permission Denial: crashApplication() from pid="
4848                    + Binder.getCallingPid()
4849                    + ", uid=" + Binder.getCallingUid()
4850                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4851            Slog.w(TAG, msg);
4852            throw new SecurityException(msg);
4853        }
4854
4855        synchronized(this) {
4856            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4857        }
4858    }
4859
4860    @Override
4861    public final void finishSubActivity(IBinder token, String resultWho,
4862            int requestCode) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866            if (r != null) {
4867                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4868            }
4869            Binder.restoreCallingIdentity(origId);
4870        }
4871    }
4872
4873    @Override
4874    public boolean finishActivityAffinity(IBinder token) {
4875        synchronized(this) {
4876            final long origId = Binder.clearCallingIdentity();
4877            try {
4878                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4879                if (r == null) {
4880                    return false;
4881                }
4882
4883                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4884                // can finish.
4885                final TaskRecord task = r.task;
4886                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4887                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4888                    mStackSupervisor.showLockTaskToast();
4889                    return false;
4890                }
4891                return task.stack.finishActivityAffinityLocked(r);
4892            } finally {
4893                Binder.restoreCallingIdentity(origId);
4894            }
4895        }
4896    }
4897
4898    @Override
4899    public void finishVoiceTask(IVoiceInteractionSession session) {
4900        synchronized (this) {
4901            final long origId = Binder.clearCallingIdentity();
4902            try {
4903                // TODO: VI Consider treating local voice interactions and voice tasks
4904                // differently here
4905                mStackSupervisor.finishVoiceTask(session);
4906            } finally {
4907                Binder.restoreCallingIdentity(origId);
4908            }
4909        }
4910
4911    }
4912
4913    @Override
4914    public boolean releaseActivityInstance(IBinder token) {
4915        synchronized(this) {
4916            final long origId = Binder.clearCallingIdentity();
4917            try {
4918                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919                if (r == null) {
4920                    return false;
4921                }
4922                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4923            } finally {
4924                Binder.restoreCallingIdentity(origId);
4925            }
4926        }
4927    }
4928
4929    @Override
4930    public void releaseSomeActivities(IApplicationThread appInt) {
4931        synchronized(this) {
4932            final long origId = Binder.clearCallingIdentity();
4933            try {
4934                ProcessRecord app = getRecordForAppLocked(appInt);
4935                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4936            } finally {
4937                Binder.restoreCallingIdentity(origId);
4938            }
4939        }
4940    }
4941
4942    @Override
4943    public boolean willActivityBeVisible(IBinder token) {
4944        synchronized(this) {
4945            ActivityStack stack = ActivityRecord.getStackLocked(token);
4946            if (stack != null) {
4947                return stack.willActivityBeVisibleLocked(token);
4948            }
4949            return false;
4950        }
4951    }
4952
4953    @Override
4954    public void overridePendingTransition(IBinder token, String packageName,
4955            int enterAnim, int exitAnim) {
4956        synchronized(this) {
4957            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4958            if (self == null) {
4959                return;
4960            }
4961
4962            final long origId = Binder.clearCallingIdentity();
4963
4964            if (self.state == ActivityState.RESUMED
4965                    || self.state == ActivityState.PAUSING) {
4966                mWindowManager.overridePendingAppTransition(packageName,
4967                        enterAnim, exitAnim, null);
4968            }
4969
4970            Binder.restoreCallingIdentity(origId);
4971        }
4972    }
4973
4974    /**
4975     * Main function for removing an existing process from the activity manager
4976     * as a result of that process going away.  Clears out all connections
4977     * to the process.
4978     */
4979    private final void handleAppDiedLocked(ProcessRecord app,
4980            boolean restarting, boolean allowRestart) {
4981        int pid = app.pid;
4982        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4983        if (!kept && !restarting) {
4984            removeLruProcessLocked(app);
4985            if (pid > 0) {
4986                ProcessList.remove(pid);
4987            }
4988        }
4989
4990        if (mProfileProc == app) {
4991            clearProfilerLocked();
4992        }
4993
4994        // Remove this application's activities from active lists.
4995        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4996
4997        app.activities.clear();
4998
4999        if (app.instrumentationClass != null) {
5000            Slog.w(TAG, "Crash of app " + app.processName
5001                  + " running instrumentation " + app.instrumentationClass);
5002            Bundle info = new Bundle();
5003            info.putString("shortMsg", "Process crashed.");
5004            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5005        }
5006
5007        if (!restarting && hasVisibleActivities
5008                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5009            // If there was nothing to resume, and we are not already restarting this process, but
5010            // there is a visible activity that is hosted by the process...  then make sure all
5011            // visible activities are running, taking care of restarting this process.
5012            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5013        }
5014    }
5015
5016    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5017        IBinder threadBinder = thread.asBinder();
5018        // Find the application record.
5019        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5020            ProcessRecord rec = mLruProcesses.get(i);
5021            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5022                return i;
5023            }
5024        }
5025        return -1;
5026    }
5027
5028    final ProcessRecord getRecordForAppLocked(
5029            IApplicationThread thread) {
5030        if (thread == null) {
5031            return null;
5032        }
5033
5034        int appIndex = getLRURecordIndexForAppLocked(thread);
5035        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5036    }
5037
5038    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5039        // If there are no longer any background processes running,
5040        // and the app that died was not running instrumentation,
5041        // then tell everyone we are now low on memory.
5042        boolean haveBg = false;
5043        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5044            ProcessRecord rec = mLruProcesses.get(i);
5045            if (rec.thread != null
5046                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5047                haveBg = true;
5048                break;
5049            }
5050        }
5051
5052        if (!haveBg) {
5053            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5054            if (doReport) {
5055                long now = SystemClock.uptimeMillis();
5056                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5057                    doReport = false;
5058                } else {
5059                    mLastMemUsageReportTime = now;
5060                }
5061            }
5062            final ArrayList<ProcessMemInfo> memInfos
5063                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5064            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5065            long now = SystemClock.uptimeMillis();
5066            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5067                ProcessRecord rec = mLruProcesses.get(i);
5068                if (rec == dyingProc || rec.thread == null) {
5069                    continue;
5070                }
5071                if (doReport) {
5072                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5073                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5074                }
5075                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5076                    // The low memory report is overriding any current
5077                    // state for a GC request.  Make sure to do
5078                    // heavy/important/visible/foreground processes first.
5079                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5080                        rec.lastRequestedGc = 0;
5081                    } else {
5082                        rec.lastRequestedGc = rec.lastLowMemory;
5083                    }
5084                    rec.reportLowMemory = true;
5085                    rec.lastLowMemory = now;
5086                    mProcessesToGc.remove(rec);
5087                    addProcessToGcListLocked(rec);
5088                }
5089            }
5090            if (doReport) {
5091                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5092                mHandler.sendMessage(msg);
5093            }
5094            scheduleAppGcsLocked();
5095        }
5096    }
5097
5098    final void appDiedLocked(ProcessRecord app) {
5099       appDiedLocked(app, app.pid, app.thread, false);
5100    }
5101
5102    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5103            boolean fromBinderDied) {
5104        // First check if this ProcessRecord is actually active for the pid.
5105        synchronized (mPidsSelfLocked) {
5106            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5107            if (curProc != app) {
5108                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5109                return;
5110            }
5111        }
5112
5113        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5114        synchronized (stats) {
5115            stats.noteProcessDiedLocked(app.info.uid, pid);
5116        }
5117
5118        if (!app.killed) {
5119            if (!fromBinderDied) {
5120                Process.killProcessQuiet(pid);
5121            }
5122            killProcessGroup(app.uid, pid);
5123            app.killed = true;
5124        }
5125
5126        // Clean up already done if the process has been re-started.
5127        if (app.pid == pid && app.thread != null &&
5128                app.thread.asBinder() == thread.asBinder()) {
5129            boolean doLowMem = app.instrumentationClass == null;
5130            boolean doOomAdj = doLowMem;
5131            if (!app.killedByAm) {
5132                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5133                        + ") has died");
5134                mAllowLowerMemLevel = true;
5135            } else {
5136                // Note that we always want to do oom adj to update our state with the
5137                // new number of procs.
5138                mAllowLowerMemLevel = false;
5139                doLowMem = false;
5140            }
5141            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5142            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5143                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5144            handleAppDiedLocked(app, false, true);
5145
5146            if (doOomAdj) {
5147                updateOomAdjLocked();
5148            }
5149            if (doLowMem) {
5150                doLowMemReportIfNeededLocked(app);
5151            }
5152        } else if (app.pid != pid) {
5153            // A new process has already been started.
5154            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5155                    + ") has died and restarted (pid " + app.pid + ").");
5156            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5157        } else if (DEBUG_PROCESSES) {
5158            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5159                    + thread.asBinder());
5160        }
5161    }
5162
5163    /**
5164     * If a stack trace dump file is configured, dump process stack traces.
5165     * @param clearTraces causes the dump file to be erased prior to the new
5166     *    traces being written, if true; when false, the new traces will be
5167     *    appended to any existing file content.
5168     * @param firstPids of dalvik VM processes to dump stack traces for first
5169     * @param lastPids of dalvik VM processes to dump stack traces for last
5170     * @param nativeProcs optional list of native process names to dump stack crawls
5171     * @return file containing stack traces, or null if no dump file is configured
5172     */
5173    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5174            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5175        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5176        if (tracesPath == null || tracesPath.length() == 0) {
5177            return null;
5178        }
5179
5180        File tracesFile = new File(tracesPath);
5181        try {
5182            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5183            tracesFile.createNewFile();
5184            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5185        } catch (IOException e) {
5186            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5187            return null;
5188        }
5189
5190        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5191        return tracesFile;
5192    }
5193
5194    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5195            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5196        // Use a FileObserver to detect when traces finish writing.
5197        // The order of traces is considered important to maintain for legibility.
5198        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5199            @Override
5200            public synchronized void onEvent(int event, String path) { notify(); }
5201        };
5202
5203        try {
5204            observer.startWatching();
5205
5206            // First collect all of the stacks of the most important pids.
5207            if (firstPids != null) {
5208                try {
5209                    int num = firstPids.size();
5210                    for (int i = 0; i < num; i++) {
5211                        synchronized (observer) {
5212                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5213                                    + firstPids.get(i));
5214                            final long sime = SystemClock.elapsedRealtime();
5215                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5216                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5217                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5218                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5219                        }
5220                    }
5221                } catch (InterruptedException e) {
5222                    Slog.wtf(TAG, e);
5223                }
5224            }
5225
5226            // Next collect the stacks of the native pids
5227            if (nativeProcs != null) {
5228                int[] pids = Process.getPidsForCommands(nativeProcs);
5229                if (pids != null) {
5230                    for (int pid : pids) {
5231                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5232                        final long sime = SystemClock.elapsedRealtime();
5233                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5234                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5235                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5236                    }
5237                }
5238            }
5239
5240            // Lastly, measure CPU usage.
5241            if (processCpuTracker != null) {
5242                processCpuTracker.init();
5243                System.gc();
5244                processCpuTracker.update();
5245                try {
5246                    synchronized (processCpuTracker) {
5247                        processCpuTracker.wait(500); // measure over 1/2 second.
5248                    }
5249                } catch (InterruptedException e) {
5250                }
5251                processCpuTracker.update();
5252
5253                // We'll take the stack crawls of just the top apps using CPU.
5254                final int N = processCpuTracker.countWorkingStats();
5255                int numProcs = 0;
5256                for (int i=0; i<N && numProcs<5; i++) {
5257                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5258                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5259                        numProcs++;
5260                        try {
5261                            synchronized (observer) {
5262                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5263                                        + stats.pid);
5264                                final long stime = SystemClock.elapsedRealtime();
5265                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5266                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5267                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5268                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5269                            }
5270                        } catch (InterruptedException e) {
5271                            Slog.wtf(TAG, e);
5272                        }
5273                    } else if (DEBUG_ANR) {
5274                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5275                                + stats.pid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            observer.stopWatching();
5281        }
5282    }
5283
5284    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5285        if (true || IS_USER_BUILD) {
5286            return;
5287        }
5288        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5289        if (tracesPath == null || tracesPath.length() == 0) {
5290            return;
5291        }
5292
5293        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5294        StrictMode.allowThreadDiskWrites();
5295        try {
5296            final File tracesFile = new File(tracesPath);
5297            final File tracesDir = tracesFile.getParentFile();
5298            final File tracesTmp = new File(tracesDir, "__tmp__");
5299            try {
5300                if (tracesFile.exists()) {
5301                    tracesTmp.delete();
5302                    tracesFile.renameTo(tracesTmp);
5303                }
5304                StringBuilder sb = new StringBuilder();
5305                Time tobj = new Time();
5306                tobj.set(System.currentTimeMillis());
5307                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5308                sb.append(": ");
5309                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5310                sb.append(" since ");
5311                sb.append(msg);
5312                FileOutputStream fos = new FileOutputStream(tracesFile);
5313                fos.write(sb.toString().getBytes());
5314                if (app == null) {
5315                    fos.write("\n*** No application process!".getBytes());
5316                }
5317                fos.close();
5318                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5319            } catch (IOException e) {
5320                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5321                return;
5322            }
5323
5324            if (app != null) {
5325                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5326                firstPids.add(app.pid);
5327                dumpStackTraces(tracesPath, firstPids, null, null, null);
5328            }
5329
5330            File lastTracesFile = null;
5331            File curTracesFile = null;
5332            for (int i=9; i>=0; i--) {
5333                String name = String.format(Locale.US, "slow%02d.txt", i);
5334                curTracesFile = new File(tracesDir, name);
5335                if (curTracesFile.exists()) {
5336                    if (lastTracesFile != null) {
5337                        curTracesFile.renameTo(lastTracesFile);
5338                    } else {
5339                        curTracesFile.delete();
5340                    }
5341                }
5342                lastTracesFile = curTracesFile;
5343            }
5344            tracesFile.renameTo(curTracesFile);
5345            if (tracesTmp.exists()) {
5346                tracesTmp.renameTo(tracesFile);
5347            }
5348        } finally {
5349            StrictMode.setThreadPolicy(oldPolicy);
5350        }
5351    }
5352
5353    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5354        if (!mLaunchWarningShown) {
5355            mLaunchWarningShown = true;
5356            mUiHandler.post(new Runnable() {
5357                @Override
5358                public void run() {
5359                    synchronized (ActivityManagerService.this) {
5360                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5361                        d.show();
5362                        mUiHandler.postDelayed(new Runnable() {
5363                            @Override
5364                            public void run() {
5365                                synchronized (ActivityManagerService.this) {
5366                                    d.dismiss();
5367                                    mLaunchWarningShown = false;
5368                                }
5369                            }
5370                        }, 4000);
5371                    }
5372                }
5373            });
5374        }
5375    }
5376
5377    @Override
5378    public boolean clearApplicationUserData(final String packageName,
5379            final IPackageDataObserver observer, int userId) {
5380        enforceNotIsolatedCaller("clearApplicationUserData");
5381        int uid = Binder.getCallingUid();
5382        int pid = Binder.getCallingPid();
5383        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5384                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5385
5386
5387        long callingId = Binder.clearCallingIdentity();
5388        try {
5389            IPackageManager pm = AppGlobals.getPackageManager();
5390            int pkgUid = -1;
5391            synchronized(this) {
5392                if (getPackageManagerInternalLocked().canPackageBeWiped(
5393                        userId, packageName)) {
5394                    throw new SecurityException(
5395                            "Cannot clear data for a device owner or a profile owner");
5396                }
5397
5398                try {
5399                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5400                } catch (RemoteException e) {
5401                }
5402                if (pkgUid == -1) {
5403                    Slog.w(TAG, "Invalid packageName: " + packageName);
5404                    if (observer != null) {
5405                        try {
5406                            observer.onRemoveCompleted(packageName, false);
5407                        } catch (RemoteException e) {
5408                            Slog.i(TAG, "Observer no longer exists.");
5409                        }
5410                    }
5411                    return false;
5412                }
5413                if (uid == pkgUid || checkComponentPermission(
5414                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5415                        pid, uid, -1, true)
5416                        == PackageManager.PERMISSION_GRANTED) {
5417                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5418                } else {
5419                    throw new SecurityException("PID " + pid + " does not have permission "
5420                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5421                                    + " of package " + packageName);
5422                }
5423
5424                // Remove all tasks match the cleared application package and user
5425                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5426                    final TaskRecord tr = mRecentTasks.get(i);
5427                    final String taskPackageName =
5428                            tr.getBaseIntent().getComponent().getPackageName();
5429                    if (tr.userId != userId) continue;
5430                    if (!taskPackageName.equals(packageName)) continue;
5431                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5432                }
5433            }
5434
5435            final int pkgUidF = pkgUid;
5436            final int userIdF = userId;
5437            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5438                @Override
5439                public void onRemoveCompleted(String packageName, boolean succeeded)
5440                        throws RemoteException {
5441                    synchronized (ActivityManagerService.this) {
5442                        finishForceStopPackageLocked(packageName, pkgUidF);
5443                    }
5444
5445                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5446                            Uri.fromParts("package", packageName, null));
5447                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5448                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5449                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5450                            null, null, 0, null, null, null, null, false, false, userIdF);
5451
5452                    if (observer != null) {
5453                        observer.onRemoveCompleted(packageName, succeeded);
5454                    }
5455                }
5456            };
5457
5458            try {
5459                // Clear application user data
5460                pm.clearApplicationUserData(packageName, localObserver, userId);
5461
5462                synchronized(this) {
5463                    // Remove all permissions granted from/to this package
5464                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5465                }
5466
5467                // Remove all zen rules created by this package; revoke it's zen access.
5468                INotificationManager inm = NotificationManager.getService();
5469                inm.removeAutomaticZenRules(packageName);
5470                inm.setNotificationPolicyAccessGranted(packageName, false);
5471
5472            } catch (RemoteException e) {
5473            }
5474        } finally {
5475            Binder.restoreCallingIdentity(callingId);
5476        }
5477        return true;
5478    }
5479
5480    @Override
5481    public void killBackgroundProcesses(final String packageName, int userId) {
5482        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5483                != PackageManager.PERMISSION_GRANTED &&
5484                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5485                        != PackageManager.PERMISSION_GRANTED) {
5486            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5487                    + Binder.getCallingPid()
5488                    + ", uid=" + Binder.getCallingUid()
5489                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5490            Slog.w(TAG, msg);
5491            throw new SecurityException(msg);
5492        }
5493
5494        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5495                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5496        long callingId = Binder.clearCallingIdentity();
5497        try {
5498            IPackageManager pm = AppGlobals.getPackageManager();
5499            synchronized(this) {
5500                int appId = -1;
5501                try {
5502                    appId = UserHandle.getAppId(
5503                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5504                } catch (RemoteException e) {
5505                }
5506                if (appId == -1) {
5507                    Slog.w(TAG, "Invalid packageName: " + packageName);
5508                    return;
5509                }
5510                killPackageProcessesLocked(packageName, appId, userId,
5511                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5512            }
5513        } finally {
5514            Binder.restoreCallingIdentity(callingId);
5515        }
5516    }
5517
5518    @Override
5519    public void killAllBackgroundProcesses() {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5523                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5524                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5525            Slog.w(TAG, msg);
5526            throw new SecurityException(msg);
5527        }
5528
5529        final long callingId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5533                final int NP = mProcessNames.getMap().size();
5534                for (int ip = 0; ip < NP; ip++) {
5535                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536                    final int NA = apps.size();
5537                    for (int ia = 0; ia < NA; ia++) {
5538                        final ProcessRecord app = apps.valueAt(ia);
5539                        if (app.persistent) {
5540                            // We don't kill persistent processes.
5541                            continue;
5542                        }
5543                        if (app.removed) {
5544                            procs.add(app);
5545                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5546                            app.removed = true;
5547                            procs.add(app);
5548                        }
5549                    }
5550                }
5551
5552                final int N = procs.size();
5553                for (int i = 0; i < N; i++) {
5554                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5555                }
5556
5557                mAllowLowerMemLevel = true;
5558
5559                updateOomAdjLocked();
5560                doLowMemReportIfNeededLocked(null);
5561            }
5562        } finally {
5563            Binder.restoreCallingIdentity(callingId);
5564        }
5565    }
5566
5567    /**
5568     * Kills all background processes, except those matching any of the
5569     * specified properties.
5570     *
5571     * @param minTargetSdk the target SDK version at or above which to preserve
5572     *                     processes, or {@code -1} to ignore the target SDK
5573     * @param maxProcState the process state at or below which to preserve
5574     *                     processes, or {@code -1} to ignore the process state
5575     */
5576    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5577        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5578                != PackageManager.PERMISSION_GRANTED) {
5579            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5580                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5581                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5582            Slog.w(TAG, msg);
5583            throw new SecurityException(msg);
5584        }
5585
5586        final long callingId = Binder.clearCallingIdentity();
5587        try {
5588            synchronized (this) {
5589                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5590                final int NP = mProcessNames.getMap().size();
5591                for (int ip = 0; ip < NP; ip++) {
5592                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5593                    final int NA = apps.size();
5594                    for (int ia = 0; ia < NA; ia++) {
5595                        final ProcessRecord app = apps.valueAt(ia);
5596                        if (app.removed) {
5597                            procs.add(app);
5598                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5599                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5600                            app.removed = true;
5601                            procs.add(app);
5602                        }
5603                    }
5604                }
5605
5606                final int N = procs.size();
5607                for (int i = 0; i < N; i++) {
5608                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5609                }
5610            }
5611        } finally {
5612            Binder.restoreCallingIdentity(callingId);
5613        }
5614    }
5615
5616    @Override
5617    public void forceStopPackage(final String packageName, int userId) {
5618        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5619                != PackageManager.PERMISSION_GRANTED) {
5620            String msg = "Permission Denial: forceStopPackage() from pid="
5621                    + Binder.getCallingPid()
5622                    + ", uid=" + Binder.getCallingUid()
5623                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5624            Slog.w(TAG, msg);
5625            throw new SecurityException(msg);
5626        }
5627        final int callingPid = Binder.getCallingPid();
5628        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5629                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5630        long callingId = Binder.clearCallingIdentity();
5631        try {
5632            IPackageManager pm = AppGlobals.getPackageManager();
5633            synchronized(this) {
5634                int[] users = userId == UserHandle.USER_ALL
5635                        ? mUserController.getUsers() : new int[] { userId };
5636                for (int user : users) {
5637                    int pkgUid = -1;
5638                    try {
5639                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5640                                user);
5641                    } catch (RemoteException e) {
5642                    }
5643                    if (pkgUid == -1) {
5644                        Slog.w(TAG, "Invalid packageName: " + packageName);
5645                        continue;
5646                    }
5647                    try {
5648                        pm.setPackageStoppedState(packageName, true, user);
5649                    } catch (RemoteException e) {
5650                    } catch (IllegalArgumentException e) {
5651                        Slog.w(TAG, "Failed trying to unstop package "
5652                                + packageName + ": " + e);
5653                    }
5654                    if (mUserController.isUserRunningLocked(user, 0)) {
5655                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5656                        finishForceStopPackageLocked(packageName, pkgUid);
5657                    }
5658                }
5659            }
5660        } finally {
5661            Binder.restoreCallingIdentity(callingId);
5662        }
5663    }
5664
5665    @Override
5666    public void addPackageDependency(String packageName) {
5667        synchronized (this) {
5668            int callingPid = Binder.getCallingPid();
5669            if (callingPid == Process.myPid()) {
5670                //  Yeah, um, no.
5671                return;
5672            }
5673            ProcessRecord proc;
5674            synchronized (mPidsSelfLocked) {
5675                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5676            }
5677            if (proc != null) {
5678                if (proc.pkgDeps == null) {
5679                    proc.pkgDeps = new ArraySet<String>(1);
5680                }
5681                proc.pkgDeps.add(packageName);
5682            }
5683        }
5684    }
5685
5686    /*
5687     * The pkg name and app id have to be specified.
5688     */
5689    @Override
5690    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5691        if (pkg == null) {
5692            return;
5693        }
5694        // Make sure the uid is valid.
5695        if (appid < 0) {
5696            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5697            return;
5698        }
5699        int callerUid = Binder.getCallingUid();
5700        // Only the system server can kill an application
5701        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5702            // Post an aysnc message to kill the application
5703            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5704            msg.arg1 = appid;
5705            msg.arg2 = 0;
5706            Bundle bundle = new Bundle();
5707            bundle.putString("pkg", pkg);
5708            bundle.putString("reason", reason);
5709            msg.obj = bundle;
5710            mHandler.sendMessage(msg);
5711        } else {
5712            throw new SecurityException(callerUid + " cannot kill pkg: " +
5713                    pkg);
5714        }
5715    }
5716
5717    @Override
5718    public void closeSystemDialogs(String reason) {
5719        enforceNotIsolatedCaller("closeSystemDialogs");
5720
5721        final int pid = Binder.getCallingPid();
5722        final int uid = Binder.getCallingUid();
5723        final long origId = Binder.clearCallingIdentity();
5724        try {
5725            synchronized (this) {
5726                // Only allow this from foreground processes, so that background
5727                // applications can't abuse it to prevent system UI from being shown.
5728                if (uid >= Process.FIRST_APPLICATION_UID) {
5729                    ProcessRecord proc;
5730                    synchronized (mPidsSelfLocked) {
5731                        proc = mPidsSelfLocked.get(pid);
5732                    }
5733                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5734                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5735                                + " from background process " + proc);
5736                        return;
5737                    }
5738                }
5739                closeSystemDialogsLocked(reason);
5740            }
5741        } finally {
5742            Binder.restoreCallingIdentity(origId);
5743        }
5744    }
5745
5746    void closeSystemDialogsLocked(String reason) {
5747        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5748        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5749                | Intent.FLAG_RECEIVER_FOREGROUND);
5750        if (reason != null) {
5751            intent.putExtra("reason", reason);
5752        }
5753        mWindowManager.closeSystemDialogs(reason);
5754
5755        mStackSupervisor.closeSystemDialogsLocked();
5756
5757        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5758                AppOpsManager.OP_NONE, null, false, false,
5759                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5760    }
5761
5762    @Override
5763    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5764        enforceNotIsolatedCaller("getProcessMemoryInfo");
5765        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5766        for (int i=pids.length-1; i>=0; i--) {
5767            ProcessRecord proc;
5768            int oomAdj;
5769            synchronized (this) {
5770                synchronized (mPidsSelfLocked) {
5771                    proc = mPidsSelfLocked.get(pids[i]);
5772                    oomAdj = proc != null ? proc.setAdj : 0;
5773                }
5774            }
5775            infos[i] = new Debug.MemoryInfo();
5776            Debug.getMemoryInfo(pids[i], infos[i]);
5777            if (proc != null) {
5778                synchronized (this) {
5779                    if (proc.thread != null && proc.setAdj == oomAdj) {
5780                        // Record this for posterity if the process has been stable.
5781                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5782                                infos[i].getTotalUss(), false, proc.pkgList);
5783                    }
5784                }
5785            }
5786        }
5787        return infos;
5788    }
5789
5790    @Override
5791    public long[] getProcessPss(int[] pids) {
5792        enforceNotIsolatedCaller("getProcessPss");
5793        long[] pss = new long[pids.length];
5794        for (int i=pids.length-1; i>=0; i--) {
5795            ProcessRecord proc;
5796            int oomAdj;
5797            synchronized (this) {
5798                synchronized (mPidsSelfLocked) {
5799                    proc = mPidsSelfLocked.get(pids[i]);
5800                    oomAdj = proc != null ? proc.setAdj : 0;
5801                }
5802            }
5803            long[] tmpUss = new long[1];
5804            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5805            if (proc != null) {
5806                synchronized (this) {
5807                    if (proc.thread != null && proc.setAdj == oomAdj) {
5808                        // Record this for posterity if the process has been stable.
5809                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5810                    }
5811                }
5812            }
5813        }
5814        return pss;
5815    }
5816
5817    @Override
5818    public void killApplicationProcess(String processName, int uid) {
5819        if (processName == null) {
5820            return;
5821        }
5822
5823        int callerUid = Binder.getCallingUid();
5824        // Only the system server can kill an application
5825        if (callerUid == Process.SYSTEM_UID) {
5826            synchronized (this) {
5827                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5828                if (app != null && app.thread != null) {
5829                    try {
5830                        app.thread.scheduleSuicide();
5831                    } catch (RemoteException e) {
5832                        // If the other end already died, then our work here is done.
5833                    }
5834                } else {
5835                    Slog.w(TAG, "Process/uid not found attempting kill of "
5836                            + processName + " / " + uid);
5837                }
5838            }
5839        } else {
5840            throw new SecurityException(callerUid + " cannot kill app process: " +
5841                    processName);
5842        }
5843    }
5844
5845    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5846        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5847                false, true, false, false, UserHandle.getUserId(uid), reason);
5848    }
5849
5850    private void finishForceStopPackageLocked(final String packageName, int uid) {
5851        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5852                Uri.fromParts("package", packageName, null));
5853        if (!mProcessesReady) {
5854            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855                    | Intent.FLAG_RECEIVER_FOREGROUND);
5856        }
5857        intent.putExtra(Intent.EXTRA_UID, uid);
5858        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5859        broadcastIntentLocked(null, null, intent,
5860                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5861                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5862    }
5863
5864
5865    private final boolean killPackageProcessesLocked(String packageName, int appId,
5866            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5867            boolean doit, boolean evenPersistent, String reason) {
5868        ArrayList<ProcessRecord> procs = new ArrayList<>();
5869
5870        // Remove all processes this package may have touched: all with the
5871        // same UID (except for the system or root user), and all whose name
5872        // matches the package name.
5873        final int NP = mProcessNames.getMap().size();
5874        for (int ip=0; ip<NP; ip++) {
5875            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5876            final int NA = apps.size();
5877            for (int ia=0; ia<NA; ia++) {
5878                ProcessRecord app = apps.valueAt(ia);
5879                if (app.persistent && !evenPersistent) {
5880                    // we don't kill persistent processes
5881                    continue;
5882                }
5883                if (app.removed) {
5884                    if (doit) {
5885                        procs.add(app);
5886                    }
5887                    continue;
5888                }
5889
5890                // Skip process if it doesn't meet our oom adj requirement.
5891                if (app.setAdj < minOomAdj) {
5892                    continue;
5893                }
5894
5895                // If no package is specified, we call all processes under the
5896                // give user id.
5897                if (packageName == null) {
5898                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5899                        continue;
5900                    }
5901                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5902                        continue;
5903                    }
5904                // Package has been specified, we want to hit all processes
5905                // that match it.  We need to qualify this by the processes
5906                // that are running under the specified app and user ID.
5907                } else {
5908                    final boolean isDep = app.pkgDeps != null
5909                            && app.pkgDeps.contains(packageName);
5910                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5911                        continue;
5912                    }
5913                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5914                        continue;
5915                    }
5916                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5917                        continue;
5918                    }
5919                }
5920
5921                // Process has passed all conditions, kill it!
5922                if (!doit) {
5923                    return true;
5924                }
5925                app.removed = true;
5926                procs.add(app);
5927            }
5928        }
5929
5930        int N = procs.size();
5931        for (int i=0; i<N; i++) {
5932            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5933        }
5934        updateOomAdjLocked();
5935        return N > 0;
5936    }
5937
5938    private void cleanupDisabledPackageComponentsLocked(
5939            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5940
5941        Set<String> disabledClasses = null;
5942        boolean packageDisabled = false;
5943        IPackageManager pm = AppGlobals.getPackageManager();
5944
5945        if (changedClasses == null) {
5946            // Nothing changed...
5947            return;
5948        }
5949
5950        // Determine enable/disable state of the package and its components.
5951        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5952        for (int i = changedClasses.length - 1; i >= 0; i--) {
5953            final String changedClass = changedClasses[i];
5954
5955            if (changedClass.equals(packageName)) {
5956                try {
5957                    // Entire package setting changed
5958                    enabled = pm.getApplicationEnabledSetting(packageName,
5959                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5960                } catch (Exception e) {
5961                    // No such package/component; probably racing with uninstall.  In any
5962                    // event it means we have nothing further to do here.
5963                    return;
5964                }
5965                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5966                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5967                if (packageDisabled) {
5968                    // Entire package is disabled.
5969                    // No need to continue to check component states.
5970                    disabledClasses = null;
5971                    break;
5972                }
5973            } else {
5974                try {
5975                    enabled = pm.getComponentEnabledSetting(
5976                            new ComponentName(packageName, changedClass),
5977                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5978                } catch (Exception e) {
5979                    // As above, probably racing with uninstall.
5980                    return;
5981                }
5982                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5983                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5984                    if (disabledClasses == null) {
5985                        disabledClasses = new ArraySet<>(changedClasses.length);
5986                    }
5987                    disabledClasses.add(changedClass);
5988                }
5989            }
5990        }
5991
5992        if (!packageDisabled && disabledClasses == null) {
5993            // Nothing to do here...
5994            return;
5995        }
5996
5997        // Clean-up disabled activities.
5998        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5999                packageName, disabledClasses, true, false, userId) && mBooted) {
6000            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6001            mStackSupervisor.scheduleIdleLocked();
6002        }
6003
6004        // Clean-up disabled tasks
6005        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6006
6007        // Clean-up disabled services.
6008        mServices.bringDownDisabledPackageServicesLocked(
6009                packageName, disabledClasses, userId, false, killProcess, true);
6010
6011        // Clean-up disabled providers.
6012        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6013        mProviderMap.collectPackageProvidersLocked(
6014                packageName, disabledClasses, true, false, userId, providers);
6015        for (int i = providers.size() - 1; i >= 0; i--) {
6016            removeDyingProviderLocked(null, providers.get(i), true);
6017        }
6018
6019        // Clean-up disabled broadcast receivers.
6020        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                    packageName, disabledClasses, userId, true);
6023        }
6024
6025    }
6026
6027    final boolean clearBroadcastQueueForUserLocked(int userId) {
6028        boolean didSomething = false;
6029        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6030            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6031                    null, null, userId, true);
6032        }
6033        return didSomething;
6034    }
6035
6036    final boolean forceStopPackageLocked(String packageName, int appId,
6037            boolean callerWillRestart, boolean purgeCache, boolean doit,
6038            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6039        int i;
6040
6041        if (userId == UserHandle.USER_ALL && packageName == null) {
6042            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6043        }
6044
6045        if (appId < 0 && packageName != null) {
6046            try {
6047                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6048                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6049            } catch (RemoteException e) {
6050            }
6051        }
6052
6053        if (doit) {
6054            if (packageName != null) {
6055                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6056                        + " user=" + userId + ": " + reason);
6057            } else {
6058                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6059            }
6060
6061            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6062        }
6063
6064        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6065                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6066                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6067
6068        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6069                packageName, null, doit, evenPersistent, userId)) {
6070            if (!doit) {
6071                return true;
6072            }
6073            didSomething = true;
6074        }
6075
6076        if (mServices.bringDownDisabledPackageServicesLocked(
6077                packageName, null, userId, evenPersistent, true, doit)) {
6078            if (!doit) {
6079                return true;
6080            }
6081            didSomething = true;
6082        }
6083
6084        if (packageName == null) {
6085            // Remove all sticky broadcasts from this user.
6086            mStickyBroadcasts.remove(userId);
6087        }
6088
6089        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6090        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6091                userId, providers)) {
6092            if (!doit) {
6093                return true;
6094            }
6095            didSomething = true;
6096        }
6097        for (i = providers.size() - 1; i >= 0; i--) {
6098            removeDyingProviderLocked(null, providers.get(i), true);
6099        }
6100
6101        // Remove transient permissions granted from/to this package/user
6102        removeUriPermissionsForPackageLocked(packageName, userId, false);
6103
6104        if (doit) {
6105            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6106                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6107                        packageName, null, userId, doit);
6108            }
6109        }
6110
6111        if (packageName == null || uninstalling) {
6112            // Remove pending intents.  For now we only do this when force
6113            // stopping users, because we have some problems when doing this
6114            // for packages -- app widgets are not currently cleaned up for
6115            // such packages, so they can be left with bad pending intents.
6116            if (mIntentSenderRecords.size() > 0) {
6117                Iterator<WeakReference<PendingIntentRecord>> it
6118                        = mIntentSenderRecords.values().iterator();
6119                while (it.hasNext()) {
6120                    WeakReference<PendingIntentRecord> wpir = it.next();
6121                    if (wpir == null) {
6122                        it.remove();
6123                        continue;
6124                    }
6125                    PendingIntentRecord pir = wpir.get();
6126                    if (pir == null) {
6127                        it.remove();
6128                        continue;
6129                    }
6130                    if (packageName == null) {
6131                        // Stopping user, remove all objects for the user.
6132                        if (pir.key.userId != userId) {
6133                            // Not the same user, skip it.
6134                            continue;
6135                        }
6136                    } else {
6137                        if (UserHandle.getAppId(pir.uid) != appId) {
6138                            // Different app id, skip it.
6139                            continue;
6140                        }
6141                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6142                            // Different user, skip it.
6143                            continue;
6144                        }
6145                        if (!pir.key.packageName.equals(packageName)) {
6146                            // Different package, skip it.
6147                            continue;
6148                        }
6149                    }
6150                    if (!doit) {
6151                        return true;
6152                    }
6153                    didSomething = true;
6154                    it.remove();
6155                    pir.canceled = true;
6156                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6157                        pir.key.activity.pendingResults.remove(pir.ref);
6158                    }
6159                }
6160            }
6161        }
6162
6163        if (doit) {
6164            if (purgeCache && packageName != null) {
6165                AttributeCache ac = AttributeCache.instance();
6166                if (ac != null) {
6167                    ac.removePackage(packageName);
6168                }
6169            }
6170            if (mBooted) {
6171                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6172                mStackSupervisor.scheduleIdleLocked();
6173            }
6174        }
6175
6176        return didSomething;
6177    }
6178
6179    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6180        ProcessRecord old = mProcessNames.remove(name, uid);
6181        if (old != null) {
6182            old.uidRecord.numProcs--;
6183            if (old.uidRecord.numProcs == 0) {
6184                // No more processes using this uid, tell clients it is gone.
6185                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6186                        "No more processes in " + old.uidRecord);
6187                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6188                mActiveUids.remove(uid);
6189                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6190            }
6191            old.uidRecord = null;
6192        }
6193        mIsolatedProcesses.remove(uid);
6194        return old;
6195    }
6196
6197    private final void addProcessNameLocked(ProcessRecord proc) {
6198        // We shouldn't already have a process under this name, but just in case we
6199        // need to clean up whatever may be there now.
6200        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6201        if (old == proc && proc.persistent) {
6202            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6203            Slog.w(TAG, "Re-adding persistent process " + proc);
6204        } else if (old != null) {
6205            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6206        }
6207        UidRecord uidRec = mActiveUids.get(proc.uid);
6208        if (uidRec == null) {
6209            uidRec = new UidRecord(proc.uid);
6210            // This is the first appearance of the uid, report it now!
6211            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6212                    "Creating new process uid: " + uidRec);
6213            mActiveUids.put(proc.uid, uidRec);
6214            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6215            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6216        }
6217        proc.uidRecord = uidRec;
6218        uidRec.numProcs++;
6219        mProcessNames.put(proc.processName, proc.uid, proc);
6220        if (proc.isolated) {
6221            mIsolatedProcesses.put(proc.uid, proc);
6222        }
6223    }
6224
6225    boolean removeProcessLocked(ProcessRecord app,
6226            boolean callerWillRestart, boolean allowRestart, String reason) {
6227        final String name = app.processName;
6228        final int uid = app.uid;
6229        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6230            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6231
6232        ProcessRecord old = mProcessNames.get(name, uid);
6233        if (old != app) {
6234            // This process is no longer active, so nothing to do.
6235            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6236            return false;
6237        }
6238        removeProcessNameLocked(name, uid);
6239        if (mHeavyWeightProcess == app) {
6240            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6241                    mHeavyWeightProcess.userId, 0));
6242            mHeavyWeightProcess = null;
6243        }
6244        boolean needRestart = false;
6245        if (app.pid > 0 && app.pid != MY_PID) {
6246            int pid = app.pid;
6247            synchronized (mPidsSelfLocked) {
6248                mPidsSelfLocked.remove(pid);
6249                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6250            }
6251            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6252            if (app.isolated) {
6253                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6254            }
6255            boolean willRestart = false;
6256            if (app.persistent && !app.isolated) {
6257                if (!callerWillRestart) {
6258                    willRestart = true;
6259                } else {
6260                    needRestart = true;
6261                }
6262            }
6263            app.kill(reason, true);
6264            handleAppDiedLocked(app, willRestart, allowRestart);
6265            if (willRestart) {
6266                removeLruProcessLocked(app);
6267                addAppLocked(app.info, false, null /* ABI override */);
6268            }
6269        } else {
6270            mRemovedProcesses.add(app);
6271        }
6272
6273        return needRestart;
6274    }
6275
6276    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6277        cleanupAppInLaunchingProvidersLocked(app, true);
6278        removeProcessLocked(app, false, true, "timeout publishing content providers");
6279    }
6280
6281    private final void processStartTimedOutLocked(ProcessRecord app) {
6282        final int pid = app.pid;
6283        boolean gone = false;
6284        synchronized (mPidsSelfLocked) {
6285            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6286            if (knownApp != null && knownApp.thread == null) {
6287                mPidsSelfLocked.remove(pid);
6288                gone = true;
6289            }
6290        }
6291
6292        if (gone) {
6293            Slog.w(TAG, "Process " + app + " failed to attach");
6294            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6295                    pid, app.uid, app.processName);
6296            removeProcessNameLocked(app.processName, app.uid);
6297            if (mHeavyWeightProcess == app) {
6298                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6299                        mHeavyWeightProcess.userId, 0));
6300                mHeavyWeightProcess = null;
6301            }
6302            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6303            if (app.isolated) {
6304                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6305            }
6306            // Take care of any launching providers waiting for this process.
6307            cleanupAppInLaunchingProvidersLocked(app, true);
6308            // Take care of any services that are waiting for the process.
6309            mServices.processStartTimedOutLocked(app);
6310            app.kill("start timeout", true);
6311            removeLruProcessLocked(app);
6312            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6313                Slog.w(TAG, "Unattached app died before backup, skipping");
6314                try {
6315                    IBackupManager bm = IBackupManager.Stub.asInterface(
6316                            ServiceManager.getService(Context.BACKUP_SERVICE));
6317                    bm.agentDisconnected(app.info.packageName);
6318                } catch (RemoteException e) {
6319                    // Can't happen; the backup manager is local
6320                }
6321            }
6322            if (isPendingBroadcastProcessLocked(pid)) {
6323                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6324                skipPendingBroadcastLocked(pid);
6325            }
6326        } else {
6327            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6328        }
6329    }
6330
6331    private final boolean attachApplicationLocked(IApplicationThread thread,
6332            int pid) {
6333
6334        // Find the application record that is being attached...  either via
6335        // the pid if we are running in multiple processes, or just pull the
6336        // next app record if we are emulating process with anonymous threads.
6337        ProcessRecord app;
6338        if (pid != MY_PID && pid >= 0) {
6339            synchronized (mPidsSelfLocked) {
6340                app = mPidsSelfLocked.get(pid);
6341            }
6342        } else {
6343            app = null;
6344        }
6345
6346        if (app == null) {
6347            Slog.w(TAG, "No pending application record for pid " + pid
6348                    + " (IApplicationThread " + thread + "); dropping process");
6349            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6350            if (pid > 0 && pid != MY_PID) {
6351                Process.killProcessQuiet(pid);
6352                //TODO: killProcessGroup(app.info.uid, pid);
6353            } else {
6354                try {
6355                    thread.scheduleExit();
6356                } catch (Exception e) {
6357                    // Ignore exceptions.
6358                }
6359            }
6360            return false;
6361        }
6362
6363        // If this application record is still attached to a previous
6364        // process, clean it up now.
6365        if (app.thread != null) {
6366            handleAppDiedLocked(app, true, true);
6367        }
6368
6369        // Tell the process all about itself.
6370
6371        if (DEBUG_ALL) Slog.v(
6372                TAG, "Binding process pid " + pid + " to record " + app);
6373
6374        final String processName = app.processName;
6375        try {
6376            AppDeathRecipient adr = new AppDeathRecipient(
6377                    app, pid, thread);
6378            thread.asBinder().linkToDeath(adr, 0);
6379            app.deathRecipient = adr;
6380        } catch (RemoteException e) {
6381            app.resetPackageList(mProcessStats);
6382            startProcessLocked(app, "link fail", processName);
6383            return false;
6384        }
6385
6386        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6387
6388        app.makeActive(thread, mProcessStats);
6389        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6390        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6391        app.forcingToForeground = null;
6392        updateProcessForegroundLocked(app, false, false);
6393        app.hasShownUi = false;
6394        app.debugging = false;
6395        app.cached = false;
6396        app.killedByAm = false;
6397
6398        // We carefully use the same state that PackageManager uses for
6399        // filtering, since we use this flag to decide if we need to install
6400        // providers when user is unlocked later
6401        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6402
6403        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6404
6405        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6406        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6407
6408        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6409            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6410            msg.obj = app;
6411            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6412        }
6413
6414        if (!normalMode) {
6415            Slog.i(TAG, "Launching preboot mode app: " + app);
6416        }
6417
6418        if (DEBUG_ALL) Slog.v(
6419            TAG, "New app record " + app
6420            + " thread=" + thread.asBinder() + " pid=" + pid);
6421        try {
6422            int testMode = IApplicationThread.DEBUG_OFF;
6423            if (mDebugApp != null && mDebugApp.equals(processName)) {
6424                testMode = mWaitForDebugger
6425                    ? IApplicationThread.DEBUG_WAIT
6426                    : IApplicationThread.DEBUG_ON;
6427                app.debugging = true;
6428                if (mDebugTransient) {
6429                    mDebugApp = mOrigDebugApp;
6430                    mWaitForDebugger = mOrigWaitForDebugger;
6431                }
6432            }
6433            String profileFile = app.instrumentationProfileFile;
6434            ParcelFileDescriptor profileFd = null;
6435            int samplingInterval = 0;
6436            boolean profileAutoStop = false;
6437            if (mProfileApp != null && mProfileApp.equals(processName)) {
6438                mProfileProc = app;
6439                profileFile = mProfileFile;
6440                profileFd = mProfileFd;
6441                samplingInterval = mSamplingInterval;
6442                profileAutoStop = mAutoStopProfiler;
6443            }
6444            boolean enableTrackAllocation = false;
6445            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6446                enableTrackAllocation = true;
6447                mTrackAllocationApp = null;
6448            }
6449
6450            // If the app is being launched for restore or full backup, set it up specially
6451            boolean isRestrictedBackupMode = false;
6452            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6453                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6454                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6455                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6456                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6457            }
6458
6459            if (app.instrumentationClass != null) {
6460                notifyPackageUse(app.instrumentationClass.getPackageName(),
6461                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6462            }
6463            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6464                    + processName + " with config " + mConfiguration);
6465            ApplicationInfo appInfo = app.instrumentationInfo != null
6466                    ? app.instrumentationInfo : app.info;
6467            app.compat = compatibilityInfoForPackageLocked(appInfo);
6468            if (profileFd != null) {
6469                profileFd = profileFd.dup();
6470            }
6471            ProfilerInfo profilerInfo = profileFile == null ? null
6472                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6473            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6474                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6475                    app.instrumentationUiAutomationConnection, testMode,
6476                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6477                    isRestrictedBackupMode || !normalMode, app.persistent,
6478                    new Configuration(mConfiguration), app.compat,
6479                    getCommonServicesLocked(app.isolated),
6480                    mCoreSettingsObserver.getCoreSettingsLocked());
6481            updateLruProcessLocked(app, false, null);
6482            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6483        } catch (Exception e) {
6484            // todo: Yikes!  What should we do?  For now we will try to
6485            // start another process, but that could easily get us in
6486            // an infinite loop of restarting processes...
6487            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6488
6489            app.resetPackageList(mProcessStats);
6490            app.unlinkDeathRecipient();
6491            startProcessLocked(app, "bind fail", processName);
6492            return false;
6493        }
6494
6495        // Remove this record from the list of starting applications.
6496        mPersistentStartingProcesses.remove(app);
6497        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6498                "Attach application locked removing on hold: " + app);
6499        mProcessesOnHold.remove(app);
6500
6501        boolean badApp = false;
6502        boolean didSomething = false;
6503
6504        // See if the top visible activity is waiting to run in this process...
6505        if (normalMode) {
6506            try {
6507                if (mStackSupervisor.attachApplicationLocked(app)) {
6508                    didSomething = true;
6509                }
6510            } catch (Exception e) {
6511                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6512                badApp = true;
6513            }
6514        }
6515
6516        // Find any services that should be running in this process...
6517        if (!badApp) {
6518            try {
6519                didSomething |= mServices.attachApplicationLocked(app, processName);
6520            } catch (Exception e) {
6521                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6522                badApp = true;
6523            }
6524        }
6525
6526        // Check if a next-broadcast receiver is in this process...
6527        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6528            try {
6529                didSomething |= sendPendingBroadcastsLocked(app);
6530            } catch (Exception e) {
6531                // If the app died trying to launch the receiver we declare it 'bad'
6532                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6533                badApp = true;
6534            }
6535        }
6536
6537        // Check whether the next backup agent is in this process...
6538        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6539            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6540                    "New app is backup target, launching agent for " + app);
6541            notifyPackageUse(mBackupTarget.appInfo.packageName,
6542                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6543            try {
6544                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6545                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6546                        mBackupTarget.backupMode);
6547            } catch (Exception e) {
6548                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6549                badApp = true;
6550            }
6551        }
6552
6553        if (badApp) {
6554            app.kill("error during init", true);
6555            handleAppDiedLocked(app, false, true);
6556            return false;
6557        }
6558
6559        if (!didSomething) {
6560            updateOomAdjLocked();
6561        }
6562
6563        return true;
6564    }
6565
6566    @Override
6567    public final void attachApplication(IApplicationThread thread) {
6568        synchronized (this) {
6569            int callingPid = Binder.getCallingPid();
6570            final long origId = Binder.clearCallingIdentity();
6571            attachApplicationLocked(thread, callingPid);
6572            Binder.restoreCallingIdentity(origId);
6573        }
6574    }
6575
6576    @Override
6577    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6578        final long origId = Binder.clearCallingIdentity();
6579        synchronized (this) {
6580            ActivityStack stack = ActivityRecord.getStackLocked(token);
6581            if (stack != null) {
6582                ActivityRecord r =
6583                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6584                if (stopProfiling) {
6585                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6586                        try {
6587                            mProfileFd.close();
6588                        } catch (IOException e) {
6589                        }
6590                        clearProfilerLocked();
6591                    }
6592                }
6593            }
6594        }
6595        Binder.restoreCallingIdentity(origId);
6596    }
6597
6598    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6599        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6600                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6601    }
6602
6603    void enableScreenAfterBoot() {
6604        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6605                SystemClock.uptimeMillis());
6606        mWindowManager.enableScreenAfterBoot();
6607
6608        synchronized (this) {
6609            updateEventDispatchingLocked();
6610        }
6611    }
6612
6613    @Override
6614    public void showBootMessage(final CharSequence msg, final boolean always) {
6615        if (Binder.getCallingUid() != Process.myUid()) {
6616            // These days only the core system can call this, so apps can't get in
6617            // the way of what we show about running them.
6618        }
6619        mWindowManager.showBootMessage(msg, always);
6620    }
6621
6622    @Override
6623    public void keyguardWaitingForActivityDrawn() {
6624        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6625        final long token = Binder.clearCallingIdentity();
6626        try {
6627            synchronized (this) {
6628                if (DEBUG_LOCKSCREEN) logLockScreen("");
6629                mWindowManager.keyguardWaitingForActivityDrawn();
6630                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6631                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6632                    updateSleepIfNeededLocked();
6633                }
6634            }
6635        } finally {
6636            Binder.restoreCallingIdentity(token);
6637        }
6638    }
6639
6640    @Override
6641    public void keyguardGoingAway(int flags) {
6642        enforceNotIsolatedCaller("keyguardGoingAway");
6643        final long token = Binder.clearCallingIdentity();
6644        try {
6645            synchronized (this) {
6646                if (DEBUG_LOCKSCREEN) logLockScreen("");
6647                mWindowManager.keyguardGoingAway(flags);
6648                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6649                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6650                    updateSleepIfNeededLocked();
6651
6652                    // Some stack visibility might change (e.g. docked stack)
6653                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6654                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6655                }
6656            }
6657        } finally {
6658            Binder.restoreCallingIdentity(token);
6659        }
6660    }
6661
6662    final void finishBooting() {
6663        synchronized (this) {
6664            if (!mBootAnimationComplete) {
6665                mCallFinishBooting = true;
6666                return;
6667            }
6668            mCallFinishBooting = false;
6669        }
6670
6671        ArraySet<String> completedIsas = new ArraySet<String>();
6672        for (String abi : Build.SUPPORTED_ABIS) {
6673            Process.establishZygoteConnectionForAbi(abi);
6674            final String instructionSet = VMRuntime.getInstructionSet(abi);
6675            if (!completedIsas.contains(instructionSet)) {
6676                try {
6677                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6678                } catch (InstallerException e) {
6679                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6680                            e.getMessage() +")");
6681                }
6682                completedIsas.add(instructionSet);
6683            }
6684        }
6685
6686        IntentFilter pkgFilter = new IntentFilter();
6687        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6688        pkgFilter.addDataScheme("package");
6689        mContext.registerReceiver(new BroadcastReceiver() {
6690            @Override
6691            public void onReceive(Context context, Intent intent) {
6692                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6693                if (pkgs != null) {
6694                    for (String pkg : pkgs) {
6695                        synchronized (ActivityManagerService.this) {
6696                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6697                                    0, "query restart")) {
6698                                setResultCode(Activity.RESULT_OK);
6699                                return;
6700                            }
6701                        }
6702                    }
6703                }
6704            }
6705        }, pkgFilter);
6706
6707        IntentFilter dumpheapFilter = new IntentFilter();
6708        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6709        mContext.registerReceiver(new BroadcastReceiver() {
6710            @Override
6711            public void onReceive(Context context, Intent intent) {
6712                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6713                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6714                } else {
6715                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6716                }
6717            }
6718        }, dumpheapFilter);
6719
6720        // Let system services know.
6721        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6722
6723        synchronized (this) {
6724            // Ensure that any processes we had put on hold are now started
6725            // up.
6726            final int NP = mProcessesOnHold.size();
6727            if (NP > 0) {
6728                ArrayList<ProcessRecord> procs =
6729                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6730                for (int ip=0; ip<NP; ip++) {
6731                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6732                            + procs.get(ip));
6733                    startProcessLocked(procs.get(ip), "on-hold", null);
6734                }
6735            }
6736
6737            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6738                // Start looking for apps that are abusing wake locks.
6739                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6740                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6741                // Tell anyone interested that we are done booting!
6742                SystemProperties.set("sys.boot_completed", "1");
6743
6744                // And trigger dev.bootcomplete if we are not showing encryption progress
6745                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6746                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6747                    SystemProperties.set("dev.bootcomplete", "1");
6748                }
6749                mUserController.sendBootCompletedLocked(
6750                        new IIntentReceiver.Stub() {
6751                            @Override
6752                            public void performReceive(Intent intent, int resultCode,
6753                                    String data, Bundle extras, boolean ordered,
6754                                    boolean sticky, int sendingUser) {
6755                                synchronized (ActivityManagerService.this) {
6756                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6757                                            true, false);
6758                                }
6759                            }
6760                        });
6761                scheduleStartProfilesLocked();
6762            }
6763        }
6764    }
6765
6766    @Override
6767    public void bootAnimationComplete() {
6768        final boolean callFinishBooting;
6769        synchronized (this) {
6770            callFinishBooting = mCallFinishBooting;
6771            mBootAnimationComplete = true;
6772        }
6773        if (callFinishBooting) {
6774            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6775            finishBooting();
6776            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6777        }
6778    }
6779
6780    final void ensureBootCompleted() {
6781        boolean booting;
6782        boolean enableScreen;
6783        synchronized (this) {
6784            booting = mBooting;
6785            mBooting = false;
6786            enableScreen = !mBooted;
6787            mBooted = true;
6788        }
6789
6790        if (booting) {
6791            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6792            finishBooting();
6793            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6794        }
6795
6796        if (enableScreen) {
6797            enableScreenAfterBoot();
6798        }
6799    }
6800
6801    @Override
6802    public final void activityResumed(IBinder token) {
6803        final long origId = Binder.clearCallingIdentity();
6804        synchronized(this) {
6805            ActivityStack stack = ActivityRecord.getStackLocked(token);
6806            if (stack != null) {
6807                stack.activityResumedLocked(token);
6808            }
6809        }
6810        Binder.restoreCallingIdentity(origId);
6811    }
6812
6813    @Override
6814    public final void activityPaused(IBinder token) {
6815        final long origId = Binder.clearCallingIdentity();
6816        synchronized(this) {
6817            ActivityStack stack = ActivityRecord.getStackLocked(token);
6818            if (stack != null) {
6819                stack.activityPausedLocked(token, false);
6820            }
6821        }
6822        Binder.restoreCallingIdentity(origId);
6823    }
6824
6825    @Override
6826    public final void activityStopped(IBinder token, Bundle icicle,
6827            PersistableBundle persistentState, CharSequence description) {
6828        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6829
6830        // Refuse possible leaked file descriptors
6831        if (icicle != null && icicle.hasFileDescriptors()) {
6832            throw new IllegalArgumentException("File descriptors passed in Bundle");
6833        }
6834
6835        final long origId = Binder.clearCallingIdentity();
6836
6837        synchronized (this) {
6838            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6839            if (r != null) {
6840                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6841            }
6842        }
6843
6844        trimApplications();
6845
6846        Binder.restoreCallingIdentity(origId);
6847    }
6848
6849    @Override
6850    public final void activityDestroyed(IBinder token) {
6851        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6852        synchronized (this) {
6853            ActivityStack stack = ActivityRecord.getStackLocked(token);
6854            if (stack != null) {
6855                stack.activityDestroyedLocked(token, "activityDestroyed");
6856            }
6857        }
6858    }
6859
6860    @Override
6861    public final void activityRelaunched(IBinder token) {
6862        final long origId = Binder.clearCallingIdentity();
6863        synchronized (this) {
6864            mStackSupervisor.activityRelaunchedLocked(token);
6865        }
6866        Binder.restoreCallingIdentity(origId);
6867    }
6868
6869    @Override
6870    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6871            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6872        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6873                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6874        synchronized (this) {
6875            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6876            if (record == null) {
6877                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6878                        + "found for: " + token);
6879            }
6880            record.setSizeConfigurations(horizontalSizeConfiguration,
6881                    verticalSizeConfigurations, smallestSizeConfigurations);
6882        }
6883    }
6884
6885    @Override
6886    public final void backgroundResourcesReleased(IBinder token) {
6887        final long origId = Binder.clearCallingIdentity();
6888        try {
6889            synchronized (this) {
6890                ActivityStack stack = ActivityRecord.getStackLocked(token);
6891                if (stack != null) {
6892                    stack.backgroundResourcesReleased();
6893                }
6894            }
6895        } finally {
6896            Binder.restoreCallingIdentity(origId);
6897        }
6898    }
6899
6900    @Override
6901    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6902        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6903    }
6904
6905    @Override
6906    public final void notifyEnterAnimationComplete(IBinder token) {
6907        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6908    }
6909
6910    @Override
6911    public String getCallingPackage(IBinder token) {
6912        synchronized (this) {
6913            ActivityRecord r = getCallingRecordLocked(token);
6914            return r != null ? r.info.packageName : null;
6915        }
6916    }
6917
6918    @Override
6919    public ComponentName getCallingActivity(IBinder token) {
6920        synchronized (this) {
6921            ActivityRecord r = getCallingRecordLocked(token);
6922            return r != null ? r.intent.getComponent() : null;
6923        }
6924    }
6925
6926    private ActivityRecord getCallingRecordLocked(IBinder token) {
6927        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6928        if (r == null) {
6929            return null;
6930        }
6931        return r.resultTo;
6932    }
6933
6934    @Override
6935    public ComponentName getActivityClassForToken(IBinder token) {
6936        synchronized(this) {
6937            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6938            if (r == null) {
6939                return null;
6940            }
6941            return r.intent.getComponent();
6942        }
6943    }
6944
6945    @Override
6946    public String getPackageForToken(IBinder token) {
6947        synchronized(this) {
6948            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6949            if (r == null) {
6950                return null;
6951            }
6952            return r.packageName;
6953        }
6954    }
6955
6956    @Override
6957    public boolean isRootVoiceInteraction(IBinder token) {
6958        synchronized(this) {
6959            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6960            if (r == null) {
6961                return false;
6962            }
6963            return r.rootVoiceInteraction;
6964        }
6965    }
6966
6967    @Override
6968    public IIntentSender getIntentSender(int type,
6969            String packageName, IBinder token, String resultWho,
6970            int requestCode, Intent[] intents, String[] resolvedTypes,
6971            int flags, Bundle bOptions, int userId) {
6972        enforceNotIsolatedCaller("getIntentSender");
6973        // Refuse possible leaked file descriptors
6974        if (intents != null) {
6975            if (intents.length < 1) {
6976                throw new IllegalArgumentException("Intents array length must be >= 1");
6977            }
6978            for (int i=0; i<intents.length; i++) {
6979                Intent intent = intents[i];
6980                if (intent != null) {
6981                    if (intent.hasFileDescriptors()) {
6982                        throw new IllegalArgumentException("File descriptors passed in Intent");
6983                    }
6984                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6985                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6986                        throw new IllegalArgumentException(
6987                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6988                    }
6989                    intents[i] = new Intent(intent);
6990                }
6991            }
6992            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6993                throw new IllegalArgumentException(
6994                        "Intent array length does not match resolvedTypes length");
6995            }
6996        }
6997        if (bOptions != null) {
6998            if (bOptions.hasFileDescriptors()) {
6999                throw new IllegalArgumentException("File descriptors passed in options");
7000            }
7001        }
7002
7003        synchronized(this) {
7004            int callingUid = Binder.getCallingUid();
7005            int origUserId = userId;
7006            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7007                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7008                    ALLOW_NON_FULL, "getIntentSender", null);
7009            if (origUserId == UserHandle.USER_CURRENT) {
7010                // We don't want to evaluate this until the pending intent is
7011                // actually executed.  However, we do want to always do the
7012                // security checking for it above.
7013                userId = UserHandle.USER_CURRENT;
7014            }
7015            try {
7016                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7017                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7018                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7019                    if (!UserHandle.isSameApp(callingUid, uid)) {
7020                        String msg = "Permission Denial: getIntentSender() from pid="
7021                            + Binder.getCallingPid()
7022                            + ", uid=" + Binder.getCallingUid()
7023                            + ", (need uid=" + uid + ")"
7024                            + " is not allowed to send as package " + packageName;
7025                        Slog.w(TAG, msg);
7026                        throw new SecurityException(msg);
7027                    }
7028                }
7029
7030                return getIntentSenderLocked(type, packageName, callingUid, userId,
7031                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7032
7033            } catch (RemoteException e) {
7034                throw new SecurityException(e);
7035            }
7036        }
7037    }
7038
7039    IIntentSender getIntentSenderLocked(int type, String packageName,
7040            int callingUid, int userId, IBinder token, String resultWho,
7041            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7042            Bundle bOptions) {
7043        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7044        ActivityRecord activity = null;
7045        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7046            activity = ActivityRecord.isInStackLocked(token);
7047            if (activity == null) {
7048                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7049                return null;
7050            }
7051            if (activity.finishing) {
7052                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7053                return null;
7054            }
7055        }
7056
7057        // We're going to be splicing together extras before sending, so we're
7058        // okay poking into any contained extras.
7059        if (intents != null) {
7060            for (int i = 0; i < intents.length; i++) {
7061                intents[i].setDefusable(true);
7062            }
7063        }
7064        Bundle.setDefusable(bOptions, true);
7065
7066        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7067        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7068        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7069        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7070                |PendingIntent.FLAG_UPDATE_CURRENT);
7071
7072        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7073                type, packageName, activity, resultWho,
7074                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7075        WeakReference<PendingIntentRecord> ref;
7076        ref = mIntentSenderRecords.get(key);
7077        PendingIntentRecord rec = ref != null ? ref.get() : null;
7078        if (rec != null) {
7079            if (!cancelCurrent) {
7080                if (updateCurrent) {
7081                    if (rec.key.requestIntent != null) {
7082                        rec.key.requestIntent.replaceExtras(intents != null ?
7083                                intents[intents.length - 1] : null);
7084                    }
7085                    if (intents != null) {
7086                        intents[intents.length-1] = rec.key.requestIntent;
7087                        rec.key.allIntents = intents;
7088                        rec.key.allResolvedTypes = resolvedTypes;
7089                    } else {
7090                        rec.key.allIntents = null;
7091                        rec.key.allResolvedTypes = null;
7092                    }
7093                }
7094                return rec;
7095            }
7096            rec.canceled = true;
7097            mIntentSenderRecords.remove(key);
7098        }
7099        if (noCreate) {
7100            return rec;
7101        }
7102        rec = new PendingIntentRecord(this, key, callingUid);
7103        mIntentSenderRecords.put(key, rec.ref);
7104        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7105            if (activity.pendingResults == null) {
7106                activity.pendingResults
7107                        = new HashSet<WeakReference<PendingIntentRecord>>();
7108            }
7109            activity.pendingResults.add(rec.ref);
7110        }
7111        return rec;
7112    }
7113
7114    @Override
7115    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7116            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7117        if (target instanceof PendingIntentRecord) {
7118            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7119                    finishedReceiver, requiredPermission, options);
7120        } else {
7121            if (intent == null) {
7122                // Weird case: someone has given us their own custom IIntentSender, and now
7123                // they have someone else trying to send to it but of course this isn't
7124                // really a PendingIntent, so there is no base Intent, and the caller isn't
7125                // supplying an Intent... but we never want to dispatch a null Intent to
7126                // a receiver, so um...  let's make something up.
7127                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7128                intent = new Intent(Intent.ACTION_MAIN);
7129            }
7130            try {
7131                target.send(code, intent, resolvedType, null, requiredPermission, options);
7132            } catch (RemoteException e) {
7133            }
7134            // Platform code can rely on getting a result back when the send is done, but if
7135            // this intent sender is from outside of the system we can't rely on it doing that.
7136            // So instead we don't give it the result receiver, and instead just directly
7137            // report the finish immediately.
7138            if (finishedReceiver != null) {
7139                try {
7140                    finishedReceiver.performReceive(intent, 0,
7141                            null, null, false, false, UserHandle.getCallingUserId());
7142                } catch (RemoteException e) {
7143                }
7144            }
7145            return 0;
7146        }
7147    }
7148
7149    /**
7150     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7151     *
7152     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7153     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7154     */
7155    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7156        if (DEBUG_WHITELISTS) {
7157            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7158                    + targetUid + ", " + duration + ")");
7159        }
7160        synchronized (mPidsSelfLocked) {
7161            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7162            if (pr == null) {
7163                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7164                return;
7165            }
7166            if (!pr.whitelistManager) {
7167                if (DEBUG_WHITELISTS) {
7168                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7169                            + callerPid + " is not allowed");
7170                }
7171                return;
7172            }
7173        }
7174
7175        final long token = Binder.clearCallingIdentity();
7176        try {
7177            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7178                    true, "pe from uid:" + callerUid);
7179        } finally {
7180            Binder.restoreCallingIdentity(token);
7181        }
7182    }
7183
7184    @Override
7185    public void cancelIntentSender(IIntentSender sender) {
7186        if (!(sender instanceof PendingIntentRecord)) {
7187            return;
7188        }
7189        synchronized(this) {
7190            PendingIntentRecord rec = (PendingIntentRecord)sender;
7191            try {
7192                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7193                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7194                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7195                    String msg = "Permission Denial: cancelIntentSender() from pid="
7196                        + Binder.getCallingPid()
7197                        + ", uid=" + Binder.getCallingUid()
7198                        + " is not allowed to cancel packges "
7199                        + rec.key.packageName;
7200                    Slog.w(TAG, msg);
7201                    throw new SecurityException(msg);
7202                }
7203            } catch (RemoteException e) {
7204                throw new SecurityException(e);
7205            }
7206            cancelIntentSenderLocked(rec, true);
7207        }
7208    }
7209
7210    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7211        rec.canceled = true;
7212        mIntentSenderRecords.remove(rec.key);
7213        if (cleanActivity && rec.key.activity != null) {
7214            rec.key.activity.pendingResults.remove(rec.ref);
7215        }
7216    }
7217
7218    @Override
7219    public String getPackageForIntentSender(IIntentSender pendingResult) {
7220        if (!(pendingResult instanceof PendingIntentRecord)) {
7221            return null;
7222        }
7223        try {
7224            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7225            return res.key.packageName;
7226        } catch (ClassCastException e) {
7227        }
7228        return null;
7229    }
7230
7231    @Override
7232    public int getUidForIntentSender(IIntentSender sender) {
7233        if (sender instanceof PendingIntentRecord) {
7234            try {
7235                PendingIntentRecord res = (PendingIntentRecord)sender;
7236                return res.uid;
7237            } catch (ClassCastException e) {
7238            }
7239        }
7240        return -1;
7241    }
7242
7243    @Override
7244    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7245        if (!(pendingResult instanceof PendingIntentRecord)) {
7246            return false;
7247        }
7248        try {
7249            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7250            if (res.key.allIntents == null) {
7251                return false;
7252            }
7253            for (int i=0; i<res.key.allIntents.length; i++) {
7254                Intent intent = res.key.allIntents[i];
7255                if (intent.getPackage() != null && intent.getComponent() != null) {
7256                    return false;
7257                }
7258            }
7259            return true;
7260        } catch (ClassCastException e) {
7261        }
7262        return false;
7263    }
7264
7265    @Override
7266    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7267        if (!(pendingResult instanceof PendingIntentRecord)) {
7268            return false;
7269        }
7270        try {
7271            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7272            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7273                return true;
7274            }
7275            return false;
7276        } catch (ClassCastException e) {
7277        }
7278        return false;
7279    }
7280
7281    @Override
7282    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7283        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7284                "getIntentForIntentSender()");
7285        if (!(pendingResult instanceof PendingIntentRecord)) {
7286            return null;
7287        }
7288        try {
7289            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7290            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7291        } catch (ClassCastException e) {
7292        }
7293        return null;
7294    }
7295
7296    @Override
7297    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7298        if (!(pendingResult instanceof PendingIntentRecord)) {
7299            return null;
7300        }
7301        try {
7302            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7303            synchronized (this) {
7304                return getTagForIntentSenderLocked(res, prefix);
7305            }
7306        } catch (ClassCastException e) {
7307        }
7308        return null;
7309    }
7310
7311    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7312        final Intent intent = res.key.requestIntent;
7313        if (intent != null) {
7314            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7315                    || res.lastTagPrefix.equals(prefix))) {
7316                return res.lastTag;
7317            }
7318            res.lastTagPrefix = prefix;
7319            final StringBuilder sb = new StringBuilder(128);
7320            if (prefix != null) {
7321                sb.append(prefix);
7322            }
7323            if (intent.getAction() != null) {
7324                sb.append(intent.getAction());
7325            } else if (intent.getComponent() != null) {
7326                intent.getComponent().appendShortString(sb);
7327            } else {
7328                sb.append("?");
7329            }
7330            return res.lastTag = sb.toString();
7331        }
7332        return null;
7333    }
7334
7335    @Override
7336    public void setProcessLimit(int max) {
7337        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7338                "setProcessLimit()");
7339        synchronized (this) {
7340            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7341            mProcessLimitOverride = max;
7342        }
7343        trimApplications();
7344    }
7345
7346    @Override
7347    public int getProcessLimit() {
7348        synchronized (this) {
7349            return mProcessLimitOverride;
7350        }
7351    }
7352
7353    void foregroundTokenDied(ForegroundToken token) {
7354        synchronized (ActivityManagerService.this) {
7355            synchronized (mPidsSelfLocked) {
7356                ForegroundToken cur
7357                    = mForegroundProcesses.get(token.pid);
7358                if (cur != token) {
7359                    return;
7360                }
7361                mForegroundProcesses.remove(token.pid);
7362                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7363                if (pr == null) {
7364                    return;
7365                }
7366                pr.forcingToForeground = null;
7367                updateProcessForegroundLocked(pr, false, false);
7368            }
7369            updateOomAdjLocked();
7370        }
7371    }
7372
7373    @Override
7374    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7375        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7376                "setProcessForeground()");
7377        synchronized(this) {
7378            boolean changed = false;
7379
7380            synchronized (mPidsSelfLocked) {
7381                ProcessRecord pr = mPidsSelfLocked.get(pid);
7382                if (pr == null && isForeground) {
7383                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7384                    return;
7385                }
7386                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7387                if (oldToken != null) {
7388                    oldToken.token.unlinkToDeath(oldToken, 0);
7389                    mForegroundProcesses.remove(pid);
7390                    if (pr != null) {
7391                        pr.forcingToForeground = null;
7392                    }
7393                    changed = true;
7394                }
7395                if (isForeground && token != null) {
7396                    ForegroundToken newToken = new ForegroundToken() {
7397                        @Override
7398                        public void binderDied() {
7399                            foregroundTokenDied(this);
7400                        }
7401                    };
7402                    newToken.pid = pid;
7403                    newToken.token = token;
7404                    try {
7405                        token.linkToDeath(newToken, 0);
7406                        mForegroundProcesses.put(pid, newToken);
7407                        pr.forcingToForeground = token;
7408                        changed = true;
7409                    } catch (RemoteException e) {
7410                        // If the process died while doing this, we will later
7411                        // do the cleanup with the process death link.
7412                    }
7413                }
7414            }
7415
7416            if (changed) {
7417                updateOomAdjLocked();
7418            }
7419        }
7420    }
7421
7422    @Override
7423    public boolean isAppForeground(int uid) throws RemoteException {
7424        synchronized (this) {
7425            UidRecord uidRec = mActiveUids.get(uid);
7426            if (uidRec == null || uidRec.idle) {
7427                return false;
7428            }
7429            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7430        }
7431    }
7432
7433    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7434    // be guarded by permission checking.
7435    int getUidState(int uid) {
7436        synchronized (this) {
7437            UidRecord uidRec = mActiveUids.get(uid);
7438            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7439        }
7440    }
7441
7442    @Override
7443    public boolean isInMultiWindowMode(IBinder token) {
7444        final long origId = Binder.clearCallingIdentity();
7445        try {
7446            synchronized(this) {
7447                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7448                if (r == null) {
7449                    return false;
7450                }
7451                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7452                return !r.task.mFullscreen;
7453            }
7454        } finally {
7455            Binder.restoreCallingIdentity(origId);
7456        }
7457    }
7458
7459    @Override
7460    public boolean isInPictureInPictureMode(IBinder token) {
7461        final long origId = Binder.clearCallingIdentity();
7462        try {
7463            synchronized(this) {
7464                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7465                if (stack == null) {
7466                    return false;
7467                }
7468                return stack.mStackId == PINNED_STACK_ID;
7469            }
7470        } finally {
7471            Binder.restoreCallingIdentity(origId);
7472        }
7473    }
7474
7475    @Override
7476    public void enterPictureInPictureMode(IBinder token) {
7477        final long origId = Binder.clearCallingIdentity();
7478        try {
7479            synchronized(this) {
7480                if (!mSupportsPictureInPicture) {
7481                    throw new IllegalStateException("enterPictureInPictureMode: "
7482                            + "Device doesn't support picture-in-picture mode.");
7483                }
7484
7485                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7486
7487                if (r == null) {
7488                    throw new IllegalStateException("enterPictureInPictureMode: "
7489                            + "Can't find activity for token=" + token);
7490                }
7491
7492                if (!r.supportsPictureInPicture()) {
7493                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7494                            + "Picture-In-Picture not supported for r=" + r);
7495                }
7496
7497                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7498                // current bounds.
7499                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7500                final Rect bounds = (pinnedStack != null)
7501                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7502
7503                mStackSupervisor.moveActivityToPinnedStackLocked(
7504                        r, "enterPictureInPictureMode", bounds);
7505            }
7506        } finally {
7507            Binder.restoreCallingIdentity(origId);
7508        }
7509    }
7510
7511    // =========================================================
7512    // PROCESS INFO
7513    // =========================================================
7514
7515    static class ProcessInfoService extends IProcessInfoService.Stub {
7516        final ActivityManagerService mActivityManagerService;
7517        ProcessInfoService(ActivityManagerService activityManagerService) {
7518            mActivityManagerService = activityManagerService;
7519        }
7520
7521        @Override
7522        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7523            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7524                    /*in*/ pids, /*out*/ states, null);
7525        }
7526
7527        @Override
7528        public void getProcessStatesAndOomScoresFromPids(
7529                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7530            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7531                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7532        }
7533    }
7534
7535    /**
7536     * For each PID in the given input array, write the current process state
7537     * for that process into the states array, or -1 to indicate that no
7538     * process with the given PID exists. If scores array is provided, write
7539     * the oom score for the process into the scores array, with INVALID_ADJ
7540     * indicating the PID doesn't exist.
7541     */
7542    public void getProcessStatesAndOomScoresForPIDs(
7543            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7544        if (scores != null) {
7545            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7546                    "getProcessStatesAndOomScoresForPIDs()");
7547        }
7548
7549        if (pids == null) {
7550            throw new NullPointerException("pids");
7551        } else if (states == null) {
7552            throw new NullPointerException("states");
7553        } else if (pids.length != states.length) {
7554            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7555        } else if (scores != null && pids.length != scores.length) {
7556            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7557        }
7558
7559        synchronized (mPidsSelfLocked) {
7560            for (int i = 0; i < pids.length; i++) {
7561                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7562                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7563                        pr.curProcState;
7564                if (scores != null) {
7565                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7566                }
7567            }
7568        }
7569    }
7570
7571    // =========================================================
7572    // PERMISSIONS
7573    // =========================================================
7574
7575    static class PermissionController extends IPermissionController.Stub {
7576        ActivityManagerService mActivityManagerService;
7577        PermissionController(ActivityManagerService activityManagerService) {
7578            mActivityManagerService = activityManagerService;
7579        }
7580
7581        @Override
7582        public boolean checkPermission(String permission, int pid, int uid) {
7583            return mActivityManagerService.checkPermission(permission, pid,
7584                    uid) == PackageManager.PERMISSION_GRANTED;
7585        }
7586
7587        @Override
7588        public String[] getPackagesForUid(int uid) {
7589            return mActivityManagerService.mContext.getPackageManager()
7590                    .getPackagesForUid(uid);
7591        }
7592
7593        @Override
7594        public boolean isRuntimePermission(String permission) {
7595            try {
7596                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7597                        .getPermissionInfo(permission, 0);
7598                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7599            } catch (NameNotFoundException nnfe) {
7600                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7601            }
7602            return false;
7603        }
7604    }
7605
7606    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7607        @Override
7608        public int checkComponentPermission(String permission, int pid, int uid,
7609                int owningUid, boolean exported) {
7610            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7611                    owningUid, exported);
7612        }
7613
7614        @Override
7615        public Object getAMSLock() {
7616            return ActivityManagerService.this;
7617        }
7618    }
7619
7620    /**
7621     * This can be called with or without the global lock held.
7622     */
7623    int checkComponentPermission(String permission, int pid, int uid,
7624            int owningUid, boolean exported) {
7625        if (pid == MY_PID) {
7626            return PackageManager.PERMISSION_GRANTED;
7627        }
7628        return ActivityManager.checkComponentPermission(permission, uid,
7629                owningUid, exported);
7630    }
7631
7632    /**
7633     * As the only public entry point for permissions checking, this method
7634     * can enforce the semantic that requesting a check on a null global
7635     * permission is automatically denied.  (Internally a null permission
7636     * string is used when calling {@link #checkComponentPermission} in cases
7637     * when only uid-based security is needed.)
7638     *
7639     * This can be called with or without the global lock held.
7640     */
7641    @Override
7642    public int checkPermission(String permission, int pid, int uid) {
7643        if (permission == null) {
7644            return PackageManager.PERMISSION_DENIED;
7645        }
7646        return checkComponentPermission(permission, pid, uid, -1, true);
7647    }
7648
7649    @Override
7650    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7651        if (permission == null) {
7652            return PackageManager.PERMISSION_DENIED;
7653        }
7654
7655        // We might be performing an operation on behalf of an indirect binder
7656        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7657        // client identity accordingly before proceeding.
7658        Identity tlsIdentity = sCallerIdentity.get();
7659        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7660            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7661                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7662            uid = tlsIdentity.uid;
7663            pid = tlsIdentity.pid;
7664        }
7665
7666        return checkComponentPermission(permission, pid, uid, -1, true);
7667    }
7668
7669    /**
7670     * Binder IPC calls go through the public entry point.
7671     * This can be called with or without the global lock held.
7672     */
7673    int checkCallingPermission(String permission) {
7674        return checkPermission(permission,
7675                Binder.getCallingPid(),
7676                UserHandle.getAppId(Binder.getCallingUid()));
7677    }
7678
7679    /**
7680     * This can be called with or without the global lock held.
7681     */
7682    void enforceCallingPermission(String permission, String func) {
7683        if (checkCallingPermission(permission)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return;
7686        }
7687
7688        String msg = "Permission Denial: " + func + " from pid="
7689                + Binder.getCallingPid()
7690                + ", uid=" + Binder.getCallingUid()
7691                + " requires " + permission;
7692        Slog.w(TAG, msg);
7693        throw new SecurityException(msg);
7694    }
7695
7696    /**
7697     * Determine if UID is holding permissions required to access {@link Uri} in
7698     * the given {@link ProviderInfo}. Final permission checking is always done
7699     * in {@link ContentProvider}.
7700     */
7701    private final boolean checkHoldingPermissionsLocked(
7702            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7703        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7704                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7705        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7706            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7707                    != PERMISSION_GRANTED) {
7708                return false;
7709            }
7710        }
7711        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7712    }
7713
7714    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7715            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7716        if (pi.applicationInfo.uid == uid) {
7717            return true;
7718        } else if (!pi.exported) {
7719            return false;
7720        }
7721
7722        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7723        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7724        try {
7725            // check if target holds top-level <provider> permissions
7726            if (!readMet && pi.readPermission != null && considerUidPermissions
7727                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7728                readMet = true;
7729            }
7730            if (!writeMet && pi.writePermission != null && considerUidPermissions
7731                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7732                writeMet = true;
7733            }
7734
7735            // track if unprotected read/write is allowed; any denied
7736            // <path-permission> below removes this ability
7737            boolean allowDefaultRead = pi.readPermission == null;
7738            boolean allowDefaultWrite = pi.writePermission == null;
7739
7740            // check if target holds any <path-permission> that match uri
7741            final PathPermission[] pps = pi.pathPermissions;
7742            if (pps != null) {
7743                final String path = grantUri.uri.getPath();
7744                int i = pps.length;
7745                while (i > 0 && (!readMet || !writeMet)) {
7746                    i--;
7747                    PathPermission pp = pps[i];
7748                    if (pp.match(path)) {
7749                        if (!readMet) {
7750                            final String pprperm = pp.getReadPermission();
7751                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7752                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7753                                    + ": match=" + pp.match(path)
7754                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7755                            if (pprperm != null) {
7756                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7757                                        == PERMISSION_GRANTED) {
7758                                    readMet = true;
7759                                } else {
7760                                    allowDefaultRead = false;
7761                                }
7762                            }
7763                        }
7764                        if (!writeMet) {
7765                            final String ppwperm = pp.getWritePermission();
7766                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7767                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7768                                    + ": match=" + pp.match(path)
7769                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7770                            if (ppwperm != null) {
7771                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7772                                        == PERMISSION_GRANTED) {
7773                                    writeMet = true;
7774                                } else {
7775                                    allowDefaultWrite = false;
7776                                }
7777                            }
7778                        }
7779                    }
7780                }
7781            }
7782
7783            // grant unprotected <provider> read/write, if not blocked by
7784            // <path-permission> above
7785            if (allowDefaultRead) readMet = true;
7786            if (allowDefaultWrite) writeMet = true;
7787
7788        } catch (RemoteException e) {
7789            return false;
7790        }
7791
7792        return readMet && writeMet;
7793    }
7794
7795    public int getAppStartMode(int uid, String packageName) {
7796        synchronized (this) {
7797            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7798        }
7799    }
7800
7801    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7802            boolean allowWhenForeground) {
7803        UidRecord uidRec = mActiveUids.get(uid);
7804        if (!mLenientBackgroundCheck) {
7805            if (!allowWhenForeground || uidRec == null
7806                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7807                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7808                        packageName) != AppOpsManager.MODE_ALLOWED) {
7809                    return ActivityManager.APP_START_MODE_DELAYED;
7810                }
7811            }
7812
7813        } else if (uidRec == null || uidRec.idle) {
7814            if (callingPid >= 0) {
7815                ProcessRecord proc;
7816                synchronized (mPidsSelfLocked) {
7817                    proc = mPidsSelfLocked.get(callingPid);
7818                }
7819                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7820                    // Whoever is instigating this is in the foreground, so we will allow it
7821                    // to go through.
7822                    return ActivityManager.APP_START_MODE_NORMAL;
7823                }
7824            }
7825            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7826                    != AppOpsManager.MODE_ALLOWED) {
7827                return ActivityManager.APP_START_MODE_DELAYED;
7828            }
7829        }
7830        return ActivityManager.APP_START_MODE_NORMAL;
7831    }
7832
7833    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7834        ProviderInfo pi = null;
7835        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7836        if (cpr != null) {
7837            pi = cpr.info;
7838        } else {
7839            try {
7840                pi = AppGlobals.getPackageManager().resolveContentProvider(
7841                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7842                        userHandle);
7843            } catch (RemoteException ex) {
7844            }
7845        }
7846        return pi;
7847    }
7848
7849    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7850        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7851        if (targetUris != null) {
7852            return targetUris.get(grantUri);
7853        }
7854        return null;
7855    }
7856
7857    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7858            String targetPkg, int targetUid, GrantUri grantUri) {
7859        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7860        if (targetUris == null) {
7861            targetUris = Maps.newArrayMap();
7862            mGrantedUriPermissions.put(targetUid, targetUris);
7863        }
7864
7865        UriPermission perm = targetUris.get(grantUri);
7866        if (perm == null) {
7867            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7868            targetUris.put(grantUri, perm);
7869        }
7870
7871        return perm;
7872    }
7873
7874    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7875            final int modeFlags) {
7876        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7877        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7878                : UriPermission.STRENGTH_OWNED;
7879
7880        // Root gets to do everything.
7881        if (uid == 0) {
7882            return true;
7883        }
7884
7885        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7886        if (perms == null) return false;
7887
7888        // First look for exact match
7889        final UriPermission exactPerm = perms.get(grantUri);
7890        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7891            return true;
7892        }
7893
7894        // No exact match, look for prefixes
7895        final int N = perms.size();
7896        for (int i = 0; i < N; i++) {
7897            final UriPermission perm = perms.valueAt(i);
7898            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7899                    && perm.getStrength(modeFlags) >= minStrength) {
7900                return true;
7901            }
7902        }
7903
7904        return false;
7905    }
7906
7907    /**
7908     * @param uri This uri must NOT contain an embedded userId.
7909     * @param userId The userId in which the uri is to be resolved.
7910     */
7911    @Override
7912    public int checkUriPermission(Uri uri, int pid, int uid,
7913            final int modeFlags, int userId, IBinder callerToken) {
7914        enforceNotIsolatedCaller("checkUriPermission");
7915
7916        // Another redirected-binder-call permissions check as in
7917        // {@link checkPermissionWithToken}.
7918        Identity tlsIdentity = sCallerIdentity.get();
7919        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7920            uid = tlsIdentity.uid;
7921            pid = tlsIdentity.pid;
7922        }
7923
7924        // Our own process gets to do everything.
7925        if (pid == MY_PID) {
7926            return PackageManager.PERMISSION_GRANTED;
7927        }
7928        synchronized (this) {
7929            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7930                    ? PackageManager.PERMISSION_GRANTED
7931                    : PackageManager.PERMISSION_DENIED;
7932        }
7933    }
7934
7935    /**
7936     * Check if the targetPkg can be granted permission to access uri by
7937     * the callingUid using the given modeFlags.  Throws a security exception
7938     * if callingUid is not allowed to do this.  Returns the uid of the target
7939     * if the URI permission grant should be performed; returns -1 if it is not
7940     * needed (for example targetPkg already has permission to access the URI).
7941     * If you already know the uid of the target, you can supply it in
7942     * lastTargetUid else set that to -1.
7943     */
7944    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7945            final int modeFlags, int lastTargetUid) {
7946        if (!Intent.isAccessUriMode(modeFlags)) {
7947            return -1;
7948        }
7949
7950        if (targetPkg != null) {
7951            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7952                    "Checking grant " + targetPkg + " permission to " + grantUri);
7953        }
7954
7955        final IPackageManager pm = AppGlobals.getPackageManager();
7956
7957        // If this is not a content: uri, we can't do anything with it.
7958        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7959            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7960                    "Can't grant URI permission for non-content URI: " + grantUri);
7961            return -1;
7962        }
7963
7964        final String authority = grantUri.uri.getAuthority();
7965        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7966                MATCH_DEBUG_TRIAGED_MISSING);
7967        if (pi == null) {
7968            Slog.w(TAG, "No content provider found for permission check: " +
7969                    grantUri.uri.toSafeString());
7970            return -1;
7971        }
7972
7973        int targetUid = lastTargetUid;
7974        if (targetUid < 0 && targetPkg != null) {
7975            try {
7976                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7977                        UserHandle.getUserId(callingUid));
7978                if (targetUid < 0) {
7979                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7980                            "Can't grant URI permission no uid for: " + targetPkg);
7981                    return -1;
7982                }
7983            } catch (RemoteException ex) {
7984                return -1;
7985            }
7986        }
7987
7988        if (targetUid >= 0) {
7989            // First...  does the target actually need this permission?
7990            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7991                // No need to grant the target this permission.
7992                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                        "Target " + targetPkg + " already has full permission to " + grantUri);
7994                return -1;
7995            }
7996        } else {
7997            // First...  there is no target package, so can anyone access it?
7998            boolean allowed = pi.exported;
7999            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8000                if (pi.readPermission != null) {
8001                    allowed = false;
8002                }
8003            }
8004            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8005                if (pi.writePermission != null) {
8006                    allowed = false;
8007                }
8008            }
8009            if (allowed) {
8010                return -1;
8011            }
8012        }
8013
8014        /* There is a special cross user grant if:
8015         * - The target is on another user.
8016         * - Apps on the current user can access the uri without any uid permissions.
8017         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8018         * grant uri permissions.
8019         */
8020        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8021                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8022                modeFlags, false /*without considering the uid permissions*/);
8023
8024        // Second...  is the provider allowing granting of URI permissions?
8025        if (!specialCrossUserGrant) {
8026            if (!pi.grantUriPermissions) {
8027                throw new SecurityException("Provider " + pi.packageName
8028                        + "/" + pi.name
8029                        + " does not allow granting of Uri permissions (uri "
8030                        + grantUri + ")");
8031            }
8032            if (pi.uriPermissionPatterns != null) {
8033                final int N = pi.uriPermissionPatterns.length;
8034                boolean allowed = false;
8035                for (int i=0; i<N; i++) {
8036                    if (pi.uriPermissionPatterns[i] != null
8037                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8038                        allowed = true;
8039                        break;
8040                    }
8041                }
8042                if (!allowed) {
8043                    throw new SecurityException("Provider " + pi.packageName
8044                            + "/" + pi.name
8045                            + " does not allow granting of permission to path of Uri "
8046                            + grantUri);
8047                }
8048            }
8049        }
8050
8051        // Third...  does the caller itself have permission to access
8052        // this uri?
8053        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8054            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8055                // Require they hold a strong enough Uri permission
8056                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8057                    throw new SecurityException("Uid " + callingUid
8058                            + " does not have permission to uri " + grantUri);
8059                }
8060            }
8061        }
8062        return targetUid;
8063    }
8064
8065    /**
8066     * @param uri This uri must NOT contain an embedded userId.
8067     * @param userId The userId in which the uri is to be resolved.
8068     */
8069    @Override
8070    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8071            final int modeFlags, int userId) {
8072        enforceNotIsolatedCaller("checkGrantUriPermission");
8073        synchronized(this) {
8074            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8075                    new GrantUri(userId, uri, false), modeFlags, -1);
8076        }
8077    }
8078
8079    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8080            final int modeFlags, UriPermissionOwner owner) {
8081        if (!Intent.isAccessUriMode(modeFlags)) {
8082            return;
8083        }
8084
8085        // So here we are: the caller has the assumed permission
8086        // to the uri, and the target doesn't.  Let's now give this to
8087        // the target.
8088
8089        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8090                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8091
8092        final String authority = grantUri.uri.getAuthority();
8093        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8094                MATCH_DEBUG_TRIAGED_MISSING);
8095        if (pi == null) {
8096            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8097            return;
8098        }
8099
8100        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8101            grantUri.prefix = true;
8102        }
8103        final UriPermission perm = findOrCreateUriPermissionLocked(
8104                pi.packageName, targetPkg, targetUid, grantUri);
8105        perm.grantModes(modeFlags, owner);
8106    }
8107
8108    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8109            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8110        if (targetPkg == null) {
8111            throw new NullPointerException("targetPkg");
8112        }
8113        int targetUid;
8114        final IPackageManager pm = AppGlobals.getPackageManager();
8115        try {
8116            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8117        } catch (RemoteException ex) {
8118            return;
8119        }
8120
8121        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8122                targetUid);
8123        if (targetUid < 0) {
8124            return;
8125        }
8126
8127        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8128                owner);
8129    }
8130
8131    static class NeededUriGrants extends ArrayList<GrantUri> {
8132        final String targetPkg;
8133        final int targetUid;
8134        final int flags;
8135
8136        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8137            this.targetPkg = targetPkg;
8138            this.targetUid = targetUid;
8139            this.flags = flags;
8140        }
8141    }
8142
8143    /**
8144     * Like checkGrantUriPermissionLocked, but takes an Intent.
8145     */
8146    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8147            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8148        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8149                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8150                + " clip=" + (intent != null ? intent.getClipData() : null)
8151                + " from " + intent + "; flags=0x"
8152                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8153
8154        if (targetPkg == null) {
8155            throw new NullPointerException("targetPkg");
8156        }
8157
8158        if (intent == null) {
8159            return null;
8160        }
8161        Uri data = intent.getData();
8162        ClipData clip = intent.getClipData();
8163        if (data == null && clip == null) {
8164            return null;
8165        }
8166        // Default userId for uris in the intent (if they don't specify it themselves)
8167        int contentUserHint = intent.getContentUserHint();
8168        if (contentUserHint == UserHandle.USER_CURRENT) {
8169            contentUserHint = UserHandle.getUserId(callingUid);
8170        }
8171        final IPackageManager pm = AppGlobals.getPackageManager();
8172        int targetUid;
8173        if (needed != null) {
8174            targetUid = needed.targetUid;
8175        } else {
8176            try {
8177                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8178                        targetUserId);
8179            } catch (RemoteException ex) {
8180                return null;
8181            }
8182            if (targetUid < 0) {
8183                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8184                        "Can't grant URI permission no uid for: " + targetPkg
8185                        + " on user " + targetUserId);
8186                return null;
8187            }
8188        }
8189        if (data != null) {
8190            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8191            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8192                    targetUid);
8193            if (targetUid > 0) {
8194                if (needed == null) {
8195                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8196                }
8197                needed.add(grantUri);
8198            }
8199        }
8200        if (clip != null) {
8201            for (int i=0; i<clip.getItemCount(); i++) {
8202                Uri uri = clip.getItemAt(i).getUri();
8203                if (uri != null) {
8204                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8205                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8206                            targetUid);
8207                    if (targetUid > 0) {
8208                        if (needed == null) {
8209                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8210                        }
8211                        needed.add(grantUri);
8212                    }
8213                } else {
8214                    Intent clipIntent = clip.getItemAt(i).getIntent();
8215                    if (clipIntent != null) {
8216                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8217                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8218                        if (newNeeded != null) {
8219                            needed = newNeeded;
8220                        }
8221                    }
8222                }
8223            }
8224        }
8225
8226        return needed;
8227    }
8228
8229    /**
8230     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8231     */
8232    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8233            UriPermissionOwner owner) {
8234        if (needed != null) {
8235            for (int i=0; i<needed.size(); i++) {
8236                GrantUri grantUri = needed.get(i);
8237                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8238                        grantUri, needed.flags, owner);
8239            }
8240        }
8241    }
8242
8243    void grantUriPermissionFromIntentLocked(int callingUid,
8244            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8245        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8246                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8247        if (needed == null) {
8248            return;
8249        }
8250
8251        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8252    }
8253
8254    /**
8255     * @param uri This uri must NOT contain an embedded userId.
8256     * @param userId The userId in which the uri is to be resolved.
8257     */
8258    @Override
8259    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8260            final int modeFlags, int userId) {
8261        enforceNotIsolatedCaller("grantUriPermission");
8262        GrantUri grantUri = new GrantUri(userId, uri, false);
8263        synchronized(this) {
8264            final ProcessRecord r = getRecordForAppLocked(caller);
8265            if (r == null) {
8266                throw new SecurityException("Unable to find app for caller "
8267                        + caller
8268                        + " when granting permission to uri " + grantUri);
8269            }
8270            if (targetPkg == null) {
8271                throw new IllegalArgumentException("null target");
8272            }
8273            if (grantUri == null) {
8274                throw new IllegalArgumentException("null uri");
8275            }
8276
8277            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8278                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8279                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8280                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8281
8282            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8283                    UserHandle.getUserId(r.uid));
8284        }
8285    }
8286
8287    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8288        if (perm.modeFlags == 0) {
8289            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8290                    perm.targetUid);
8291            if (perms != null) {
8292                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8294
8295                perms.remove(perm.uri);
8296                if (perms.isEmpty()) {
8297                    mGrantedUriPermissions.remove(perm.targetUid);
8298                }
8299            }
8300        }
8301    }
8302
8303    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8304        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8305                "Revoking all granted permissions to " + grantUri);
8306
8307        final IPackageManager pm = AppGlobals.getPackageManager();
8308        final String authority = grantUri.uri.getAuthority();
8309        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8310                MATCH_DEBUG_TRIAGED_MISSING);
8311        if (pi == null) {
8312            Slog.w(TAG, "No content provider found for permission revoke: "
8313                    + grantUri.toSafeString());
8314            return;
8315        }
8316
8317        // Does the caller have this permission on the URI?
8318        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8319            // If they don't have direct access to the URI, then revoke any
8320            // ownerless URI permissions that have been granted to them.
8321            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8322            if (perms != null) {
8323                boolean persistChanged = false;
8324                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8325                    final UriPermission perm = it.next();
8326                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8327                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8328                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8329                                "Revoking non-owned " + perm.targetUid
8330                                + " permission to " + perm.uri);
8331                        persistChanged |= perm.revokeModes(
8332                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8333                        if (perm.modeFlags == 0) {
8334                            it.remove();
8335                        }
8336                    }
8337                }
8338                if (perms.isEmpty()) {
8339                    mGrantedUriPermissions.remove(callingUid);
8340                }
8341                if (persistChanged) {
8342                    schedulePersistUriGrants();
8343                }
8344            }
8345            return;
8346        }
8347
8348        boolean persistChanged = false;
8349
8350        // Go through all of the permissions and remove any that match.
8351        int N = mGrantedUriPermissions.size();
8352        for (int i = 0; i < N; i++) {
8353            final int targetUid = mGrantedUriPermissions.keyAt(i);
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8355
8356            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8357                final UriPermission perm = it.next();
8358                if (perm.uri.sourceUserId == grantUri.sourceUserId
8359                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8360                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8361                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8362                    persistChanged |= perm.revokeModes(
8363                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8364                    if (perm.modeFlags == 0) {
8365                        it.remove();
8366                    }
8367                }
8368            }
8369
8370            if (perms.isEmpty()) {
8371                mGrantedUriPermissions.remove(targetUid);
8372                N--;
8373                i--;
8374            }
8375        }
8376
8377        if (persistChanged) {
8378            schedulePersistUriGrants();
8379        }
8380    }
8381
8382    /**
8383     * @param uri This uri must NOT contain an embedded userId.
8384     * @param userId The userId in which the uri is to be resolved.
8385     */
8386    @Override
8387    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8388            int userId) {
8389        enforceNotIsolatedCaller("revokeUriPermission");
8390        synchronized(this) {
8391            final ProcessRecord r = getRecordForAppLocked(caller);
8392            if (r == null) {
8393                throw new SecurityException("Unable to find app for caller "
8394                        + caller
8395                        + " when revoking permission to uri " + uri);
8396            }
8397            if (uri == null) {
8398                Slog.w(TAG, "revokeUriPermission: null uri");
8399                return;
8400            }
8401
8402            if (!Intent.isAccessUriMode(modeFlags)) {
8403                return;
8404            }
8405
8406            final String authority = uri.getAuthority();
8407            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8408                    MATCH_DEBUG_TRIAGED_MISSING);
8409            if (pi == null) {
8410                Slog.w(TAG, "No content provider found for permission revoke: "
8411                        + uri.toSafeString());
8412                return;
8413            }
8414
8415            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8416        }
8417    }
8418
8419    /**
8420     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8421     * given package.
8422     *
8423     * @param packageName Package name to match, or {@code null} to apply to all
8424     *            packages.
8425     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8426     *            to all users.
8427     * @param persistable If persistable grants should be removed.
8428     */
8429    private void removeUriPermissionsForPackageLocked(
8430            String packageName, int userHandle, boolean persistable) {
8431        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8432            throw new IllegalArgumentException("Must narrow by either package or user");
8433        }
8434
8435        boolean persistChanged = false;
8436
8437        int N = mGrantedUriPermissions.size();
8438        for (int i = 0; i < N; i++) {
8439            final int targetUid = mGrantedUriPermissions.keyAt(i);
8440            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8441
8442            // Only inspect grants matching user
8443            if (userHandle == UserHandle.USER_ALL
8444                    || userHandle == UserHandle.getUserId(targetUid)) {
8445                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8446                    final UriPermission perm = it.next();
8447
8448                    // Only inspect grants matching package
8449                    if (packageName == null || perm.sourcePkg.equals(packageName)
8450                            || perm.targetPkg.equals(packageName)) {
8451                        persistChanged |= perm.revokeModes(persistable
8452                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8453
8454                        // Only remove when no modes remain; any persisted grants
8455                        // will keep this alive.
8456                        if (perm.modeFlags == 0) {
8457                            it.remove();
8458                        }
8459                    }
8460                }
8461
8462                if (perms.isEmpty()) {
8463                    mGrantedUriPermissions.remove(targetUid);
8464                    N--;
8465                    i--;
8466                }
8467            }
8468        }
8469
8470        if (persistChanged) {
8471            schedulePersistUriGrants();
8472        }
8473    }
8474
8475    @Override
8476    public IBinder newUriPermissionOwner(String name) {
8477        enforceNotIsolatedCaller("newUriPermissionOwner");
8478        synchronized(this) {
8479            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8480            return owner.getExternalTokenLocked();
8481        }
8482    }
8483
8484    @Override
8485    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8486        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8487        synchronized(this) {
8488            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8489            if (r == null) {
8490                throw new IllegalArgumentException("Activity does not exist; token="
8491                        + activityToken);
8492            }
8493            return r.getUriPermissionsLocked().getExternalTokenLocked();
8494        }
8495    }
8496    /**
8497     * @param uri This uri must NOT contain an embedded userId.
8498     * @param sourceUserId The userId in which the uri is to be resolved.
8499     * @param targetUserId The userId of the app that receives the grant.
8500     */
8501    @Override
8502    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8503            final int modeFlags, int sourceUserId, int targetUserId) {
8504        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8505                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8506                "grantUriPermissionFromOwner", null);
8507        synchronized(this) {
8508            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8509            if (owner == null) {
8510                throw new IllegalArgumentException("Unknown owner: " + token);
8511            }
8512            if (fromUid != Binder.getCallingUid()) {
8513                if (Binder.getCallingUid() != Process.myUid()) {
8514                    // Only system code can grant URI permissions on behalf
8515                    // of other users.
8516                    throw new SecurityException("nice try");
8517                }
8518            }
8519            if (targetPkg == null) {
8520                throw new IllegalArgumentException("null target");
8521            }
8522            if (uri == null) {
8523                throw new IllegalArgumentException("null uri");
8524            }
8525
8526            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8527                    modeFlags, owner, targetUserId);
8528        }
8529    }
8530
8531    /**
8532     * @param uri This uri must NOT contain an embedded userId.
8533     * @param userId The userId in which the uri is to be resolved.
8534     */
8535    @Override
8536    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8537        synchronized(this) {
8538            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8539            if (owner == null) {
8540                throw new IllegalArgumentException("Unknown owner: " + token);
8541            }
8542
8543            if (uri == null) {
8544                owner.removeUriPermissionsLocked(mode);
8545            } else {
8546                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8547            }
8548        }
8549    }
8550
8551    private void schedulePersistUriGrants() {
8552        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8553            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8554                    10 * DateUtils.SECOND_IN_MILLIS);
8555        }
8556    }
8557
8558    private void writeGrantedUriPermissions() {
8559        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8560
8561        // Snapshot permissions so we can persist without lock
8562        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8563        synchronized (this) {
8564            final int size = mGrantedUriPermissions.size();
8565            for (int i = 0; i < size; i++) {
8566                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8567                for (UriPermission perm : perms.values()) {
8568                    if (perm.persistedModeFlags != 0) {
8569                        persist.add(perm.snapshot());
8570                    }
8571                }
8572            }
8573        }
8574
8575        FileOutputStream fos = null;
8576        try {
8577            fos = mGrantFile.startWrite();
8578
8579            XmlSerializer out = new FastXmlSerializer();
8580            out.setOutput(fos, StandardCharsets.UTF_8.name());
8581            out.startDocument(null, true);
8582            out.startTag(null, TAG_URI_GRANTS);
8583            for (UriPermission.Snapshot perm : persist) {
8584                out.startTag(null, TAG_URI_GRANT);
8585                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8586                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8587                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8588                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8589                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8590                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8591                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8592                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8593                out.endTag(null, TAG_URI_GRANT);
8594            }
8595            out.endTag(null, TAG_URI_GRANTS);
8596            out.endDocument();
8597
8598            mGrantFile.finishWrite(fos);
8599        } catch (IOException e) {
8600            if (fos != null) {
8601                mGrantFile.failWrite(fos);
8602            }
8603        }
8604    }
8605
8606    private void readGrantedUriPermissionsLocked() {
8607        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8608
8609        final long now = System.currentTimeMillis();
8610
8611        FileInputStream fis = null;
8612        try {
8613            fis = mGrantFile.openRead();
8614            final XmlPullParser in = Xml.newPullParser();
8615            in.setInput(fis, StandardCharsets.UTF_8.name());
8616
8617            int type;
8618            while ((type = in.next()) != END_DOCUMENT) {
8619                final String tag = in.getName();
8620                if (type == START_TAG) {
8621                    if (TAG_URI_GRANT.equals(tag)) {
8622                        final int sourceUserId;
8623                        final int targetUserId;
8624                        final int userHandle = readIntAttribute(in,
8625                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8626                        if (userHandle != UserHandle.USER_NULL) {
8627                            // For backwards compatibility.
8628                            sourceUserId = userHandle;
8629                            targetUserId = userHandle;
8630                        } else {
8631                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8632                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8633                        }
8634                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8635                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8636                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8637                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8638                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8639                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8640
8641                        // Sanity check that provider still belongs to source package
8642                        // Both direct boot aware and unaware packages are fine as we
8643                        // will do filtering at query time to avoid multiple parsing.
8644                        final ProviderInfo pi = getProviderInfoLocked(
8645                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8646                                        | MATCH_DIRECT_BOOT_UNAWARE);
8647                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8648                            int targetUid = -1;
8649                            try {
8650                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8651                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8652                            } catch (RemoteException e) {
8653                            }
8654                            if (targetUid != -1) {
8655                                final UriPermission perm = findOrCreateUriPermissionLocked(
8656                                        sourcePkg, targetPkg, targetUid,
8657                                        new GrantUri(sourceUserId, uri, prefix));
8658                                perm.initPersistedModes(modeFlags, createdTime);
8659                            }
8660                        } else {
8661                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8662                                    + " but instead found " + pi);
8663                        }
8664                    }
8665                }
8666            }
8667        } catch (FileNotFoundException e) {
8668            // Missing grants is okay
8669        } catch (IOException e) {
8670            Slog.wtf(TAG, "Failed reading Uri grants", e);
8671        } catch (XmlPullParserException e) {
8672            Slog.wtf(TAG, "Failed reading Uri grants", e);
8673        } finally {
8674            IoUtils.closeQuietly(fis);
8675        }
8676    }
8677
8678    /**
8679     * @param uri This uri must NOT contain an embedded userId.
8680     * @param userId The userId in which the uri is to be resolved.
8681     */
8682    @Override
8683    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8684        enforceNotIsolatedCaller("takePersistableUriPermission");
8685
8686        Preconditions.checkFlagsArgument(modeFlags,
8687                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8688
8689        synchronized (this) {
8690            final int callingUid = Binder.getCallingUid();
8691            boolean persistChanged = false;
8692            GrantUri grantUri = new GrantUri(userId, uri, false);
8693
8694            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8695                    new GrantUri(userId, uri, false));
8696            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8697                    new GrantUri(userId, uri, true));
8698
8699            final boolean exactValid = (exactPerm != null)
8700                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8701            final boolean prefixValid = (prefixPerm != null)
8702                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8703
8704            if (!(exactValid || prefixValid)) {
8705                throw new SecurityException("No persistable permission grants found for UID "
8706                        + callingUid + " and Uri " + grantUri.toSafeString());
8707            }
8708
8709            if (exactValid) {
8710                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8711            }
8712            if (prefixValid) {
8713                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8714            }
8715
8716            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8717
8718            if (persistChanged) {
8719                schedulePersistUriGrants();
8720            }
8721        }
8722    }
8723
8724    /**
8725     * @param uri This uri must NOT contain an embedded userId.
8726     * @param userId The userId in which the uri is to be resolved.
8727     */
8728    @Override
8729    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8730        enforceNotIsolatedCaller("releasePersistableUriPermission");
8731
8732        Preconditions.checkFlagsArgument(modeFlags,
8733                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8734
8735        synchronized (this) {
8736            final int callingUid = Binder.getCallingUid();
8737            boolean persistChanged = false;
8738
8739            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8740                    new GrantUri(userId, uri, false));
8741            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8742                    new GrantUri(userId, uri, true));
8743            if (exactPerm == null && prefixPerm == null) {
8744                throw new SecurityException("No permission grants found for UID " + callingUid
8745                        + " and Uri " + uri.toSafeString());
8746            }
8747
8748            if (exactPerm != null) {
8749                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8750                removeUriPermissionIfNeededLocked(exactPerm);
8751            }
8752            if (prefixPerm != null) {
8753                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8754                removeUriPermissionIfNeededLocked(prefixPerm);
8755            }
8756
8757            if (persistChanged) {
8758                schedulePersistUriGrants();
8759            }
8760        }
8761    }
8762
8763    /**
8764     * Prune any older {@link UriPermission} for the given UID until outstanding
8765     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8766     *
8767     * @return if any mutations occured that require persisting.
8768     */
8769    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8770        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8771        if (perms == null) return false;
8772        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8773
8774        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8775        for (UriPermission perm : perms.values()) {
8776            if (perm.persistedModeFlags != 0) {
8777                persisted.add(perm);
8778            }
8779        }
8780
8781        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8782        if (trimCount <= 0) return false;
8783
8784        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8785        for (int i = 0; i < trimCount; i++) {
8786            final UriPermission perm = persisted.get(i);
8787
8788            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8789                    "Trimming grant created at " + perm.persistedCreateTime);
8790
8791            perm.releasePersistableModes(~0);
8792            removeUriPermissionIfNeededLocked(perm);
8793        }
8794
8795        return true;
8796    }
8797
8798    @Override
8799    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8800            String packageName, boolean incoming) {
8801        enforceNotIsolatedCaller("getPersistedUriPermissions");
8802        Preconditions.checkNotNull(packageName, "packageName");
8803
8804        final int callingUid = Binder.getCallingUid();
8805        final IPackageManager pm = AppGlobals.getPackageManager();
8806        try {
8807            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8808                    UserHandle.getUserId(callingUid));
8809            if (packageUid != callingUid) {
8810                throw new SecurityException(
8811                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8812            }
8813        } catch (RemoteException e) {
8814            throw new SecurityException("Failed to verify package name ownership");
8815        }
8816
8817        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8818        synchronized (this) {
8819            if (incoming) {
8820                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8821                        callingUid);
8822                if (perms == null) {
8823                    Slog.w(TAG, "No permission grants found for " + packageName);
8824                } else {
8825                    final int userId = UserHandle.getUserId(callingUid);
8826                    Set<String> existingAuthorities = null;
8827
8828                    for (UriPermission perm : perms.values()) {
8829                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8830                            // Is this provider available in the current boot state? If the user
8831                            // is not running and unlocked we check if the provider package exists.
8832                            if (!mUserController.isUserRunningLocked(userId,
8833                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8834                                String authority = perm.uri.uri.getAuthority();
8835                                if (existingAuthorities == null
8836                                        || !existingAuthorities.contains(authority)) {
8837                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8838                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8839                                    if (providerInfo != null) {
8840                                        if (existingAuthorities == null) {
8841                                            existingAuthorities = new ArraySet<>();
8842                                        }
8843                                        existingAuthorities.add(authority);
8844                                    } else {
8845                                        continue;
8846                                    }
8847                                }
8848                            }
8849                            result.add(perm.buildPersistedPublicApiObject());
8850                        }
8851                    }
8852                }
8853            } else {
8854                final int size = mGrantedUriPermissions.size();
8855                for (int i = 0; i < size; i++) {
8856                    final ArrayMap<GrantUri, UriPermission> perms =
8857                            mGrantedUriPermissions.valueAt(i);
8858                    for (UriPermission perm : perms.values()) {
8859                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8860                            result.add(perm.buildPersistedPublicApiObject());
8861                        }
8862                    }
8863                }
8864            }
8865        }
8866        return new ParceledListSlice<android.content.UriPermission>(result);
8867    }
8868
8869    @Override
8870    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8871            String packageName, int userId) {
8872        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8873                "getGrantedUriPermissions");
8874
8875        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8876        synchronized (this) {
8877            final int size = mGrantedUriPermissions.size();
8878            for (int i = 0; i < size; i++) {
8879                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8880                for (UriPermission perm : perms.values()) {
8881                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8882                            && perm.persistedModeFlags != 0) {
8883                        result.add(perm.buildPersistedPublicApiObject());
8884                    }
8885                }
8886            }
8887        }
8888        return new ParceledListSlice<android.content.UriPermission>(result);
8889    }
8890
8891    @Override
8892    public void clearGrantedUriPermissions(String packageName, int userId) {
8893        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8894                "clearGrantedUriPermissions");
8895        removeUriPermissionsForPackageLocked(packageName, userId, true);
8896    }
8897
8898    @Override
8899    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8900        synchronized (this) {
8901            ProcessRecord app =
8902                who != null ? getRecordForAppLocked(who) : null;
8903            if (app == null) return;
8904
8905            Message msg = Message.obtain();
8906            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8907            msg.obj = app;
8908            msg.arg1 = waiting ? 1 : 0;
8909            mUiHandler.sendMessage(msg);
8910        }
8911    }
8912
8913    @Override
8914    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8915        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8916        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8917        outInfo.availMem = Process.getFreeMemory();
8918        outInfo.totalMem = Process.getTotalMemory();
8919        outInfo.threshold = homeAppMem;
8920        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8921        outInfo.hiddenAppThreshold = cachedAppMem;
8922        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8923                ProcessList.SERVICE_ADJ);
8924        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8925                ProcessList.VISIBLE_APP_ADJ);
8926        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8927                ProcessList.FOREGROUND_APP_ADJ);
8928    }
8929
8930    // =========================================================
8931    // TASK MANAGEMENT
8932    // =========================================================
8933
8934    @Override
8935    public List<IAppTask> getAppTasks(String callingPackage) {
8936        int callingUid = Binder.getCallingUid();
8937        long ident = Binder.clearCallingIdentity();
8938
8939        synchronized(this) {
8940            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8941            try {
8942                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8943
8944                final int N = mRecentTasks.size();
8945                for (int i = 0; i < N; i++) {
8946                    TaskRecord tr = mRecentTasks.get(i);
8947                    // Skip tasks that do not match the caller.  We don't need to verify
8948                    // callingPackage, because we are also limiting to callingUid and know
8949                    // that will limit to the correct security sandbox.
8950                    if (tr.effectiveUid != callingUid) {
8951                        continue;
8952                    }
8953                    Intent intent = tr.getBaseIntent();
8954                    if (intent == null ||
8955                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8956                        continue;
8957                    }
8958                    ActivityManager.RecentTaskInfo taskInfo =
8959                            createRecentTaskInfoFromTaskRecord(tr);
8960                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8961                    list.add(taskImpl);
8962                }
8963            } finally {
8964                Binder.restoreCallingIdentity(ident);
8965            }
8966            return list;
8967        }
8968    }
8969
8970    @Override
8971    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8972        final int callingUid = Binder.getCallingUid();
8973        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8974
8975        synchronized(this) {
8976            if (DEBUG_ALL) Slog.v(
8977                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8978
8979            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8980                    callingUid);
8981
8982            // TODO: Improve with MRU list from all ActivityStacks.
8983            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8984        }
8985
8986        return list;
8987    }
8988
8989    /**
8990     * Creates a new RecentTaskInfo from a TaskRecord.
8991     */
8992    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8993        // Update the task description to reflect any changes in the task stack
8994        tr.updateTaskDescription();
8995
8996        // Compose the recent task info
8997        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8998        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8999        rti.persistentId = tr.taskId;
9000        rti.baseIntent = new Intent(tr.getBaseIntent());
9001        rti.origActivity = tr.origActivity;
9002        rti.realActivity = tr.realActivity;
9003        rti.description = tr.lastDescription;
9004        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9005        rti.userId = tr.userId;
9006        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9007        rti.firstActiveTime = tr.firstActiveTime;
9008        rti.lastActiveTime = tr.lastActiveTime;
9009        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9010        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9011        rti.numActivities = 0;
9012        if (tr.mBounds != null) {
9013            rti.bounds = new Rect(tr.mBounds);
9014        }
9015        rti.isDockable = tr.canGoInDockedStack();
9016        rti.resizeMode = tr.mResizeMode;
9017
9018        ActivityRecord base = null;
9019        ActivityRecord top = null;
9020        ActivityRecord tmp;
9021
9022        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9023            tmp = tr.mActivities.get(i);
9024            if (tmp.finishing) {
9025                continue;
9026            }
9027            base = tmp;
9028            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9029                top = base;
9030            }
9031            rti.numActivities++;
9032        }
9033
9034        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9035        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9036
9037        return rti;
9038    }
9039
9040    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9041        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9042                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9043        if (!allowed) {
9044            if (checkPermission(android.Manifest.permission.GET_TASKS,
9045                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9046                // Temporary compatibility: some existing apps on the system image may
9047                // still be requesting the old permission and not switched to the new
9048                // one; if so, we'll still allow them full access.  This means we need
9049                // to see if they are holding the old permission and are a system app.
9050                try {
9051                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9052                        allowed = true;
9053                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9054                                + " is using old GET_TASKS but privileged; allowing");
9055                    }
9056                } catch (RemoteException e) {
9057                }
9058            }
9059        }
9060        if (!allowed) {
9061            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9062                    + " does not hold REAL_GET_TASKS; limiting output");
9063        }
9064        return allowed;
9065    }
9066
9067    @Override
9068    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9069        final int callingUid = Binder.getCallingUid();
9070        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9071                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9072
9073        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9074        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9075        synchronized (this) {
9076            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9077                    callingUid);
9078            final boolean detailed = checkCallingPermission(
9079                    android.Manifest.permission.GET_DETAILED_TASKS)
9080                    == PackageManager.PERMISSION_GRANTED;
9081
9082            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9083                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9084                return Collections.emptyList();
9085            }
9086            mRecentTasks.loadUserRecentsLocked(userId);
9087
9088            final int recentsCount = mRecentTasks.size();
9089            ArrayList<ActivityManager.RecentTaskInfo> res =
9090                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9091
9092            final Set<Integer> includedUsers;
9093            if (includeProfiles) {
9094                includedUsers = mUserController.getProfileIds(userId);
9095            } else {
9096                includedUsers = new HashSet<>();
9097            }
9098            includedUsers.add(Integer.valueOf(userId));
9099
9100            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9101                TaskRecord tr = mRecentTasks.get(i);
9102                // Only add calling user or related users recent tasks
9103                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9104                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9105                    continue;
9106                }
9107
9108                if (tr.realActivitySuspended) {
9109                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9110                    continue;
9111                }
9112
9113                // Return the entry if desired by the caller.  We always return
9114                // the first entry, because callers always expect this to be the
9115                // foreground app.  We may filter others if the caller has
9116                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9117                // we should exclude the entry.
9118
9119                if (i == 0
9120                        || withExcluded
9121                        || (tr.intent == null)
9122                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9123                                == 0)) {
9124                    if (!allowed) {
9125                        // If the caller doesn't have the GET_TASKS permission, then only
9126                        // allow them to see a small subset of tasks -- their own and home.
9127                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9128                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9129                            continue;
9130                        }
9131                    }
9132                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9133                        if (tr.stack != null && tr.stack.isHomeStack()) {
9134                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9135                                    "Skipping, home stack task: " + tr);
9136                            continue;
9137                        }
9138                    }
9139                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9140                        final ActivityStack stack = tr.stack;
9141                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9142                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9143                                    "Skipping, top task in docked stack: " + tr);
9144                            continue;
9145                        }
9146                    }
9147                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9148                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9149                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9150                                    "Skipping, pinned stack task: " + tr);
9151                            continue;
9152                        }
9153                    }
9154                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9155                        // Don't include auto remove tasks that are finished or finishing.
9156                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9157                                "Skipping, auto-remove without activity: " + tr);
9158                        continue;
9159                    }
9160                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9161                            && !tr.isAvailable) {
9162                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9163                                "Skipping, unavail real act: " + tr);
9164                        continue;
9165                    }
9166
9167                    if (!tr.mUserSetupComplete) {
9168                        // Don't include task launched while user is not done setting-up.
9169                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                "Skipping, user setup not complete: " + tr);
9171                        continue;
9172                    }
9173
9174                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9175                    if (!detailed) {
9176                        rti.baseIntent.replaceExtras((Bundle)null);
9177                    }
9178
9179                    res.add(rti);
9180                    maxNum--;
9181                }
9182            }
9183            return res;
9184        }
9185    }
9186
9187    @Override
9188    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9189        synchronized (this) {
9190            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9191                    "getTaskThumbnail()");
9192            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9193                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9194            if (tr != null) {
9195                return tr.getTaskThumbnailLocked();
9196            }
9197        }
9198        return null;
9199    }
9200
9201    @Override
9202    public int addAppTask(IBinder activityToken, Intent intent,
9203            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9204        final int callingUid = Binder.getCallingUid();
9205        final long callingIdent = Binder.clearCallingIdentity();
9206
9207        try {
9208            synchronized (this) {
9209                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9210                if (r == null) {
9211                    throw new IllegalArgumentException("Activity does not exist; token="
9212                            + activityToken);
9213                }
9214                ComponentName comp = intent.getComponent();
9215                if (comp == null) {
9216                    throw new IllegalArgumentException("Intent " + intent
9217                            + " must specify explicit component");
9218                }
9219                if (thumbnail.getWidth() != mThumbnailWidth
9220                        || thumbnail.getHeight() != mThumbnailHeight) {
9221                    throw new IllegalArgumentException("Bad thumbnail size: got "
9222                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9223                            + mThumbnailWidth + "x" + mThumbnailHeight);
9224                }
9225                if (intent.getSelector() != null) {
9226                    intent.setSelector(null);
9227                }
9228                if (intent.getSourceBounds() != null) {
9229                    intent.setSourceBounds(null);
9230                }
9231                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9232                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9233                        // The caller has added this as an auto-remove task...  that makes no
9234                        // sense, so turn off auto-remove.
9235                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9236                    }
9237                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9238                    // Must be a new task.
9239                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9240                }
9241                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9242                    mLastAddedTaskActivity = null;
9243                }
9244                ActivityInfo ainfo = mLastAddedTaskActivity;
9245                if (ainfo == null) {
9246                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9247                            comp, 0, UserHandle.getUserId(callingUid));
9248                    if (ainfo.applicationInfo.uid != callingUid) {
9249                        throw new SecurityException(
9250                                "Can't add task for another application: target uid="
9251                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9252                    }
9253                }
9254
9255                // Use the full screen as the context for the task thumbnail
9256                final Point displaySize = new Point();
9257                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9258                r.task.stack.getDisplaySize(displaySize);
9259                thumbnailInfo.taskWidth = displaySize.x;
9260                thumbnailInfo.taskHeight = displaySize.y;
9261                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9262
9263                TaskRecord task = new TaskRecord(this,
9264                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9265                        ainfo, intent, description, thumbnailInfo);
9266
9267                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9268                if (trimIdx >= 0) {
9269                    // If this would have caused a trim, then we'll abort because that
9270                    // means it would be added at the end of the list but then just removed.
9271                    return INVALID_TASK_ID;
9272                }
9273
9274                final int N = mRecentTasks.size();
9275                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9276                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9277                    tr.removedFromRecents();
9278                }
9279
9280                task.inRecents = true;
9281                mRecentTasks.add(task);
9282                r.task.stack.addTask(task, false, "addAppTask");
9283
9284                task.setLastThumbnailLocked(thumbnail);
9285                task.freeLastThumbnail();
9286
9287                return task.taskId;
9288            }
9289        } finally {
9290            Binder.restoreCallingIdentity(callingIdent);
9291        }
9292    }
9293
9294    @Override
9295    public Point getAppTaskThumbnailSize() {
9296        synchronized (this) {
9297            return new Point(mThumbnailWidth,  mThumbnailHeight);
9298        }
9299    }
9300
9301    @Override
9302    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9303        synchronized (this) {
9304            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9305            if (r != null) {
9306                r.setTaskDescription(td);
9307                r.task.updateTaskDescription();
9308            }
9309        }
9310    }
9311
9312    @Override
9313    public void setTaskResizeable(int taskId, int resizeableMode) {
9314        synchronized (this) {
9315            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9316                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9317            if (task == null) {
9318                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9319                return;
9320            }
9321            if (task.mResizeMode != resizeableMode) {
9322                task.mResizeMode = resizeableMode;
9323                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9324                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9325                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9326            }
9327        }
9328    }
9329
9330    @Override
9331    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9332        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9333        long ident = Binder.clearCallingIdentity();
9334        try {
9335            synchronized (this) {
9336                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9337                if (task == null) {
9338                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9339                    return;
9340                }
9341                int stackId = task.stack.mStackId;
9342                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9343                // in crop windows resize mode or if the task size is affected by the docked stack
9344                // changing size. No need to update configuration.
9345                if (bounds != null && task.inCropWindowsResizeMode()
9346                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9347                    mWindowManager.scrollTask(task.taskId, bounds);
9348                    return;
9349                }
9350
9351                // Place the task in the right stack if it isn't there already based on
9352                // the requested bounds.
9353                // The stack transition logic is:
9354                // - a null bounds on a freeform task moves that task to fullscreen
9355                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9356                //   that task to freeform
9357                // - otherwise the task is not moved
9358                if (!StackId.isTaskResizeAllowed(stackId)) {
9359                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9360                }
9361                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9362                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9363                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9364                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9365                }
9366                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9367                if (stackId != task.stack.mStackId) {
9368                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9369                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9370                    preserveWindow = false;
9371                }
9372
9373                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9374                        false /* deferResume */);
9375            }
9376        } finally {
9377            Binder.restoreCallingIdentity(ident);
9378        }
9379    }
9380
9381    @Override
9382    public Rect getTaskBounds(int taskId) {
9383        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9384        long ident = Binder.clearCallingIdentity();
9385        Rect rect = new Rect();
9386        try {
9387            synchronized (this) {
9388                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9389                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9390                if (task == null) {
9391                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9392                    return rect;
9393                }
9394                if (task.stack != null) {
9395                    // Return the bounds from window manager since it will be adjusted for various
9396                    // things like the presense of a docked stack for tasks that aren't resizeable.
9397                    mWindowManager.getTaskBounds(task.taskId, rect);
9398                } else {
9399                    // Task isn't in window manager yet since it isn't associated with a stack.
9400                    // Return the persist value from activity manager
9401                    if (task.mBounds != null) {
9402                        rect.set(task.mBounds);
9403                    } else if (task.mLastNonFullscreenBounds != null) {
9404                        rect.set(task.mLastNonFullscreenBounds);
9405                    }
9406                }
9407            }
9408        } finally {
9409            Binder.restoreCallingIdentity(ident);
9410        }
9411        return rect;
9412    }
9413
9414    @Override
9415    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9416        if (userId != UserHandle.getCallingUserId()) {
9417            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9418                    "getTaskDescriptionIcon");
9419        }
9420        final File passedIconFile = new File(filePath);
9421        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9422                passedIconFile.getName());
9423        if (!legitIconFile.getPath().equals(filePath)
9424                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9425            throw new IllegalArgumentException("Bad file path: " + filePath
9426                    + " passed for userId " + userId);
9427        }
9428        return mRecentTasks.getTaskDescriptionIcon(filePath);
9429    }
9430
9431    @Override
9432    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9433            throws RemoteException {
9434        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9435                opts.getCustomInPlaceResId() == 0) {
9436            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9437                    "with valid animation");
9438        }
9439        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9440        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9441                opts.getCustomInPlaceResId());
9442        mWindowManager.executeAppTransition();
9443    }
9444
9445    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9446            boolean removeFromRecents) {
9447        if (removeFromRecents) {
9448            mRecentTasks.remove(tr);
9449            tr.removedFromRecents();
9450        }
9451        ComponentName component = tr.getBaseIntent().getComponent();
9452        if (component == null) {
9453            Slog.w(TAG, "No component for base intent of task: " + tr);
9454            return;
9455        }
9456
9457        // Find any running services associated with this app and stop if needed.
9458        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9459
9460        if (!killProcess) {
9461            return;
9462        }
9463
9464        // Determine if the process(es) for this task should be killed.
9465        final String pkg = component.getPackageName();
9466        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9467        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9468        for (int i = 0; i < pmap.size(); i++) {
9469
9470            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9471            for (int j = 0; j < uids.size(); j++) {
9472                ProcessRecord proc = uids.valueAt(j);
9473                if (proc.userId != tr.userId) {
9474                    // Don't kill process for a different user.
9475                    continue;
9476                }
9477                if (proc == mHomeProcess) {
9478                    // Don't kill the home process along with tasks from the same package.
9479                    continue;
9480                }
9481                if (!proc.pkgList.containsKey(pkg)) {
9482                    // Don't kill process that is not associated with this task.
9483                    continue;
9484                }
9485
9486                for (int k = 0; k < proc.activities.size(); k++) {
9487                    TaskRecord otherTask = proc.activities.get(k).task;
9488                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9489                        // Don't kill process(es) that has an activity in a different task that is
9490                        // also in recents.
9491                        return;
9492                    }
9493                }
9494
9495                if (proc.foregroundServices) {
9496                    // Don't kill process(es) with foreground service.
9497                    return;
9498                }
9499
9500                // Add process to kill list.
9501                procsToKill.add(proc);
9502            }
9503        }
9504
9505        // Kill the running processes.
9506        for (int i = 0; i < procsToKill.size(); i++) {
9507            ProcessRecord pr = procsToKill.get(i);
9508            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9509                    && pr.curReceiver == null) {
9510                pr.kill("remove task", true);
9511            } else {
9512                // We delay killing processes that are not in the background or running a receiver.
9513                pr.waitingToKill = "remove task";
9514            }
9515        }
9516    }
9517
9518    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9519        // Remove all tasks with activities in the specified package from the list of recent tasks
9520        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9521            TaskRecord tr = mRecentTasks.get(i);
9522            if (tr.userId != userId) continue;
9523
9524            ComponentName cn = tr.intent.getComponent();
9525            if (cn != null && cn.getPackageName().equals(packageName)) {
9526                // If the package name matches, remove the task.
9527                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9528            }
9529        }
9530    }
9531
9532    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9533            int userId) {
9534
9535        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9536            TaskRecord tr = mRecentTasks.get(i);
9537            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9538                continue;
9539            }
9540
9541            ComponentName cn = tr.intent.getComponent();
9542            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9543                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9544            if (sameComponent) {
9545                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9546            }
9547        }
9548    }
9549
9550    /**
9551     * Removes the task with the specified task id.
9552     *
9553     * @param taskId Identifier of the task to be removed.
9554     * @param killProcess Kill any process associated with the task if possible.
9555     * @param removeFromRecents Whether to also remove the task from recents.
9556     * @return Returns true if the given task was found and removed.
9557     */
9558    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9559            boolean removeFromRecents) {
9560        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9561                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9562        if (tr != null) {
9563            tr.removeTaskActivitiesLocked();
9564            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9565            if (tr.isPersistable) {
9566                notifyTaskPersisterLocked(null, true);
9567            }
9568            return true;
9569        }
9570        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9571        return false;
9572    }
9573
9574    @Override
9575    public void removeStack(int stackId) {
9576        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9577        if (stackId == HOME_STACK_ID) {
9578            throw new IllegalArgumentException("Removing home stack is not allowed.");
9579        }
9580
9581        synchronized (this) {
9582            final long ident = Binder.clearCallingIdentity();
9583            try {
9584                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9585                if (stack == null) {
9586                    return;
9587                }
9588                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9589                for (int i = tasks.size() - 1; i >= 0; i--) {
9590                    removeTaskByIdLocked(
9591                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9592                }
9593            } finally {
9594                Binder.restoreCallingIdentity(ident);
9595            }
9596        }
9597    }
9598
9599    @Override
9600    public boolean removeTask(int taskId) {
9601        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9602        synchronized (this) {
9603            final long ident = Binder.clearCallingIdentity();
9604            try {
9605                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9606            } finally {
9607                Binder.restoreCallingIdentity(ident);
9608            }
9609        }
9610    }
9611
9612    /**
9613     * TODO: Add mController hook
9614     */
9615    @Override
9616    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9617        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9618
9619        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9620        synchronized(this) {
9621            moveTaskToFrontLocked(taskId, flags, bOptions);
9622        }
9623    }
9624
9625    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9626        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9627
9628        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9629                Binder.getCallingUid(), -1, -1, "Task to front")) {
9630            ActivityOptions.abort(options);
9631            return;
9632        }
9633        final long origId = Binder.clearCallingIdentity();
9634        try {
9635            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9636            if (task == null) {
9637                Slog.d(TAG, "Could not find task for id: "+ taskId);
9638                return;
9639            }
9640            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9641                mStackSupervisor.showLockTaskToast();
9642                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9643                return;
9644            }
9645            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9646            if (prev != null && prev.isRecentsActivity()) {
9647                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9648            }
9649            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9650                    false /* forceNonResizable */);
9651        } finally {
9652            Binder.restoreCallingIdentity(origId);
9653        }
9654        ActivityOptions.abort(options);
9655    }
9656
9657    /**
9658     * Moves an activity, and all of the other activities within the same task, to the bottom
9659     * of the history stack.  The activity's order within the task is unchanged.
9660     *
9661     * @param token A reference to the activity we wish to move
9662     * @param nonRoot If false then this only works if the activity is the root
9663     *                of a task; if true it will work for any activity in a task.
9664     * @return Returns true if the move completed, false if not.
9665     */
9666    @Override
9667    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9668        enforceNotIsolatedCaller("moveActivityTaskToBack");
9669        synchronized(this) {
9670            final long origId = Binder.clearCallingIdentity();
9671            try {
9672                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9673                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9674                if (task != null) {
9675                    if (mStackSupervisor.isLockedTask(task)) {
9676                        mStackSupervisor.showLockTaskToast();
9677                        return false;
9678                    }
9679                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9680                }
9681            } finally {
9682                Binder.restoreCallingIdentity(origId);
9683            }
9684        }
9685        return false;
9686    }
9687
9688    @Override
9689    public void moveTaskBackwards(int task) {
9690        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9691                "moveTaskBackwards()");
9692
9693        synchronized(this) {
9694            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9695                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9696                return;
9697            }
9698            final long origId = Binder.clearCallingIdentity();
9699            moveTaskBackwardsLocked(task);
9700            Binder.restoreCallingIdentity(origId);
9701        }
9702    }
9703
9704    private final void moveTaskBackwardsLocked(int task) {
9705        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9706    }
9707
9708    @Override
9709    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9710            IActivityContainerCallback callback) throws RemoteException {
9711        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9712        synchronized (this) {
9713            if (parentActivityToken == null) {
9714                throw new IllegalArgumentException("parent token must not be null");
9715            }
9716            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9717            if (r == null) {
9718                return null;
9719            }
9720            if (callback == null) {
9721                throw new IllegalArgumentException("callback must not be null");
9722            }
9723            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9724        }
9725    }
9726
9727    @Override
9728    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9730        synchronized (this) {
9731            mStackSupervisor.deleteActivityContainer(container);
9732        }
9733    }
9734
9735    @Override
9736    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9738        synchronized (this) {
9739            final int stackId = mStackSupervisor.getNextStackId();
9740            final ActivityStack stack =
9741                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9742            if (stack == null) {
9743                return null;
9744            }
9745            return stack.mActivityContainer;
9746        }
9747    }
9748
9749    @Override
9750    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9751        synchronized (this) {
9752            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9753            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9754                return stack.mActivityContainer.getDisplayId();
9755            }
9756            return Display.DEFAULT_DISPLAY;
9757        }
9758    }
9759
9760    @Override
9761    public int getActivityStackId(IBinder token) throws RemoteException {
9762        synchronized (this) {
9763            ActivityStack stack = ActivityRecord.getStackLocked(token);
9764            if (stack == null) {
9765                return INVALID_STACK_ID;
9766            }
9767            return stack.mStackId;
9768        }
9769    }
9770
9771    @Override
9772    public void exitFreeformMode(IBinder token) throws RemoteException {
9773        synchronized (this) {
9774            long ident = Binder.clearCallingIdentity();
9775            try {
9776                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9777                if (r == null) {
9778                    throw new IllegalArgumentException(
9779                            "exitFreeformMode: No activity record matching token=" + token);
9780                }
9781                final ActivityStack stack = r.getStackLocked(token);
9782                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9783                    throw new IllegalStateException(
9784                            "exitFreeformMode: You can only go fullscreen from freeform.");
9785                }
9786                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9787                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9788                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9789            } finally {
9790                Binder.restoreCallingIdentity(ident);
9791            }
9792        }
9793    }
9794
9795    @Override
9796    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9797        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9798        if (stackId == HOME_STACK_ID) {
9799            throw new IllegalArgumentException(
9800                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9801        }
9802        synchronized (this) {
9803            long ident = Binder.clearCallingIdentity();
9804            try {
9805                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9806                        + " to stackId=" + stackId + " toTop=" + toTop);
9807                if (stackId == DOCKED_STACK_ID) {
9808                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9809                            null /* initialBounds */);
9810                }
9811                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9812                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9813                if (result && stackId == DOCKED_STACK_ID) {
9814                    // If task moved to docked stack - show recents if needed.
9815                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9816                            "moveTaskToDockedStack");
9817                }
9818            } finally {
9819                Binder.restoreCallingIdentity(ident);
9820            }
9821        }
9822    }
9823
9824    @Override
9825    public void swapDockedAndFullscreenStack() throws RemoteException {
9826        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9827        synchronized (this) {
9828            long ident = Binder.clearCallingIdentity();
9829            try {
9830                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9831                        FULLSCREEN_WORKSPACE_STACK_ID);
9832                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9833                        : null;
9834                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9835                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9836                        : null;
9837                if (topTask == null || tasks == null || tasks.size() == 0) {
9838                    Slog.w(TAG,
9839                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9840                    return;
9841                }
9842
9843                // TODO: App transition
9844                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9845
9846                // Defer the resume so resume/pausing while moving stacks is dangerous.
9847                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9848                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9849                        ANIMATE, true /* deferResume */);
9850                final int size = tasks.size();
9851                for (int i = 0; i < size; i++) {
9852                    final int id = tasks.get(i).taskId;
9853                    if (id == topTask.taskId) {
9854                        continue;
9855                    }
9856                    mStackSupervisor.moveTaskToStackLocked(id,
9857                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9858                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9859                }
9860
9861                // Because we deferred the resume, to avoid conflicts with stack switches while
9862                // resuming, we need to do it after all the tasks are moved.
9863                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9864                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9865
9866                mWindowManager.executeAppTransition();
9867            } finally {
9868                Binder.restoreCallingIdentity(ident);
9869            }
9870        }
9871    }
9872
9873    /**
9874     * Moves the input task to the docked stack.
9875     *
9876     * @param taskId Id of task to move.
9877     * @param createMode The mode the docked stack should be created in if it doesn't exist
9878     *                   already. See
9879     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9880     *                   and
9881     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9882     * @param toTop If the task and stack should be moved to the top.
9883     * @param animate Whether we should play an animation for the moving the task
9884     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9885     *                      docked stack. Pass {@code null} to use default bounds.
9886     */
9887    @Override
9888    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9889            Rect initialBounds, boolean moveHomeStackFront) {
9890        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9891        synchronized (this) {
9892            long ident = Binder.clearCallingIdentity();
9893            try {
9894                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9895                        + " to createMode=" + createMode + " toTop=" + toTop);
9896                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9897                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9898                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9899                        animate, DEFER_RESUME);
9900                if (moved) {
9901                    if (moveHomeStackFront) {
9902                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9903                    }
9904                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9905                }
9906                return moved;
9907            } finally {
9908                Binder.restoreCallingIdentity(ident);
9909            }
9910        }
9911    }
9912
9913    /**
9914     * Moves the top activity in the input stackId to the pinned stack.
9915     *
9916     * @param stackId Id of stack to move the top activity to pinned stack.
9917     * @param bounds Bounds to use for pinned stack.
9918     *
9919     * @return True if the top activity of the input stack was successfully moved to the pinned
9920     *          stack.
9921     */
9922    @Override
9923    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9924        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9925        synchronized (this) {
9926            if (!mSupportsPictureInPicture) {
9927                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9928                        + "Device doesn't support picture-in-pciture mode");
9929            }
9930
9931            long ident = Binder.clearCallingIdentity();
9932            try {
9933                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9934            } finally {
9935                Binder.restoreCallingIdentity(ident);
9936            }
9937        }
9938    }
9939
9940    @Override
9941    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9942            boolean preserveWindows, boolean animate, int animationDuration) {
9943        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9944        long ident = Binder.clearCallingIdentity();
9945        try {
9946            synchronized (this) {
9947                if (animate) {
9948                    if (stackId == PINNED_STACK_ID) {
9949                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9950                    } else {
9951                        throw new IllegalArgumentException("Stack: " + stackId
9952                                + " doesn't support animated resize.");
9953                    }
9954                } else {
9955                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9956                            null /* tempTaskInsetBounds */, preserveWindows,
9957                            allowResizeInDockedMode, !DEFER_RESUME);
9958                }
9959            }
9960        } finally {
9961            Binder.restoreCallingIdentity(ident);
9962        }
9963    }
9964
9965    @Override
9966    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9967            Rect tempDockedTaskInsetBounds,
9968            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9970                "resizeDockedStack()");
9971        long ident = Binder.clearCallingIdentity();
9972        try {
9973            synchronized (this) {
9974                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9975                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9976                        PRESERVE_WINDOWS);
9977            }
9978        } finally {
9979            Binder.restoreCallingIdentity(ident);
9980        }
9981    }
9982
9983    @Override
9984    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9985        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9986                "resizePinnedStack()");
9987        final long ident = Binder.clearCallingIdentity();
9988        try {
9989            synchronized (this) {
9990                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9991            }
9992        } finally {
9993            Binder.restoreCallingIdentity(ident);
9994        }
9995    }
9996
9997    @Override
9998    public void positionTaskInStack(int taskId, int stackId, int position) {
9999        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10000        if (stackId == HOME_STACK_ID) {
10001            throw new IllegalArgumentException(
10002                    "positionTaskInStack: Attempt to change the position of task "
10003                    + taskId + " in/to home stack");
10004        }
10005        synchronized (this) {
10006            long ident = Binder.clearCallingIdentity();
10007            try {
10008                if (DEBUG_STACK) Slog.d(TAG_STACK,
10009                        "positionTaskInStack: positioning task=" + taskId
10010                        + " in stackId=" + stackId + " at position=" + position);
10011                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10012            } finally {
10013                Binder.restoreCallingIdentity(ident);
10014            }
10015        }
10016    }
10017
10018    @Override
10019    public List<StackInfo> getAllStackInfos() {
10020        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10021        long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                return mStackSupervisor.getAllStackInfosLocked();
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public StackInfo getStackInfo(int stackId) {
10033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10034        long ident = Binder.clearCallingIdentity();
10035        try {
10036            synchronized (this) {
10037                return mStackSupervisor.getStackInfoLocked(stackId);
10038            }
10039        } finally {
10040            Binder.restoreCallingIdentity(ident);
10041        }
10042    }
10043
10044    @Override
10045    public boolean isInHomeStack(int taskId) {
10046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10047        long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10051                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10052                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10053            }
10054        } finally {
10055            Binder.restoreCallingIdentity(ident);
10056        }
10057    }
10058
10059    @Override
10060    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10061        synchronized(this) {
10062            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10063        }
10064    }
10065
10066    @Override
10067    public void updateDeviceOwner(String packageName) {
10068        final int callingUid = Binder.getCallingUid();
10069        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10070            throw new SecurityException("updateDeviceOwner called from non-system process");
10071        }
10072        synchronized (this) {
10073            mDeviceOwnerName = packageName;
10074        }
10075    }
10076
10077    @Override
10078    public void updateLockTaskPackages(int userId, String[] packages) {
10079        final int callingUid = Binder.getCallingUid();
10080        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10081            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10082                    "updateLockTaskPackages()");
10083        }
10084        synchronized (this) {
10085            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10086                    Arrays.toString(packages));
10087            mLockTaskPackages.put(userId, packages);
10088            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10089        }
10090    }
10091
10092
10093    void startLockTaskModeLocked(TaskRecord task) {
10094        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10095        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10096            return;
10097        }
10098
10099        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10100        // is initiated by system after the pinning request was shown and locked mode is initiated
10101        // by an authorized app directly
10102        final int callingUid = Binder.getCallingUid();
10103        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10104        long ident = Binder.clearCallingIdentity();
10105        try {
10106            if (!isSystemInitiated) {
10107                task.mLockTaskUid = callingUid;
10108                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10109                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10110                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10111                    StatusBarManagerInternal statusBarManager =
10112                            LocalServices.getService(StatusBarManagerInternal.class);
10113                    if (statusBarManager != null) {
10114                        statusBarManager.showScreenPinningRequest(task.taskId);
10115                    }
10116                    return;
10117                }
10118
10119                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10120                if (stack == null || task != stack.topTask()) {
10121                    throw new IllegalArgumentException("Invalid task, not in foreground");
10122                }
10123            }
10124            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10125                    "Locking fully");
10126            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10127                    ActivityManager.LOCK_TASK_MODE_PINNED :
10128                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10129                    "startLockTask", true);
10130        } finally {
10131            Binder.restoreCallingIdentity(ident);
10132        }
10133    }
10134
10135    @Override
10136    public void startLockTaskMode(int taskId) {
10137        synchronized (this) {
10138            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10139            if (task != null) {
10140                startLockTaskModeLocked(task);
10141            }
10142        }
10143    }
10144
10145    @Override
10146    public void startLockTaskMode(IBinder token) {
10147        synchronized (this) {
10148            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10149            if (r == null) {
10150                return;
10151            }
10152            final TaskRecord task = r.task;
10153            if (task != null) {
10154                startLockTaskModeLocked(task);
10155            }
10156        }
10157    }
10158
10159    @Override
10160    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10162        // This makes inner call to look as if it was initiated by system.
10163        long ident = Binder.clearCallingIdentity();
10164        try {
10165            synchronized (this) {
10166                startLockTaskMode(taskId);
10167            }
10168        } finally {
10169            Binder.restoreCallingIdentity(ident);
10170        }
10171    }
10172
10173    @Override
10174    public void stopLockTaskMode() {
10175        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10176        if (lockTask == null) {
10177            // Our work here is done.
10178            return;
10179        }
10180
10181        final int callingUid = Binder.getCallingUid();
10182        final int lockTaskUid = lockTask.mLockTaskUid;
10183        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10184        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10185            // Done.
10186            return;
10187        } else {
10188            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10189            // It is possible lockTaskMode was started by the system process because
10190            // android:lockTaskMode is set to a locking value in the application manifest
10191            // instead of the app calling startLockTaskMode. In this case
10192            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10193            // {@link TaskRecord.effectiveUid} instead. Also caller with
10194            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10195            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10196                    && callingUid != lockTaskUid
10197                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10198                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10199                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10200            }
10201        }
10202        long ident = Binder.clearCallingIdentity();
10203        try {
10204            Log.d(TAG, "stopLockTaskMode");
10205            // Stop lock task
10206            synchronized (this) {
10207                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10208                        "stopLockTask", true);
10209            }
10210            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10211            if (tm != null) {
10212                tm.showInCallScreen(false);
10213            }
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    /**
10220     * This API should be called by SystemUI only when user perform certain action to dismiss
10221     * lock task mode. We should only dismiss pinned lock task mode in this case.
10222     */
10223    @Override
10224    public void stopSystemLockTaskMode() throws RemoteException {
10225        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10226            stopLockTaskMode();
10227        } else {
10228            mStackSupervisor.showLockTaskToast();
10229        }
10230    }
10231
10232    @Override
10233    public boolean isInLockTaskMode() {
10234        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10235    }
10236
10237    @Override
10238    public int getLockTaskModeState() {
10239        synchronized (this) {
10240            return mStackSupervisor.getLockTaskModeState();
10241        }
10242    }
10243
10244    @Override
10245    public void showLockTaskEscapeMessage(IBinder token) {
10246        synchronized (this) {
10247            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10248            if (r == null) {
10249                return;
10250            }
10251            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10252        }
10253    }
10254
10255    // =========================================================
10256    // CONTENT PROVIDERS
10257    // =========================================================
10258
10259    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10260        List<ProviderInfo> providers = null;
10261        try {
10262            providers = AppGlobals.getPackageManager()
10263                    .queryContentProviders(app.processName, app.uid,
10264                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10265                                    | MATCH_DEBUG_TRIAGED_MISSING)
10266                    .getList();
10267        } catch (RemoteException ex) {
10268        }
10269        if (DEBUG_MU) Slog.v(TAG_MU,
10270                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10271        int userId = app.userId;
10272        if (providers != null) {
10273            int N = providers.size();
10274            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10275            for (int i=0; i<N; i++) {
10276                // TODO: keep logic in sync with installEncryptionUnawareProviders
10277                ProviderInfo cpi =
10278                    (ProviderInfo)providers.get(i);
10279                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10280                        cpi.name, cpi.flags);
10281                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10282                    // This is a singleton provider, but a user besides the
10283                    // default user is asking to initialize a process it runs
10284                    // in...  well, no, it doesn't actually run in this process,
10285                    // it runs in the process of the default user.  Get rid of it.
10286                    providers.remove(i);
10287                    N--;
10288                    i--;
10289                    continue;
10290                }
10291
10292                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10293                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10294                if (cpr == null) {
10295                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10296                    mProviderMap.putProviderByClass(comp, cpr);
10297                }
10298                if (DEBUG_MU) Slog.v(TAG_MU,
10299                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10300                app.pubProviders.put(cpi.name, cpr);
10301                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10302                    // Don't add this if it is a platform component that is marked
10303                    // to run in multiple processes, because this is actually
10304                    // part of the framework so doesn't make sense to track as a
10305                    // separate apk in the process.
10306                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10307                            mProcessStats);
10308                }
10309                notifyPackageUse(cpi.applicationInfo.packageName,
10310                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10311            }
10312        }
10313        return providers;
10314    }
10315
10316    /**
10317     * Check if {@link ProcessRecord} has a possible chance at accessing the
10318     * given {@link ProviderInfo}. Final permission checking is always done
10319     * in {@link ContentProvider}.
10320     */
10321    private final String checkContentProviderPermissionLocked(
10322            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10323        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10324        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10325        boolean checkedGrants = false;
10326        if (checkUser) {
10327            // Looking for cross-user grants before enforcing the typical cross-users permissions
10328            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10329            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10330                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10331                    return null;
10332                }
10333                checkedGrants = true;
10334            }
10335            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10336                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10337            if (userId != tmpTargetUserId) {
10338                // When we actually went to determine the final targer user ID, this ended
10339                // up different than our initial check for the authority.  This is because
10340                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10341                // SELF.  So we need to re-check the grants again.
10342                checkedGrants = false;
10343            }
10344        }
10345        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10346                cpi.applicationInfo.uid, cpi.exported)
10347                == PackageManager.PERMISSION_GRANTED) {
10348            return null;
10349        }
10350        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10351                cpi.applicationInfo.uid, cpi.exported)
10352                == PackageManager.PERMISSION_GRANTED) {
10353            return null;
10354        }
10355
10356        PathPermission[] pps = cpi.pathPermissions;
10357        if (pps != null) {
10358            int i = pps.length;
10359            while (i > 0) {
10360                i--;
10361                PathPermission pp = pps[i];
10362                String pprperm = pp.getReadPermission();
10363                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10364                        cpi.applicationInfo.uid, cpi.exported)
10365                        == PackageManager.PERMISSION_GRANTED) {
10366                    return null;
10367                }
10368                String ppwperm = pp.getWritePermission();
10369                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10370                        cpi.applicationInfo.uid, cpi.exported)
10371                        == PackageManager.PERMISSION_GRANTED) {
10372                    return null;
10373                }
10374            }
10375        }
10376        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10377            return null;
10378        }
10379
10380        String msg;
10381        if (!cpi.exported) {
10382            msg = "Permission Denial: opening provider " + cpi.name
10383                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10384                    + ", uid=" + callingUid + ") that is not exported from uid "
10385                    + cpi.applicationInfo.uid;
10386        } else {
10387            msg = "Permission Denial: opening provider " + cpi.name
10388                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10389                    + ", uid=" + callingUid + ") requires "
10390                    + cpi.readPermission + " or " + cpi.writePermission;
10391        }
10392        Slog.w(TAG, msg);
10393        return msg;
10394    }
10395
10396    /**
10397     * Returns if the ContentProvider has granted a uri to callingUid
10398     */
10399    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10400        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10401        if (perms != null) {
10402            for (int i=perms.size()-1; i>=0; i--) {
10403                GrantUri grantUri = perms.keyAt(i);
10404                if (grantUri.sourceUserId == userId || !checkUser) {
10405                    if (matchesProvider(grantUri.uri, cpi)) {
10406                        return true;
10407                    }
10408                }
10409            }
10410        }
10411        return false;
10412    }
10413
10414    /**
10415     * Returns true if the uri authority is one of the authorities specified in the provider.
10416     */
10417    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10418        String uriAuth = uri.getAuthority();
10419        String cpiAuth = cpi.authority;
10420        if (cpiAuth.indexOf(';') == -1) {
10421            return cpiAuth.equals(uriAuth);
10422        }
10423        String[] cpiAuths = cpiAuth.split(";");
10424        int length = cpiAuths.length;
10425        for (int i = 0; i < length; i++) {
10426            if (cpiAuths[i].equals(uriAuth)) return true;
10427        }
10428        return false;
10429    }
10430
10431    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10432            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433        if (r != null) {
10434            for (int i=0; i<r.conProviders.size(); i++) {
10435                ContentProviderConnection conn = r.conProviders.get(i);
10436                if (conn.provider == cpr) {
10437                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10438                            "Adding provider requested by "
10439                            + r.processName + " from process "
10440                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10441                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10442                    if (stable) {
10443                        conn.stableCount++;
10444                        conn.numStableIncs++;
10445                    } else {
10446                        conn.unstableCount++;
10447                        conn.numUnstableIncs++;
10448                    }
10449                    return conn;
10450                }
10451            }
10452            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10453            if (stable) {
10454                conn.stableCount = 1;
10455                conn.numStableIncs = 1;
10456            } else {
10457                conn.unstableCount = 1;
10458                conn.numUnstableIncs = 1;
10459            }
10460            cpr.connections.add(conn);
10461            r.conProviders.add(conn);
10462            startAssociationLocked(r.uid, r.processName, r.curProcState,
10463                    cpr.uid, cpr.name, cpr.info.processName);
10464            return conn;
10465        }
10466        cpr.addExternalProcessHandleLocked(externalProcessToken);
10467        return null;
10468    }
10469
10470    boolean decProviderCountLocked(ContentProviderConnection conn,
10471            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10472        if (conn != null) {
10473            cpr = conn.provider;
10474            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10475                    "Removing provider requested by "
10476                    + conn.client.processName + " from process "
10477                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10478                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10479            if (stable) {
10480                conn.stableCount--;
10481            } else {
10482                conn.unstableCount--;
10483            }
10484            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10485                cpr.connections.remove(conn);
10486                conn.client.conProviders.remove(conn);
10487                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10488                    // The client is more important than last activity -- note the time this
10489                    // is happening, so we keep the old provider process around a bit as last
10490                    // activity to avoid thrashing it.
10491                    if (cpr.proc != null) {
10492                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10493                    }
10494                }
10495                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10496                return true;
10497            }
10498            return false;
10499        }
10500        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10501        return false;
10502    }
10503
10504    private void checkTime(long startTime, String where) {
10505        long now = SystemClock.uptimeMillis();
10506        if ((now-startTime) > 50) {
10507            // If we are taking more than 50ms, log about it.
10508            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10509        }
10510    }
10511
10512    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10513            String name, IBinder token, boolean stable, int userId) {
10514        ContentProviderRecord cpr;
10515        ContentProviderConnection conn = null;
10516        ProviderInfo cpi = null;
10517
10518        synchronized(this) {
10519            long startTime = SystemClock.uptimeMillis();
10520
10521            ProcessRecord r = null;
10522            if (caller != null) {
10523                r = getRecordForAppLocked(caller);
10524                if (r == null) {
10525                    throw new SecurityException(
10526                            "Unable to find app for caller " + caller
10527                          + " (pid=" + Binder.getCallingPid()
10528                          + ") when getting content provider " + name);
10529                }
10530            }
10531
10532            boolean checkCrossUser = true;
10533
10534            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10535
10536            // First check if this content provider has been published...
10537            cpr = mProviderMap.getProviderByName(name, userId);
10538            // If that didn't work, check if it exists for user 0 and then
10539            // verify that it's a singleton provider before using it.
10540            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10541                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10542                if (cpr != null) {
10543                    cpi = cpr.info;
10544                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10545                            cpi.name, cpi.flags)
10546                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10547                        userId = UserHandle.USER_SYSTEM;
10548                        checkCrossUser = false;
10549                    } else {
10550                        cpr = null;
10551                        cpi = null;
10552                    }
10553                }
10554            }
10555
10556            boolean providerRunning = cpr != null;
10557            if (providerRunning) {
10558                cpi = cpr.info;
10559                String msg;
10560                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10561                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10562                        != null) {
10563                    throw new SecurityException(msg);
10564                }
10565                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10566
10567                if (r != null && cpr.canRunHere(r)) {
10568                    // This provider has been published or is in the process
10569                    // of being published...  but it is also allowed to run
10570                    // in the caller's process, so don't make a connection
10571                    // and just let the caller instantiate its own instance.
10572                    ContentProviderHolder holder = cpr.newHolder(null);
10573                    // don't give caller the provider object, it needs
10574                    // to make its own.
10575                    holder.provider = null;
10576                    return holder;
10577                }
10578
10579                final long origId = Binder.clearCallingIdentity();
10580
10581                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10582
10583                // In this case the provider instance already exists, so we can
10584                // return it right away.
10585                conn = incProviderCountLocked(r, cpr, token, stable);
10586                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10587                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10588                        // If this is a perceptible app accessing the provider,
10589                        // make sure to count it as being accessed and thus
10590                        // back up on the LRU list.  This is good because
10591                        // content providers are often expensive to start.
10592                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10593                        updateLruProcessLocked(cpr.proc, false, null);
10594                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10595                    }
10596                }
10597
10598                if (cpr.proc != null) {
10599                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10600                    boolean success = updateOomAdjLocked(cpr.proc);
10601                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10602                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10603                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10604                    // NOTE: there is still a race here where a signal could be
10605                    // pending on the process even though we managed to update its
10606                    // adj level.  Not sure what to do about this, but at least
10607                    // the race is now smaller.
10608                    if (!success) {
10609                        // Uh oh...  it looks like the provider's process
10610                        // has been killed on us.  We need to wait for a new
10611                        // process to be started, and make sure its death
10612                        // doesn't kill our process.
10613                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10614                                + " is crashing; detaching " + r);
10615                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10616                        checkTime(startTime, "getContentProviderImpl: before appDied");
10617                        appDiedLocked(cpr.proc);
10618                        checkTime(startTime, "getContentProviderImpl: after appDied");
10619                        if (!lastRef) {
10620                            // This wasn't the last ref our process had on
10621                            // the provider...  we have now been killed, bail.
10622                            return null;
10623                        }
10624                        providerRunning = false;
10625                        conn = null;
10626                    }
10627                }
10628
10629                Binder.restoreCallingIdentity(origId);
10630            }
10631
10632            if (!providerRunning) {
10633                try {
10634                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10635                    cpi = AppGlobals.getPackageManager().
10636                        resolveContentProvider(name,
10637                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10638                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10639                } catch (RemoteException ex) {
10640                }
10641                if (cpi == null) {
10642                    return null;
10643                }
10644                // If the provider is a singleton AND
10645                // (it's a call within the same user || the provider is a
10646                // privileged app)
10647                // Then allow connecting to the singleton provider
10648                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10649                        cpi.name, cpi.flags)
10650                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10651                if (singleton) {
10652                    userId = UserHandle.USER_SYSTEM;
10653                }
10654                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10655                checkTime(startTime, "getContentProviderImpl: got app info for user");
10656
10657                String msg;
10658                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10659                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10660                        != null) {
10661                    throw new SecurityException(msg);
10662                }
10663                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10664
10665                if (!mProcessesReady
10666                        && !cpi.processName.equals("system")) {
10667                    // If this content provider does not run in the system
10668                    // process, and the system is not yet ready to run other
10669                    // processes, then fail fast instead of hanging.
10670                    throw new IllegalArgumentException(
10671                            "Attempt to launch content provider before system ready");
10672                }
10673
10674                // Make sure that the user who owns this provider is running.  If not,
10675                // we don't want to allow it to run.
10676                if (!mUserController.isUserRunningLocked(userId, 0)) {
10677                    Slog.w(TAG, "Unable to launch app "
10678                            + cpi.applicationInfo.packageName + "/"
10679                            + cpi.applicationInfo.uid + " for provider "
10680                            + name + ": user " + userId + " is stopped");
10681                    return null;
10682                }
10683
10684                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10685                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10686                cpr = mProviderMap.getProviderByClass(comp, userId);
10687                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10688                final boolean firstClass = cpr == null;
10689                if (firstClass) {
10690                    final long ident = Binder.clearCallingIdentity();
10691
10692                    // If permissions need a review before any of the app components can run,
10693                    // we return no provider and launch a review activity if the calling app
10694                    // is in the foreground.
10695                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10696                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10697                            return null;
10698                        }
10699                    }
10700
10701                    try {
10702                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10703                        ApplicationInfo ai =
10704                            AppGlobals.getPackageManager().
10705                                getApplicationInfo(
10706                                        cpi.applicationInfo.packageName,
10707                                        STOCK_PM_FLAGS, userId);
10708                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10709                        if (ai == null) {
10710                            Slog.w(TAG, "No package info for content provider "
10711                                    + cpi.name);
10712                            return null;
10713                        }
10714                        ai = getAppInfoForUser(ai, userId);
10715                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10716                    } catch (RemoteException ex) {
10717                        // pm is in same process, this will never happen.
10718                    } finally {
10719                        Binder.restoreCallingIdentity(ident);
10720                    }
10721                }
10722
10723                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10724
10725                if (r != null && cpr.canRunHere(r)) {
10726                    // If this is a multiprocess provider, then just return its
10727                    // info and allow the caller to instantiate it.  Only do
10728                    // this if the provider is the same user as the caller's
10729                    // process, or can run as root (so can be in any process).
10730                    return cpr.newHolder(null);
10731                }
10732
10733                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10734                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10735                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10736
10737                // This is single process, and our app is now connecting to it.
10738                // See if we are already in the process of launching this
10739                // provider.
10740                final int N = mLaunchingProviders.size();
10741                int i;
10742                for (i = 0; i < N; i++) {
10743                    if (mLaunchingProviders.get(i) == cpr) {
10744                        break;
10745                    }
10746                }
10747
10748                // If the provider is not already being launched, then get it
10749                // started.
10750                if (i >= N) {
10751                    final long origId = Binder.clearCallingIdentity();
10752
10753                    try {
10754                        // Content provider is now in use, its package can't be stopped.
10755                        try {
10756                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10757                            AppGlobals.getPackageManager().setPackageStoppedState(
10758                                    cpr.appInfo.packageName, false, userId);
10759                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10760                        } catch (RemoteException e) {
10761                        } catch (IllegalArgumentException e) {
10762                            Slog.w(TAG, "Failed trying to unstop package "
10763                                    + cpr.appInfo.packageName + ": " + e);
10764                        }
10765
10766                        // Use existing process if already started
10767                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10768                        ProcessRecord proc = getProcessRecordLocked(
10769                                cpi.processName, cpr.appInfo.uid, false);
10770                        if (proc != null && proc.thread != null) {
10771                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10772                                    "Installing in existing process " + proc);
10773                            if (!proc.pubProviders.containsKey(cpi.name)) {
10774                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10775                                proc.pubProviders.put(cpi.name, cpr);
10776                                try {
10777                                    proc.thread.scheduleInstallProvider(cpi);
10778                                } catch (RemoteException e) {
10779                                }
10780                            }
10781                        } else {
10782                            checkTime(startTime, "getContentProviderImpl: before start process");
10783                            proc = startProcessLocked(cpi.processName,
10784                                    cpr.appInfo, false, 0, "content provider",
10785                                    new ComponentName(cpi.applicationInfo.packageName,
10786                                            cpi.name), false, false, false);
10787                            checkTime(startTime, "getContentProviderImpl: after start process");
10788                            if (proc == null) {
10789                                Slog.w(TAG, "Unable to launch app "
10790                                        + cpi.applicationInfo.packageName + "/"
10791                                        + cpi.applicationInfo.uid + " for provider "
10792                                        + name + ": process is bad");
10793                                return null;
10794                            }
10795                        }
10796                        cpr.launchingApp = proc;
10797                        mLaunchingProviders.add(cpr);
10798                    } finally {
10799                        Binder.restoreCallingIdentity(origId);
10800                    }
10801                }
10802
10803                checkTime(startTime, "getContentProviderImpl: updating data structures");
10804
10805                // Make sure the provider is published (the same provider class
10806                // may be published under multiple names).
10807                if (firstClass) {
10808                    mProviderMap.putProviderByClass(comp, cpr);
10809                }
10810
10811                mProviderMap.putProviderByName(name, cpr);
10812                conn = incProviderCountLocked(r, cpr, token, stable);
10813                if (conn != null) {
10814                    conn.waiting = true;
10815                }
10816            }
10817            checkTime(startTime, "getContentProviderImpl: done!");
10818        }
10819
10820        // Wait for the provider to be published...
10821        synchronized (cpr) {
10822            while (cpr.provider == null) {
10823                if (cpr.launchingApp == null) {
10824                    Slog.w(TAG, "Unable to launch app "
10825                            + cpi.applicationInfo.packageName + "/"
10826                            + cpi.applicationInfo.uid + " for provider "
10827                            + name + ": launching app became null");
10828                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10829                            UserHandle.getUserId(cpi.applicationInfo.uid),
10830                            cpi.applicationInfo.packageName,
10831                            cpi.applicationInfo.uid, name);
10832                    return null;
10833                }
10834                try {
10835                    if (DEBUG_MU) Slog.v(TAG_MU,
10836                            "Waiting to start provider " + cpr
10837                            + " launchingApp=" + cpr.launchingApp);
10838                    if (conn != null) {
10839                        conn.waiting = true;
10840                    }
10841                    cpr.wait();
10842                } catch (InterruptedException ex) {
10843                } finally {
10844                    if (conn != null) {
10845                        conn.waiting = false;
10846                    }
10847                }
10848            }
10849        }
10850        return cpr != null ? cpr.newHolder(conn) : null;
10851    }
10852
10853    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10854            ProcessRecord r, final int userId) {
10855        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10856                cpi.packageName, userId)) {
10857
10858            final boolean callerForeground = r == null || r.setSchedGroup
10859                    != ProcessList.SCHED_GROUP_BACKGROUND;
10860
10861            // Show a permission review UI only for starting from a foreground app
10862            if (!callerForeground) {
10863                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10864                        + cpi.packageName + " requires a permissions review");
10865                return false;
10866            }
10867
10868            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10869            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10870                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10871            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10872
10873            if (DEBUG_PERMISSIONS_REVIEW) {
10874                Slog.i(TAG, "u" + userId + " Launching permission review "
10875                        + "for package " + cpi.packageName);
10876            }
10877
10878            final UserHandle userHandle = new UserHandle(userId);
10879            mHandler.post(new Runnable() {
10880                @Override
10881                public void run() {
10882                    mContext.startActivityAsUser(intent, userHandle);
10883                }
10884            });
10885
10886            return false;
10887        }
10888
10889        return true;
10890    }
10891
10892    PackageManagerInternal getPackageManagerInternalLocked() {
10893        if (mPackageManagerInt == null) {
10894            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10895        }
10896        return mPackageManagerInt;
10897    }
10898
10899    @Override
10900    public final ContentProviderHolder getContentProvider(
10901            IApplicationThread caller, String name, int userId, boolean stable) {
10902        enforceNotIsolatedCaller("getContentProvider");
10903        if (caller == null) {
10904            String msg = "null IApplicationThread when getting content provider "
10905                    + name;
10906            Slog.w(TAG, msg);
10907            throw new SecurityException(msg);
10908        }
10909        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10910        // with cross-user grant.
10911        return getContentProviderImpl(caller, name, null, stable, userId);
10912    }
10913
10914    public ContentProviderHolder getContentProviderExternal(
10915            String name, int userId, IBinder token) {
10916        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10917            "Do not have permission in call getContentProviderExternal()");
10918        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10919                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10920        return getContentProviderExternalUnchecked(name, token, userId);
10921    }
10922
10923    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10924            IBinder token, int userId) {
10925        return getContentProviderImpl(null, name, token, true, userId);
10926    }
10927
10928    /**
10929     * Drop a content provider from a ProcessRecord's bookkeeping
10930     */
10931    public void removeContentProvider(IBinder connection, boolean stable) {
10932        enforceNotIsolatedCaller("removeContentProvider");
10933        long ident = Binder.clearCallingIdentity();
10934        try {
10935            synchronized (this) {
10936                ContentProviderConnection conn;
10937                try {
10938                    conn = (ContentProviderConnection)connection;
10939                } catch (ClassCastException e) {
10940                    String msg ="removeContentProvider: " + connection
10941                            + " not a ContentProviderConnection";
10942                    Slog.w(TAG, msg);
10943                    throw new IllegalArgumentException(msg);
10944                }
10945                if (conn == null) {
10946                    throw new NullPointerException("connection is null");
10947                }
10948                if (decProviderCountLocked(conn, null, null, stable)) {
10949                    updateOomAdjLocked();
10950                }
10951            }
10952        } finally {
10953            Binder.restoreCallingIdentity(ident);
10954        }
10955    }
10956
10957    public void removeContentProviderExternal(String name, IBinder token) {
10958        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10959            "Do not have permission in call removeContentProviderExternal()");
10960        int userId = UserHandle.getCallingUserId();
10961        long ident = Binder.clearCallingIdentity();
10962        try {
10963            removeContentProviderExternalUnchecked(name, token, userId);
10964        } finally {
10965            Binder.restoreCallingIdentity(ident);
10966        }
10967    }
10968
10969    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10970        synchronized (this) {
10971            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10972            if(cpr == null) {
10973                //remove from mProvidersByClass
10974                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10975                return;
10976            }
10977
10978            //update content provider record entry info
10979            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10980            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10981            if (localCpr.hasExternalProcessHandles()) {
10982                if (localCpr.removeExternalProcessHandleLocked(token)) {
10983                    updateOomAdjLocked();
10984                } else {
10985                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10986                            + " with no external reference for token: "
10987                            + token + ".");
10988                }
10989            } else {
10990                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10991                        + " with no external references.");
10992            }
10993        }
10994    }
10995
10996    public final void publishContentProviders(IApplicationThread caller,
10997            List<ContentProviderHolder> providers) {
10998        if (providers == null) {
10999            return;
11000        }
11001
11002        enforceNotIsolatedCaller("publishContentProviders");
11003        synchronized (this) {
11004            final ProcessRecord r = getRecordForAppLocked(caller);
11005            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11006            if (r == null) {
11007                throw new SecurityException(
11008                        "Unable to find app for caller " + caller
11009                      + " (pid=" + Binder.getCallingPid()
11010                      + ") when publishing content providers");
11011            }
11012
11013            final long origId = Binder.clearCallingIdentity();
11014
11015            final int N = providers.size();
11016            for (int i = 0; i < N; i++) {
11017                ContentProviderHolder src = providers.get(i);
11018                if (src == null || src.info == null || src.provider == null) {
11019                    continue;
11020                }
11021                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11022                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11023                if (dst != null) {
11024                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11025                    mProviderMap.putProviderByClass(comp, dst);
11026                    String names[] = dst.info.authority.split(";");
11027                    for (int j = 0; j < names.length; j++) {
11028                        mProviderMap.putProviderByName(names[j], dst);
11029                    }
11030
11031                    int launchingCount = mLaunchingProviders.size();
11032                    int j;
11033                    boolean wasInLaunchingProviders = false;
11034                    for (j = 0; j < launchingCount; j++) {
11035                        if (mLaunchingProviders.get(j) == dst) {
11036                            mLaunchingProviders.remove(j);
11037                            wasInLaunchingProviders = true;
11038                            j--;
11039                            launchingCount--;
11040                        }
11041                    }
11042                    if (wasInLaunchingProviders) {
11043                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11044                    }
11045                    synchronized (dst) {
11046                        dst.provider = src.provider;
11047                        dst.proc = r;
11048                        dst.notifyAll();
11049                    }
11050                    updateOomAdjLocked(r);
11051                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11052                            src.info.authority);
11053                }
11054            }
11055
11056            Binder.restoreCallingIdentity(origId);
11057        }
11058    }
11059
11060    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11061        ContentProviderConnection conn;
11062        try {
11063            conn = (ContentProviderConnection)connection;
11064        } catch (ClassCastException e) {
11065            String msg ="refContentProvider: " + connection
11066                    + " not a ContentProviderConnection";
11067            Slog.w(TAG, msg);
11068            throw new IllegalArgumentException(msg);
11069        }
11070        if (conn == null) {
11071            throw new NullPointerException("connection is null");
11072        }
11073
11074        synchronized (this) {
11075            if (stable > 0) {
11076                conn.numStableIncs += stable;
11077            }
11078            stable = conn.stableCount + stable;
11079            if (stable < 0) {
11080                throw new IllegalStateException("stableCount < 0: " + stable);
11081            }
11082
11083            if (unstable > 0) {
11084                conn.numUnstableIncs += unstable;
11085            }
11086            unstable = conn.unstableCount + unstable;
11087            if (unstable < 0) {
11088                throw new IllegalStateException("unstableCount < 0: " + unstable);
11089            }
11090
11091            if ((stable+unstable) <= 0) {
11092                throw new IllegalStateException("ref counts can't go to zero here: stable="
11093                        + stable + " unstable=" + unstable);
11094            }
11095            conn.stableCount = stable;
11096            conn.unstableCount = unstable;
11097            return !conn.dead;
11098        }
11099    }
11100
11101    public void unstableProviderDied(IBinder connection) {
11102        ContentProviderConnection conn;
11103        try {
11104            conn = (ContentProviderConnection)connection;
11105        } catch (ClassCastException e) {
11106            String msg ="refContentProvider: " + connection
11107                    + " not a ContentProviderConnection";
11108            Slog.w(TAG, msg);
11109            throw new IllegalArgumentException(msg);
11110        }
11111        if (conn == null) {
11112            throw new NullPointerException("connection is null");
11113        }
11114
11115        // Safely retrieve the content provider associated with the connection.
11116        IContentProvider provider;
11117        synchronized (this) {
11118            provider = conn.provider.provider;
11119        }
11120
11121        if (provider == null) {
11122            // Um, yeah, we're way ahead of you.
11123            return;
11124        }
11125
11126        // Make sure the caller is being honest with us.
11127        if (provider.asBinder().pingBinder()) {
11128            // Er, no, still looks good to us.
11129            synchronized (this) {
11130                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11131                        + " says " + conn + " died, but we don't agree");
11132                return;
11133            }
11134        }
11135
11136        // Well look at that!  It's dead!
11137        synchronized (this) {
11138            if (conn.provider.provider != provider) {
11139                // But something changed...  good enough.
11140                return;
11141            }
11142
11143            ProcessRecord proc = conn.provider.proc;
11144            if (proc == null || proc.thread == null) {
11145                // Seems like the process is already cleaned up.
11146                return;
11147            }
11148
11149            // As far as we're concerned, this is just like receiving a
11150            // death notification...  just a bit prematurely.
11151            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11152                    + ") early provider death");
11153            final long ident = Binder.clearCallingIdentity();
11154            try {
11155                appDiedLocked(proc);
11156            } finally {
11157                Binder.restoreCallingIdentity(ident);
11158            }
11159        }
11160    }
11161
11162    @Override
11163    public void appNotRespondingViaProvider(IBinder connection) {
11164        enforceCallingPermission(
11165                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11166
11167        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11168        if (conn == null) {
11169            Slog.w(TAG, "ContentProviderConnection is null");
11170            return;
11171        }
11172
11173        final ProcessRecord host = conn.provider.proc;
11174        if (host == null) {
11175            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11176            return;
11177        }
11178
11179        mHandler.post(new Runnable() {
11180            @Override
11181            public void run() {
11182                mAppErrors.appNotResponding(host, null, null, false,
11183                        "ContentProvider not responding");
11184            }
11185        });
11186    }
11187
11188    public final void installSystemProviders() {
11189        List<ProviderInfo> providers;
11190        synchronized (this) {
11191            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11192            providers = generateApplicationProvidersLocked(app);
11193            if (providers != null) {
11194                for (int i=providers.size()-1; i>=0; i--) {
11195                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11196                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11197                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11198                                + ": not system .apk");
11199                        providers.remove(i);
11200                    }
11201                }
11202            }
11203        }
11204        if (providers != null) {
11205            mSystemThread.installSystemProviders(providers);
11206        }
11207
11208        mCoreSettingsObserver = new CoreSettingsObserver(this);
11209        mFontScaleSettingObserver = new FontScaleSettingObserver();
11210
11211        //mUsageStatsService.monitorPackages();
11212    }
11213
11214    private void startPersistentApps(int matchFlags) {
11215        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11216
11217        synchronized (this) {
11218            try {
11219                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11220                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11221                for (ApplicationInfo app : apps) {
11222                    if (!"android".equals(app.packageName)) {
11223                        addAppLocked(app, false, null /* ABI override */);
11224                    }
11225                }
11226            } catch (RemoteException ex) {
11227            }
11228        }
11229    }
11230
11231    /**
11232     * When a user is unlocked, we need to install encryption-unaware providers
11233     * belonging to any running apps.
11234     */
11235    private void installEncryptionUnawareProviders(int userId) {
11236        // We're only interested in providers that are encryption unaware, and
11237        // we don't care about uninstalled apps, since there's no way they're
11238        // running at this point.
11239        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11240
11241        synchronized (this) {
11242            final int NP = mProcessNames.getMap().size();
11243            for (int ip = 0; ip < NP; ip++) {
11244                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11245                final int NA = apps.size();
11246                for (int ia = 0; ia < NA; ia++) {
11247                    final ProcessRecord app = apps.valueAt(ia);
11248                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11249
11250                    final int NG = app.pkgList.size();
11251                    for (int ig = 0; ig < NG; ig++) {
11252                        try {
11253                            final String pkgName = app.pkgList.keyAt(ig);
11254                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11255                                    .getPackageInfo(pkgName, matchFlags, userId);
11256                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11257                                for (ProviderInfo pi : pkgInfo.providers) {
11258                                    // TODO: keep in sync with generateApplicationProvidersLocked
11259                                    final boolean processMatch = Objects.equals(pi.processName,
11260                                            app.processName) || pi.multiprocess;
11261                                    final boolean userMatch = isSingleton(pi.processName,
11262                                            pi.applicationInfo, pi.name, pi.flags)
11263                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11264                                    if (processMatch && userMatch) {
11265                                        Log.v(TAG, "Installing " + pi);
11266                                        app.thread.scheduleInstallProvider(pi);
11267                                    } else {
11268                                        Log.v(TAG, "Skipping " + pi);
11269                                    }
11270                                }
11271                            }
11272                        } catch (RemoteException ignored) {
11273                        }
11274                    }
11275                }
11276            }
11277        }
11278    }
11279
11280    /**
11281     * Allows apps to retrieve the MIME type of a URI.
11282     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11283     * users, then it does not need permission to access the ContentProvider.
11284     * Either, it needs cross-user uri grants.
11285     *
11286     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11287     *
11288     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11289     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11290     */
11291    public String getProviderMimeType(Uri uri, int userId) {
11292        enforceNotIsolatedCaller("getProviderMimeType");
11293        final String name = uri.getAuthority();
11294        int callingUid = Binder.getCallingUid();
11295        int callingPid = Binder.getCallingPid();
11296        long ident = 0;
11297        boolean clearedIdentity = false;
11298        synchronized (this) {
11299            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11300        }
11301        if (canClearIdentity(callingPid, callingUid, userId)) {
11302            clearedIdentity = true;
11303            ident = Binder.clearCallingIdentity();
11304        }
11305        ContentProviderHolder holder = null;
11306        try {
11307            holder = getContentProviderExternalUnchecked(name, null, userId);
11308            if (holder != null) {
11309                return holder.provider.getType(uri);
11310            }
11311        } catch (RemoteException e) {
11312            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11313            return null;
11314        } catch (Exception e) {
11315            Log.w(TAG, "Exception while determining type of " + uri, e);
11316            return null;
11317        } finally {
11318            // We need to clear the identity to call removeContentProviderExternalUnchecked
11319            if (!clearedIdentity) {
11320                ident = Binder.clearCallingIdentity();
11321            }
11322            try {
11323                if (holder != null) {
11324                    removeContentProviderExternalUnchecked(name, null, userId);
11325                }
11326            } finally {
11327                Binder.restoreCallingIdentity(ident);
11328            }
11329        }
11330
11331        return null;
11332    }
11333
11334    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11335        if (UserHandle.getUserId(callingUid) == userId) {
11336            return true;
11337        }
11338        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11339                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11340                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11341                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11342                return true;
11343        }
11344        return false;
11345    }
11346
11347    // =========================================================
11348    // GLOBAL MANAGEMENT
11349    // =========================================================
11350
11351    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11352            boolean isolated, int isolatedUid) {
11353        String proc = customProcess != null ? customProcess : info.processName;
11354        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11355        final int userId = UserHandle.getUserId(info.uid);
11356        int uid = info.uid;
11357        if (isolated) {
11358            if (isolatedUid == 0) {
11359                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11360                while (true) {
11361                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11362                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11363                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11364                    }
11365                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11366                    mNextIsolatedProcessUid++;
11367                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11368                        // No process for this uid, use it.
11369                        break;
11370                    }
11371                    stepsLeft--;
11372                    if (stepsLeft <= 0) {
11373                        return null;
11374                    }
11375                }
11376            } else {
11377                // Special case for startIsolatedProcess (internal only), where
11378                // the uid of the isolated process is specified by the caller.
11379                uid = isolatedUid;
11380            }
11381        }
11382        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11383        if (!mBooted && !mBooting
11384                && userId == UserHandle.USER_SYSTEM
11385                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11386            r.persistent = true;
11387        }
11388        addProcessNameLocked(r);
11389        return r;
11390    }
11391
11392    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11393            String abiOverride) {
11394        ProcessRecord app;
11395        if (!isolated) {
11396            app = getProcessRecordLocked(info.processName, info.uid, true);
11397        } else {
11398            app = null;
11399        }
11400
11401        if (app == null) {
11402            app = newProcessRecordLocked(info, null, isolated, 0);
11403            updateLruProcessLocked(app, false, null);
11404            updateOomAdjLocked();
11405        }
11406
11407        // This package really, really can not be stopped.
11408        try {
11409            AppGlobals.getPackageManager().setPackageStoppedState(
11410                    info.packageName, false, UserHandle.getUserId(app.uid));
11411        } catch (RemoteException e) {
11412        } catch (IllegalArgumentException e) {
11413            Slog.w(TAG, "Failed trying to unstop package "
11414                    + info.packageName + ": " + e);
11415        }
11416
11417        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11418            app.persistent = true;
11419            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11420        }
11421        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11422            mPersistentStartingProcesses.add(app);
11423            startProcessLocked(app, "added application", app.processName, abiOverride,
11424                    null /* entryPoint */, null /* entryPointArgs */);
11425        }
11426
11427        return app;
11428    }
11429
11430    public void unhandledBack() {
11431        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11432                "unhandledBack()");
11433
11434        synchronized(this) {
11435            final long origId = Binder.clearCallingIdentity();
11436            try {
11437                getFocusedStack().unhandledBackLocked();
11438            } finally {
11439                Binder.restoreCallingIdentity(origId);
11440            }
11441        }
11442    }
11443
11444    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11445        enforceNotIsolatedCaller("openContentUri");
11446        final int userId = UserHandle.getCallingUserId();
11447        String name = uri.getAuthority();
11448        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11449        ParcelFileDescriptor pfd = null;
11450        if (cph != null) {
11451            // We record the binder invoker's uid in thread-local storage before
11452            // going to the content provider to open the file.  Later, in the code
11453            // that handles all permissions checks, we look for this uid and use
11454            // that rather than the Activity Manager's own uid.  The effect is that
11455            // we do the check against the caller's permissions even though it looks
11456            // to the content provider like the Activity Manager itself is making
11457            // the request.
11458            Binder token = new Binder();
11459            sCallerIdentity.set(new Identity(
11460                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11461            try {
11462                pfd = cph.provider.openFile(null, uri, "r", null, token);
11463            } catch (FileNotFoundException e) {
11464                // do nothing; pfd will be returned null
11465            } finally {
11466                // Ensure that whatever happens, we clean up the identity state
11467                sCallerIdentity.remove();
11468                // Ensure we're done with the provider.
11469                removeContentProviderExternalUnchecked(name, null, userId);
11470            }
11471        } else {
11472            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11473        }
11474        return pfd;
11475    }
11476
11477    // Actually is sleeping or shutting down or whatever else in the future
11478    // is an inactive state.
11479    public boolean isSleepingOrShuttingDown() {
11480        return isSleeping() || mShuttingDown;
11481    }
11482
11483    public boolean isSleeping() {
11484        return mSleeping;
11485    }
11486
11487    void onWakefulnessChanged(int wakefulness) {
11488        synchronized(this) {
11489            mWakefulness = wakefulness;
11490            updateSleepIfNeededLocked();
11491        }
11492    }
11493
11494    void finishRunningVoiceLocked() {
11495        if (mRunningVoice != null) {
11496            mRunningVoice = null;
11497            mVoiceWakeLock.release();
11498            updateSleepIfNeededLocked();
11499        }
11500    }
11501
11502    void startTimeTrackingFocusedActivityLocked() {
11503        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11504            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11505        }
11506    }
11507
11508    void updateSleepIfNeededLocked() {
11509        if (mSleeping && !shouldSleepLocked()) {
11510            mSleeping = false;
11511            startTimeTrackingFocusedActivityLocked();
11512            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11513            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11514            updateOomAdjLocked();
11515        } else if (!mSleeping && shouldSleepLocked()) {
11516            mSleeping = true;
11517            if (mCurAppTimeTracker != null) {
11518                mCurAppTimeTracker.stop();
11519            }
11520            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11521            mStackSupervisor.goingToSleepLocked();
11522            updateOomAdjLocked();
11523
11524            // Initialize the wake times of all processes.
11525            checkExcessivePowerUsageLocked(false);
11526            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11527            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11528            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11529        }
11530    }
11531
11532    private boolean shouldSleepLocked() {
11533        // Resume applications while running a voice interactor.
11534        if (mRunningVoice != null) {
11535            return false;
11536        }
11537
11538        // TODO: Transform the lock screen state into a sleep token instead.
11539        switch (mWakefulness) {
11540            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11541            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11542            case PowerManagerInternal.WAKEFULNESS_DOZING:
11543                // Pause applications whenever the lock screen is shown or any sleep
11544                // tokens have been acquired.
11545                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11546            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11547            default:
11548                // If we're asleep then pause applications unconditionally.
11549                return true;
11550        }
11551    }
11552
11553    /** Pokes the task persister. */
11554    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11555        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11556    }
11557
11558    /** Notifies all listeners when the task stack has changed. */
11559    void notifyTaskStackChangedLocked() {
11560        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11561        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11562        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11563        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11564    }
11565
11566    /** Notifies all listeners when an Activity is pinned. */
11567    void notifyActivityPinnedLocked() {
11568        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11569        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11570    }
11571
11572    /**
11573     * Notifies all listeners when an attempt was made to start an an activity that is already
11574     * running in the pinned stack and the activity was not actually started, but the task is
11575     * either brought to the front or a new Intent is delivered to it.
11576     */
11577    void notifyPinnedActivityRestartAttemptLocked() {
11578        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11579        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11580    }
11581
11582    /** Notifies all listeners when the pinned stack animation ends. */
11583    @Override
11584    public void notifyPinnedStackAnimationEnded() {
11585        synchronized (this) {
11586            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11587            mHandler.obtainMessage(
11588                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11589        }
11590    }
11591
11592    @Override
11593    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11594        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11595    }
11596
11597    @Override
11598    public boolean shutdown(int timeout) {
11599        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11600                != PackageManager.PERMISSION_GRANTED) {
11601            throw new SecurityException("Requires permission "
11602                    + android.Manifest.permission.SHUTDOWN);
11603        }
11604
11605        boolean timedout = false;
11606
11607        synchronized(this) {
11608            mShuttingDown = true;
11609            updateEventDispatchingLocked();
11610            timedout = mStackSupervisor.shutdownLocked(timeout);
11611        }
11612
11613        mAppOpsService.shutdown();
11614        if (mUsageStatsService != null) {
11615            mUsageStatsService.prepareShutdown();
11616        }
11617        mBatteryStatsService.shutdown();
11618        synchronized (this) {
11619            mProcessStats.shutdownLocked();
11620            notifyTaskPersisterLocked(null, true);
11621        }
11622
11623        return timedout;
11624    }
11625
11626    public final void activitySlept(IBinder token) {
11627        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11628
11629        final long origId = Binder.clearCallingIdentity();
11630
11631        synchronized (this) {
11632            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11633            if (r != null) {
11634                mStackSupervisor.activitySleptLocked(r);
11635            }
11636        }
11637
11638        Binder.restoreCallingIdentity(origId);
11639    }
11640
11641    private String lockScreenShownToString() {
11642        switch (mLockScreenShown) {
11643            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11644            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11645            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11646            default: return "Unknown=" + mLockScreenShown;
11647        }
11648    }
11649
11650    void logLockScreen(String msg) {
11651        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11652                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11653                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11654                + " mSleeping=" + mSleeping);
11655    }
11656
11657    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11658        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11659        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11660        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11661            boolean wasRunningVoice = mRunningVoice != null;
11662            mRunningVoice = session;
11663            if (!wasRunningVoice) {
11664                mVoiceWakeLock.acquire();
11665                updateSleepIfNeededLocked();
11666            }
11667        }
11668    }
11669
11670    private void updateEventDispatchingLocked() {
11671        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11672    }
11673
11674    public void setLockScreenShown(boolean showing, boolean occluded) {
11675        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11676                != PackageManager.PERMISSION_GRANTED) {
11677            throw new SecurityException("Requires permission "
11678                    + android.Manifest.permission.DEVICE_POWER);
11679        }
11680
11681        synchronized(this) {
11682            long ident = Binder.clearCallingIdentity();
11683            try {
11684                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11685                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11686                if (showing && occluded) {
11687                    // The lock screen is currently showing, but is occluded by a window that can
11688                    // show on top of the lock screen. In this can we want to dismiss the docked
11689                    // stack since it will be complicated/risky to try to put the activity on top
11690                    // of the lock screen in the right fullscreen configuration.
11691                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11692                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11693                }
11694
11695                updateSleepIfNeededLocked();
11696            } finally {
11697                Binder.restoreCallingIdentity(ident);
11698            }
11699        }
11700    }
11701
11702    @Override
11703    public void notifyLockedProfile(@UserIdInt int userId) {
11704        try {
11705            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11706                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11707            }
11708        } catch (RemoteException ex) {
11709            throw new SecurityException("Fail to check is caller a privileged app", ex);
11710        }
11711
11712        synchronized (this) {
11713            if (mStackSupervisor.isUserLockedProfile(userId)) {
11714                final long ident = Binder.clearCallingIdentity();
11715                try {
11716                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11717                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11718                        // If there is no device lock, we will show the profile's credential page.
11719                        mActivityStarter.showConfirmDeviceCredential(userId);
11720                    } else {
11721                        // Showing launcher to avoid user entering credential twice.
11722                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11723                    }
11724                } finally {
11725                    Binder.restoreCallingIdentity(ident);
11726                }
11727            }
11728        }
11729    }
11730
11731    @Override
11732    public void startConfirmDeviceCredentialIntent(Intent intent) {
11733        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11734        synchronized (this) {
11735            final long ident = Binder.clearCallingIdentity();
11736            try {
11737                mActivityStarter.startConfirmCredentialIntent(intent);
11738            } finally {
11739                Binder.restoreCallingIdentity(ident);
11740            }
11741        }
11742    }
11743
11744    @Override
11745    public void stopAppSwitches() {
11746        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11747                != PackageManager.PERMISSION_GRANTED) {
11748            throw new SecurityException("viewquires permission "
11749                    + android.Manifest.permission.STOP_APP_SWITCHES);
11750        }
11751
11752        synchronized(this) {
11753            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11754                    + APP_SWITCH_DELAY_TIME;
11755            mDidAppSwitch = false;
11756            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11757            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11758            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11759        }
11760    }
11761
11762    public void resumeAppSwitches() {
11763        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11764                != PackageManager.PERMISSION_GRANTED) {
11765            throw new SecurityException("Requires permission "
11766                    + android.Manifest.permission.STOP_APP_SWITCHES);
11767        }
11768
11769        synchronized(this) {
11770            // Note that we don't execute any pending app switches... we will
11771            // let those wait until either the timeout, or the next start
11772            // activity request.
11773            mAppSwitchesAllowedTime = 0;
11774        }
11775    }
11776
11777    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11778            int callingPid, int callingUid, String name) {
11779        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11780            return true;
11781        }
11782
11783        int perm = checkComponentPermission(
11784                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11785                sourceUid, -1, true);
11786        if (perm == PackageManager.PERMISSION_GRANTED) {
11787            return true;
11788        }
11789
11790        // If the actual IPC caller is different from the logical source, then
11791        // also see if they are allowed to control app switches.
11792        if (callingUid != -1 && callingUid != sourceUid) {
11793            perm = checkComponentPermission(
11794                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11795                    callingUid, -1, true);
11796            if (perm == PackageManager.PERMISSION_GRANTED) {
11797                return true;
11798            }
11799        }
11800
11801        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11802        return false;
11803    }
11804
11805    public void setDebugApp(String packageName, boolean waitForDebugger,
11806            boolean persistent) {
11807        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11808                "setDebugApp()");
11809
11810        long ident = Binder.clearCallingIdentity();
11811        try {
11812            // Note that this is not really thread safe if there are multiple
11813            // callers into it at the same time, but that's not a situation we
11814            // care about.
11815            if (persistent) {
11816                final ContentResolver resolver = mContext.getContentResolver();
11817                Settings.Global.putString(
11818                    resolver, Settings.Global.DEBUG_APP,
11819                    packageName);
11820                Settings.Global.putInt(
11821                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11822                    waitForDebugger ? 1 : 0);
11823            }
11824
11825            synchronized (this) {
11826                if (!persistent) {
11827                    mOrigDebugApp = mDebugApp;
11828                    mOrigWaitForDebugger = mWaitForDebugger;
11829                }
11830                mDebugApp = packageName;
11831                mWaitForDebugger = waitForDebugger;
11832                mDebugTransient = !persistent;
11833                if (packageName != null) {
11834                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11835                            false, UserHandle.USER_ALL, "set debug app");
11836                }
11837            }
11838        } finally {
11839            Binder.restoreCallingIdentity(ident);
11840        }
11841    }
11842
11843    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11844        synchronized (this) {
11845            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11846            if (!isDebuggable) {
11847                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11848                    throw new SecurityException("Process not debuggable: " + app.packageName);
11849                }
11850            }
11851
11852            mTrackAllocationApp = processName;
11853        }
11854    }
11855
11856    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11857        synchronized (this) {
11858            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11859            if (!isDebuggable) {
11860                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11861                    throw new SecurityException("Process not debuggable: " + app.packageName);
11862                }
11863            }
11864            mProfileApp = processName;
11865            mProfileFile = profilerInfo.profileFile;
11866            if (mProfileFd != null) {
11867                try {
11868                    mProfileFd.close();
11869                } catch (IOException e) {
11870                }
11871                mProfileFd = null;
11872            }
11873            mProfileFd = profilerInfo.profileFd;
11874            mSamplingInterval = profilerInfo.samplingInterval;
11875            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11876            mProfileType = 0;
11877        }
11878    }
11879
11880    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11881        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11882        if (!isDebuggable) {
11883            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11884                throw new SecurityException("Process not debuggable: " + app.packageName);
11885            }
11886        }
11887        mNativeDebuggingApp = processName;
11888    }
11889
11890    @Override
11891    public void setAlwaysFinish(boolean enabled) {
11892        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11893                "setAlwaysFinish()");
11894
11895        long ident = Binder.clearCallingIdentity();
11896        try {
11897            Settings.Global.putInt(
11898                    mContext.getContentResolver(),
11899                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11900
11901            synchronized (this) {
11902                mAlwaysFinishActivities = enabled;
11903            }
11904        } finally {
11905            Binder.restoreCallingIdentity(ident);
11906        }
11907    }
11908
11909    @Override
11910    public void setLenientBackgroundCheck(boolean enabled) {
11911        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11912                "setLenientBackgroundCheck()");
11913
11914        long ident = Binder.clearCallingIdentity();
11915        try {
11916            Settings.Global.putInt(
11917                    mContext.getContentResolver(),
11918                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11919
11920            synchronized (this) {
11921                mLenientBackgroundCheck = enabled;
11922            }
11923        } finally {
11924            Binder.restoreCallingIdentity(ident);
11925        }
11926    }
11927
11928    @Override
11929    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11930        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11931                "setActivityController()");
11932        synchronized (this) {
11933            mController = controller;
11934            mControllerIsAMonkey = imAMonkey;
11935            Watchdog.getInstance().setActivityController(controller);
11936        }
11937    }
11938
11939    @Override
11940    public void setUserIsMonkey(boolean userIsMonkey) {
11941        synchronized (this) {
11942            synchronized (mPidsSelfLocked) {
11943                final int callingPid = Binder.getCallingPid();
11944                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11945                if (precessRecord == null) {
11946                    throw new SecurityException("Unknown process: " + callingPid);
11947                }
11948                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11949                    throw new SecurityException("Only an instrumentation process "
11950                            + "with a UiAutomation can call setUserIsMonkey");
11951                }
11952            }
11953            mUserIsMonkey = userIsMonkey;
11954        }
11955    }
11956
11957    @Override
11958    public boolean isUserAMonkey() {
11959        synchronized (this) {
11960            // If there is a controller also implies the user is a monkey.
11961            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11962        }
11963    }
11964
11965    public void requestBugReport(int bugreportType) {
11966        String service = null;
11967        switch (bugreportType) {
11968            case ActivityManager.BUGREPORT_OPTION_FULL:
11969                service = "bugreport";
11970                break;
11971            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11972                service = "bugreportplus";
11973                break;
11974            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11975                service = "bugreportremote";
11976                break;
11977        }
11978        if (service == null) {
11979            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11980                    + bugreportType);
11981        }
11982        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11983        SystemProperties.set("ctl.start", service);
11984    }
11985
11986    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11987        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11988    }
11989
11990    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11991        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11992            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11993        }
11994        return KEY_DISPATCHING_TIMEOUT;
11995    }
11996
11997    @Override
11998    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11999        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12000                != PackageManager.PERMISSION_GRANTED) {
12001            throw new SecurityException("Requires permission "
12002                    + android.Manifest.permission.FILTER_EVENTS);
12003        }
12004        ProcessRecord proc;
12005        long timeout;
12006        synchronized (this) {
12007            synchronized (mPidsSelfLocked) {
12008                proc = mPidsSelfLocked.get(pid);
12009            }
12010            timeout = getInputDispatchingTimeoutLocked(proc);
12011        }
12012
12013        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12014            return -1;
12015        }
12016
12017        return timeout;
12018    }
12019
12020    /**
12021     * Handle input dispatching timeouts.
12022     * Returns whether input dispatching should be aborted or not.
12023     */
12024    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12025            final ActivityRecord activity, final ActivityRecord parent,
12026            final boolean aboveSystem, String reason) {
12027        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12028                != PackageManager.PERMISSION_GRANTED) {
12029            throw new SecurityException("Requires permission "
12030                    + android.Manifest.permission.FILTER_EVENTS);
12031        }
12032
12033        final String annotation;
12034        if (reason == null) {
12035            annotation = "Input dispatching timed out";
12036        } else {
12037            annotation = "Input dispatching timed out (" + reason + ")";
12038        }
12039
12040        if (proc != null) {
12041            synchronized (this) {
12042                if (proc.debugging) {
12043                    return false;
12044                }
12045
12046                if (mDidDexOpt) {
12047                    // Give more time since we were dexopting.
12048                    mDidDexOpt = false;
12049                    return false;
12050                }
12051
12052                if (proc.instrumentationClass != null) {
12053                    Bundle info = new Bundle();
12054                    info.putString("shortMsg", "keyDispatchingTimedOut");
12055                    info.putString("longMsg", annotation);
12056                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12057                    return true;
12058                }
12059            }
12060            mHandler.post(new Runnable() {
12061                @Override
12062                public void run() {
12063                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12064                }
12065            });
12066        }
12067
12068        return true;
12069    }
12070
12071    @Override
12072    public Bundle getAssistContextExtras(int requestType) {
12073        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12074                null, null, true /* focused */, true /* newSessionId */,
12075                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12076        if (pae == null) {
12077            return null;
12078        }
12079        synchronized (pae) {
12080            while (!pae.haveResult) {
12081                try {
12082                    pae.wait();
12083                } catch (InterruptedException e) {
12084                }
12085            }
12086        }
12087        synchronized (this) {
12088            buildAssistBundleLocked(pae, pae.result);
12089            mPendingAssistExtras.remove(pae);
12090            mUiHandler.removeCallbacks(pae);
12091        }
12092        return pae.extras;
12093    }
12094
12095    @Override
12096    public boolean isAssistDataAllowedOnCurrentActivity() {
12097        int userId;
12098        synchronized (this) {
12099            userId = mUserController.getCurrentUserIdLocked();
12100            ActivityRecord activity = getFocusedStack().topActivity();
12101            if (activity == null) {
12102                return false;
12103            }
12104            userId = activity.userId;
12105        }
12106        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12107                Context.DEVICE_POLICY_SERVICE);
12108        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12109    }
12110
12111    @Override
12112    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12113        long ident = Binder.clearCallingIdentity();
12114        try {
12115            synchronized (this) {
12116                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12117                ActivityRecord top = getFocusedStack().topActivity();
12118                if (top != caller) {
12119                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12120                            + " is not current top " + top);
12121                    return false;
12122                }
12123                if (!top.nowVisible) {
12124                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12125                            + " is not visible");
12126                    return false;
12127                }
12128            }
12129            AssistUtils utils = new AssistUtils(mContext);
12130            return utils.showSessionForActiveService(args,
12131                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12132        } finally {
12133            Binder.restoreCallingIdentity(ident);
12134        }
12135    }
12136
12137    @Override
12138    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12139            Bundle receiverExtras,
12140            IBinder activityToken, boolean focused, boolean newSessionId) {
12141        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12142                activityToken, focused, newSessionId,
12143                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12144                != null;
12145    }
12146
12147    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12148            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12149            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12150        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12151                "enqueueAssistContext()");
12152        synchronized (this) {
12153            ActivityRecord activity = getFocusedStack().topActivity();
12154            if (activity == null) {
12155                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12156                return null;
12157            }
12158            if (activity.app == null || activity.app.thread == null) {
12159                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12160                return null;
12161            }
12162            if (focused) {
12163                if (activityToken != null) {
12164                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12165                    if (activity != caller) {
12166                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12167                                + " is not current top " + activity);
12168                        return null;
12169                    }
12170                }
12171            } else {
12172                activity = ActivityRecord.forTokenLocked(activityToken);
12173                if (activity == null) {
12174                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12175                            + " couldn't be found");
12176                    return null;
12177                }
12178            }
12179
12180            PendingAssistExtras pae;
12181            Bundle extras = new Bundle();
12182            if (args != null) {
12183                extras.putAll(args);
12184            }
12185            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12186            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12187            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12188                    userHandle);
12189            // Increment the sessionId if necessary
12190            if (newSessionId) {
12191                mViSessionId++;
12192            }
12193            try {
12194                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12195                        requestType, mViSessionId);
12196                mPendingAssistExtras.add(pae);
12197                mUiHandler.postDelayed(pae, timeout);
12198            } catch (RemoteException e) {
12199                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12200                return null;
12201            }
12202            return pae;
12203        }
12204    }
12205
12206    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12207        IResultReceiver receiver;
12208        synchronized (this) {
12209            mPendingAssistExtras.remove(pae);
12210            receiver = pae.receiver;
12211        }
12212        if (receiver != null) {
12213            // Caller wants result sent back to them.
12214            Bundle sendBundle = new Bundle();
12215            // At least return the receiver extras
12216            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12217                    pae.receiverExtras);
12218            try {
12219                pae.receiver.send(0, sendBundle);
12220            } catch (RemoteException e) {
12221            }
12222        }
12223    }
12224
12225    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12226        if (result != null) {
12227            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12228        }
12229        if (pae.hint != null) {
12230            pae.extras.putBoolean(pae.hint, true);
12231        }
12232    }
12233
12234    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12235            AssistContent content, Uri referrer) {
12236        PendingAssistExtras pae = (PendingAssistExtras)token;
12237        synchronized (pae) {
12238            pae.result = extras;
12239            pae.structure = structure;
12240            pae.content = content;
12241            if (referrer != null) {
12242                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12243            }
12244            pae.haveResult = true;
12245            pae.notifyAll();
12246            if (pae.intent == null && pae.receiver == null) {
12247                // Caller is just waiting for the result.
12248                return;
12249            }
12250        }
12251
12252        // We are now ready to launch the assist activity.
12253        IResultReceiver sendReceiver = null;
12254        Bundle sendBundle = null;
12255        synchronized (this) {
12256            buildAssistBundleLocked(pae, extras);
12257            boolean exists = mPendingAssistExtras.remove(pae);
12258            mUiHandler.removeCallbacks(pae);
12259            if (!exists) {
12260                // Timed out.
12261                return;
12262            }
12263            if ((sendReceiver=pae.receiver) != null) {
12264                // Caller wants result sent back to them.
12265                sendBundle = new Bundle();
12266                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12267                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12268                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12269                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12270                        pae.receiverExtras);
12271            }
12272        }
12273        if (sendReceiver != null) {
12274            try {
12275                sendReceiver.send(0, sendBundle);
12276            } catch (RemoteException e) {
12277            }
12278            return;
12279        }
12280
12281        long ident = Binder.clearCallingIdentity();
12282        try {
12283            pae.intent.replaceExtras(pae.extras);
12284            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12285                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12286                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12287            closeSystemDialogs("assist");
12288            try {
12289                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12290            } catch (ActivityNotFoundException e) {
12291                Slog.w(TAG, "No activity to handle assist action.", e);
12292            }
12293        } finally {
12294            Binder.restoreCallingIdentity(ident);
12295        }
12296    }
12297
12298    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12299            Bundle args) {
12300        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12301                true /* focused */, true /* newSessionId */,
12302                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12303    }
12304
12305    public void registerProcessObserver(IProcessObserver observer) {
12306        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12307                "registerProcessObserver()");
12308        synchronized (this) {
12309            mProcessObservers.register(observer);
12310        }
12311    }
12312
12313    @Override
12314    public void unregisterProcessObserver(IProcessObserver observer) {
12315        synchronized (this) {
12316            mProcessObservers.unregister(observer);
12317        }
12318    }
12319
12320    @Override
12321    public void registerUidObserver(IUidObserver observer, int which) {
12322        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12323                "registerUidObserver()");
12324        synchronized (this) {
12325            mUidObservers.register(observer, which);
12326        }
12327    }
12328
12329    @Override
12330    public void unregisterUidObserver(IUidObserver observer) {
12331        synchronized (this) {
12332            mUidObservers.unregister(observer);
12333        }
12334    }
12335
12336    @Override
12337    public boolean convertFromTranslucent(IBinder token) {
12338        final long origId = Binder.clearCallingIdentity();
12339        try {
12340            synchronized (this) {
12341                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12342                if (r == null) {
12343                    return false;
12344                }
12345                final boolean translucentChanged = r.changeWindowTranslucency(true);
12346                if (translucentChanged) {
12347                    r.task.stack.releaseBackgroundResources(r);
12348                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12349                }
12350                mWindowManager.setAppFullscreen(token, true);
12351                return translucentChanged;
12352            }
12353        } finally {
12354            Binder.restoreCallingIdentity(origId);
12355        }
12356    }
12357
12358    @Override
12359    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12360        final long origId = Binder.clearCallingIdentity();
12361        try {
12362            synchronized (this) {
12363                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12364                if (r == null) {
12365                    return false;
12366                }
12367                int index = r.task.mActivities.lastIndexOf(r);
12368                if (index > 0) {
12369                    ActivityRecord under = r.task.mActivities.get(index - 1);
12370                    under.returningOptions = options;
12371                }
12372                final boolean translucentChanged = r.changeWindowTranslucency(false);
12373                if (translucentChanged) {
12374                    r.task.stack.convertActivityToTranslucent(r);
12375                }
12376                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12377                mWindowManager.setAppFullscreen(token, false);
12378                return translucentChanged;
12379            }
12380        } finally {
12381            Binder.restoreCallingIdentity(origId);
12382        }
12383    }
12384
12385    @Override
12386    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12387        final long origId = Binder.clearCallingIdentity();
12388        try {
12389            synchronized (this) {
12390                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12391                if (r != null) {
12392                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12393                }
12394            }
12395            return false;
12396        } finally {
12397            Binder.restoreCallingIdentity(origId);
12398        }
12399    }
12400
12401    @Override
12402    public boolean isBackgroundVisibleBehind(IBinder token) {
12403        final long origId = Binder.clearCallingIdentity();
12404        try {
12405            synchronized (this) {
12406                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12407                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12408                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12409                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12410                return visible;
12411            }
12412        } finally {
12413            Binder.restoreCallingIdentity(origId);
12414        }
12415    }
12416
12417    @Override
12418    public ActivityOptions getActivityOptions(IBinder token) {
12419        final long origId = Binder.clearCallingIdentity();
12420        try {
12421            synchronized (this) {
12422                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12423                if (r != null) {
12424                    final ActivityOptions activityOptions = r.pendingOptions;
12425                    r.pendingOptions = null;
12426                    return activityOptions;
12427                }
12428                return null;
12429            }
12430        } finally {
12431            Binder.restoreCallingIdentity(origId);
12432        }
12433    }
12434
12435    @Override
12436    public void setImmersive(IBinder token, boolean immersive) {
12437        synchronized(this) {
12438            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12439            if (r == null) {
12440                throw new IllegalArgumentException();
12441            }
12442            r.immersive = immersive;
12443
12444            // update associated state if we're frontmost
12445            if (r == mFocusedActivity) {
12446                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12447                applyUpdateLockStateLocked(r);
12448            }
12449        }
12450    }
12451
12452    @Override
12453    public boolean isImmersive(IBinder token) {
12454        synchronized (this) {
12455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12456            if (r == null) {
12457                throw new IllegalArgumentException();
12458            }
12459            return r.immersive;
12460        }
12461    }
12462
12463    @Override
12464    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12465        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12466            throw new UnsupportedOperationException("VR mode not supported on this device!");
12467        }
12468
12469        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12470
12471        ActivityRecord r;
12472        synchronized (this) {
12473            r = ActivityRecord.isInStackLocked(token);
12474        }
12475
12476        if (r == null) {
12477            throw new IllegalArgumentException();
12478        }
12479
12480        int err;
12481        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12482                VrManagerInternal.NO_ERROR) {
12483            return err;
12484        }
12485
12486        synchronized(this) {
12487            r.requestedVrComponent = (enabled) ? packageName : null;
12488
12489            // Update associated state if this activity is currently focused
12490            if (r == mFocusedActivity) {
12491                applyUpdateVrModeLocked(r);
12492            }
12493            return 0;
12494        }
12495    }
12496
12497    @Override
12498    public boolean isVrModePackageEnabled(ComponentName packageName) {
12499        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12500            throw new UnsupportedOperationException("VR mode not supported on this device!");
12501        }
12502
12503        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12504
12505        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12506                VrManagerInternal.NO_ERROR;
12507    }
12508
12509    public boolean isTopActivityImmersive() {
12510        enforceNotIsolatedCaller("startActivity");
12511        synchronized (this) {
12512            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12513            return (r != null) ? r.immersive : false;
12514        }
12515    }
12516
12517    @Override
12518    public boolean isTopOfTask(IBinder token) {
12519        synchronized (this) {
12520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12521            if (r == null) {
12522                throw new IllegalArgumentException();
12523            }
12524            return r.task.getTopActivity() == r;
12525        }
12526    }
12527
12528    public final void enterSafeMode() {
12529        synchronized(this) {
12530            // It only makes sense to do this before the system is ready
12531            // and started launching other packages.
12532            if (!mSystemReady) {
12533                try {
12534                    AppGlobals.getPackageManager().enterSafeMode();
12535                } catch (RemoteException e) {
12536                }
12537            }
12538
12539            mSafeMode = true;
12540        }
12541    }
12542
12543    public final void showSafeModeOverlay() {
12544        View v = LayoutInflater.from(mContext).inflate(
12545                com.android.internal.R.layout.safe_mode, null);
12546        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12547        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12548        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12549        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12550        lp.gravity = Gravity.BOTTOM | Gravity.START;
12551        lp.format = v.getBackground().getOpacity();
12552        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12553                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12554        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12555        ((WindowManager)mContext.getSystemService(
12556                Context.WINDOW_SERVICE)).addView(v, lp);
12557    }
12558
12559    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12560        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12561            return;
12562        }
12563        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12564        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12565        synchronized (stats) {
12566            if (mBatteryStatsService.isOnBattery()) {
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                BatteryStatsImpl.Uid.Pkg pkg =
12576                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12577                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12578                pkg.noteWakeupAlarmLocked(tag);
12579            }
12580        }
12581    }
12582
12583    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12584        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12585            return;
12586        }
12587        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12588        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12589        synchronized (stats) {
12590            mBatteryStatsService.enforceCallingPermission();
12591            int MY_UID = Binder.getCallingUid();
12592            final int uid;
12593            if (sender == null) {
12594                uid = sourceUid;
12595            } else {
12596                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12597            }
12598            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12599        }
12600    }
12601
12602    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12603        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12604            return;
12605        }
12606        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12607        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12608        synchronized (stats) {
12609            mBatteryStatsService.enforceCallingPermission();
12610            int MY_UID = Binder.getCallingUid();
12611            final int uid;
12612            if (sender == null) {
12613                uid = sourceUid;
12614            } else {
12615                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12616            }
12617            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12618        }
12619    }
12620
12621    public boolean killPids(int[] pids, String pReason, boolean secure) {
12622        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12623            throw new SecurityException("killPids only available to the system");
12624        }
12625        String reason = (pReason == null) ? "Unknown" : pReason;
12626        // XXX Note: don't acquire main activity lock here, because the window
12627        // manager calls in with its locks held.
12628
12629        boolean killed = false;
12630        synchronized (mPidsSelfLocked) {
12631            int worstType = 0;
12632            for (int i=0; i<pids.length; i++) {
12633                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12634                if (proc != null) {
12635                    int type = proc.setAdj;
12636                    if (type > worstType) {
12637                        worstType = type;
12638                    }
12639                }
12640            }
12641
12642            // If the worst oom_adj is somewhere in the cached proc LRU range,
12643            // then constrain it so we will kill all cached procs.
12644            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12645                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12646                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12647            }
12648
12649            // If this is not a secure call, don't let it kill processes that
12650            // are important.
12651            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12652                worstType = ProcessList.SERVICE_ADJ;
12653            }
12654
12655            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12656            for (int i=0; i<pids.length; i++) {
12657                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12658                if (proc == null) {
12659                    continue;
12660                }
12661                int adj = proc.setAdj;
12662                if (adj >= worstType && !proc.killedByAm) {
12663                    proc.kill(reason, true);
12664                    killed = true;
12665                }
12666            }
12667        }
12668        return killed;
12669    }
12670
12671    @Override
12672    public void killUid(int appId, int userId, String reason) {
12673        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12674        synchronized (this) {
12675            final long identity = Binder.clearCallingIdentity();
12676            try {
12677                killPackageProcessesLocked(null, appId, userId,
12678                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12679                        reason != null ? reason : "kill uid");
12680            } finally {
12681                Binder.restoreCallingIdentity(identity);
12682            }
12683        }
12684    }
12685
12686    @Override
12687    public boolean killProcessesBelowForeground(String reason) {
12688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12689            throw new SecurityException("killProcessesBelowForeground() only available to system");
12690        }
12691
12692        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12693    }
12694
12695    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12696        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12697            throw new SecurityException("killProcessesBelowAdj() only available to system");
12698        }
12699
12700        boolean killed = false;
12701        synchronized (mPidsSelfLocked) {
12702            final int size = mPidsSelfLocked.size();
12703            for (int i = 0; i < size; i++) {
12704                final int pid = mPidsSelfLocked.keyAt(i);
12705                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12706                if (proc == null) continue;
12707
12708                final int adj = proc.setAdj;
12709                if (adj > belowAdj && !proc.killedByAm) {
12710                    proc.kill(reason, true);
12711                    killed = true;
12712                }
12713            }
12714        }
12715        return killed;
12716    }
12717
12718    @Override
12719    public void hang(final IBinder who, boolean allowRestart) {
12720        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12721                != PackageManager.PERMISSION_GRANTED) {
12722            throw new SecurityException("Requires permission "
12723                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12724        }
12725
12726        final IBinder.DeathRecipient death = new DeathRecipient() {
12727            @Override
12728            public void binderDied() {
12729                synchronized (this) {
12730                    notifyAll();
12731                }
12732            }
12733        };
12734
12735        try {
12736            who.linkToDeath(death, 0);
12737        } catch (RemoteException e) {
12738            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12739            return;
12740        }
12741
12742        synchronized (this) {
12743            Watchdog.getInstance().setAllowRestart(allowRestart);
12744            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12745            synchronized (death) {
12746                while (who.isBinderAlive()) {
12747                    try {
12748                        death.wait();
12749                    } catch (InterruptedException e) {
12750                    }
12751                }
12752            }
12753            Watchdog.getInstance().setAllowRestart(true);
12754        }
12755    }
12756
12757    @Override
12758    public void restart() {
12759        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12760                != PackageManager.PERMISSION_GRANTED) {
12761            throw new SecurityException("Requires permission "
12762                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12763        }
12764
12765        Log.i(TAG, "Sending shutdown broadcast...");
12766
12767        BroadcastReceiver br = new BroadcastReceiver() {
12768            @Override public void onReceive(Context context, Intent intent) {
12769                // Now the broadcast is done, finish up the low-level shutdown.
12770                Log.i(TAG, "Shutting down activity manager...");
12771                shutdown(10000);
12772                Log.i(TAG, "Shutdown complete, restarting!");
12773                Process.killProcess(Process.myPid());
12774                System.exit(10);
12775            }
12776        };
12777
12778        // First send the high-level shut down broadcast.
12779        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12780        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12781        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12782        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12783        mContext.sendOrderedBroadcastAsUser(intent,
12784                UserHandle.ALL, null, br, mHandler, 0, null, null);
12785        */
12786        br.onReceive(mContext, intent);
12787    }
12788
12789    private long getLowRamTimeSinceIdle(long now) {
12790        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12791    }
12792
12793    @Override
12794    public void performIdleMaintenance() {
12795        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12796                != PackageManager.PERMISSION_GRANTED) {
12797            throw new SecurityException("Requires permission "
12798                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12799        }
12800
12801        synchronized (this) {
12802            final long now = SystemClock.uptimeMillis();
12803            final long timeSinceLastIdle = now - mLastIdleTime;
12804            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12805            mLastIdleTime = now;
12806            mLowRamTimeSinceLastIdle = 0;
12807            if (mLowRamStartTime != 0) {
12808                mLowRamStartTime = now;
12809            }
12810
12811            StringBuilder sb = new StringBuilder(128);
12812            sb.append("Idle maintenance over ");
12813            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12814            sb.append(" low RAM for ");
12815            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12816            Slog.i(TAG, sb.toString());
12817
12818            // If at least 1/3 of our time since the last idle period has been spent
12819            // with RAM low, then we want to kill processes.
12820            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12821
12822            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12823                ProcessRecord proc = mLruProcesses.get(i);
12824                if (proc.notCachedSinceIdle) {
12825                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12826                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12827                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12828                        if (doKilling && proc.initialIdlePss != 0
12829                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12830                            sb = new StringBuilder(128);
12831                            sb.append("Kill");
12832                            sb.append(proc.processName);
12833                            sb.append(" in idle maint: pss=");
12834                            sb.append(proc.lastPss);
12835                            sb.append(", swapPss=");
12836                            sb.append(proc.lastSwapPss);
12837                            sb.append(", initialPss=");
12838                            sb.append(proc.initialIdlePss);
12839                            sb.append(", period=");
12840                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12841                            sb.append(", lowRamPeriod=");
12842                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12843                            Slog.wtfQuiet(TAG, sb.toString());
12844                            proc.kill("idle maint (pss " + proc.lastPss
12845                                    + " from " + proc.initialIdlePss + ")", true);
12846                        }
12847                    }
12848                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12849                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12850                    proc.notCachedSinceIdle = true;
12851                    proc.initialIdlePss = 0;
12852                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12853                            mTestPssMode, isSleeping(), now);
12854                }
12855            }
12856
12857            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12858            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12859        }
12860    }
12861
12862    @Override
12863    public void sendIdleJobTrigger() {
12864        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12865                != PackageManager.PERMISSION_GRANTED) {
12866            throw new SecurityException("Requires permission "
12867                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12868        }
12869
12870        final long ident = Binder.clearCallingIdentity();
12871        try {
12872            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12873                    .setPackage("android")
12874                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12875            broadcastIntent(null, intent, null, null, 0, null, null, null,
12876                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12877        } finally {
12878            Binder.restoreCallingIdentity(ident);
12879        }
12880    }
12881
12882    private void retrieveSettings() {
12883        final ContentResolver resolver = mContext.getContentResolver();
12884        final boolean freeformWindowManagement =
12885                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12886                        || Settings.Global.getInt(
12887                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12888        final boolean supportsPictureInPicture =
12889                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12890
12891        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12892        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12893        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12894        final boolean alwaysFinishActivities =
12895                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12896        final boolean lenientBackgroundCheck =
12897                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12898        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12899        final boolean forceResizable = Settings.Global.getInt(
12900                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12901        final boolean supportsLeanbackOnly =
12902                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12903
12904        // Transfer any global setting for forcing RTL layout, into a System Property
12905        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12906
12907        final Configuration configuration = new Configuration();
12908        Settings.System.getConfiguration(resolver, configuration);
12909        if (forceRtl) {
12910            // This will take care of setting the correct layout direction flags
12911            configuration.setLayoutDirection(configuration.locale);
12912        }
12913
12914        synchronized (this) {
12915            mDebugApp = mOrigDebugApp = debugApp;
12916            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12917            mAlwaysFinishActivities = alwaysFinishActivities;
12918            mLenientBackgroundCheck = lenientBackgroundCheck;
12919            mSupportsLeanbackOnly = supportsLeanbackOnly;
12920            mForceResizableActivities = forceResizable;
12921            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12922            if (supportsMultiWindow || forceResizable) {
12923                mSupportsMultiWindow = true;
12924                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12925                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12926            } else {
12927                mSupportsMultiWindow = false;
12928                mSupportsFreeformWindowManagement = false;
12929                mSupportsPictureInPicture = false;
12930            }
12931            // This happens before any activities are started, so we can
12932            // change mConfiguration in-place.
12933            updateConfigurationLocked(configuration, null, true);
12934            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12935                    "Initial config: " + mConfiguration);
12936
12937            // Load resources only after the current configuration has been set.
12938            final Resources res = mContext.getResources();
12939            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12940            mThumbnailWidth = res.getDimensionPixelSize(
12941                    com.android.internal.R.dimen.thumbnail_width);
12942            mThumbnailHeight = res.getDimensionPixelSize(
12943                    com.android.internal.R.dimen.thumbnail_height);
12944            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12945                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12946            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12947                    com.android.internal.R.string.config_appsNotReportingCrashes));
12948            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12949                mFullscreenThumbnailScale = (float) res
12950                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12951                    (float) mConfiguration.screenWidthDp;
12952            } else {
12953                mFullscreenThumbnailScale = res.getFraction(
12954                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12955            }
12956        }
12957    }
12958
12959    public boolean testIsSystemReady() {
12960        // no need to synchronize(this) just to read & return the value
12961        return mSystemReady;
12962    }
12963
12964    public void systemReady(final Runnable goingCallback) {
12965        synchronized(this) {
12966            if (mSystemReady) {
12967                // If we're done calling all the receivers, run the next "boot phase" passed in
12968                // by the SystemServer
12969                if (goingCallback != null) {
12970                    goingCallback.run();
12971                }
12972                return;
12973            }
12974
12975            mLocalDeviceIdleController
12976                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12977
12978            // Make sure we have the current profile info, since it is needed for security checks.
12979            mUserController.onSystemReady();
12980            mRecentTasks.onSystemReadyLocked();
12981            mAppOpsService.systemReady();
12982            mSystemReady = true;
12983        }
12984
12985        ArrayList<ProcessRecord> procsToKill = null;
12986        synchronized(mPidsSelfLocked) {
12987            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12988                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12989                if (!isAllowedWhileBooting(proc.info)){
12990                    if (procsToKill == null) {
12991                        procsToKill = new ArrayList<ProcessRecord>();
12992                    }
12993                    procsToKill.add(proc);
12994                }
12995            }
12996        }
12997
12998        synchronized(this) {
12999            if (procsToKill != null) {
13000                for (int i=procsToKill.size()-1; i>=0; i--) {
13001                    ProcessRecord proc = procsToKill.get(i);
13002                    Slog.i(TAG, "Removing system update proc: " + proc);
13003                    removeProcessLocked(proc, true, false, "system update done");
13004                }
13005            }
13006
13007            // Now that we have cleaned up any update processes, we
13008            // are ready to start launching real processes and know that
13009            // we won't trample on them any more.
13010            mProcessesReady = true;
13011        }
13012
13013        Slog.i(TAG, "System now ready");
13014        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13015            SystemClock.uptimeMillis());
13016
13017        synchronized(this) {
13018            // Make sure we have no pre-ready processes sitting around.
13019
13020            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13021                ResolveInfo ri = mContext.getPackageManager()
13022                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13023                                STOCK_PM_FLAGS);
13024                CharSequence errorMsg = null;
13025                if (ri != null) {
13026                    ActivityInfo ai = ri.activityInfo;
13027                    ApplicationInfo app = ai.applicationInfo;
13028                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13029                        mTopAction = Intent.ACTION_FACTORY_TEST;
13030                        mTopData = null;
13031                        mTopComponent = new ComponentName(app.packageName,
13032                                ai.name);
13033                    } else {
13034                        errorMsg = mContext.getResources().getText(
13035                                com.android.internal.R.string.factorytest_not_system);
13036                    }
13037                } else {
13038                    errorMsg = mContext.getResources().getText(
13039                            com.android.internal.R.string.factorytest_no_action);
13040                }
13041                if (errorMsg != null) {
13042                    mTopAction = null;
13043                    mTopData = null;
13044                    mTopComponent = null;
13045                    Message msg = Message.obtain();
13046                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13047                    msg.getData().putCharSequence("msg", errorMsg);
13048                    mUiHandler.sendMessage(msg);
13049                }
13050            }
13051        }
13052
13053        retrieveSettings();
13054        final int currentUserId;
13055        synchronized (this) {
13056            currentUserId = mUserController.getCurrentUserIdLocked();
13057            readGrantedUriPermissionsLocked();
13058        }
13059
13060        if (goingCallback != null) goingCallback.run();
13061
13062        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13063                Integer.toString(currentUserId), currentUserId);
13064        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13065                Integer.toString(currentUserId), currentUserId);
13066        mSystemServiceManager.startUser(currentUserId);
13067
13068        synchronized (this) {
13069            // Only start up encryption-aware persistent apps; once user is
13070            // unlocked we'll come back around and start unaware apps
13071            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13072
13073            // Start up initial activity.
13074            mBooting = true;
13075            // Enable home activity for system user, so that the system can always boot
13076            if (UserManager.isSplitSystemUser()) {
13077                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13078                try {
13079                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13080                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13081                            UserHandle.USER_SYSTEM);
13082                } catch (RemoteException e) {
13083                    throw e.rethrowAsRuntimeException();
13084                }
13085            }
13086            startHomeActivityLocked(currentUserId, "systemReady");
13087
13088            try {
13089                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13090                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13091                            + " data partition or your device will be unstable.");
13092                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13093                }
13094            } catch (RemoteException e) {
13095            }
13096
13097            if (!Build.isBuildConsistent()) {
13098                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13099                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13100            }
13101
13102            long ident = Binder.clearCallingIdentity();
13103            try {
13104                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13105                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13106                        | Intent.FLAG_RECEIVER_FOREGROUND);
13107                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13108                broadcastIntentLocked(null, null, intent,
13109                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13110                        null, false, false, MY_PID, Process.SYSTEM_UID,
13111                        currentUserId);
13112                intent = new Intent(Intent.ACTION_USER_STARTING);
13113                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13114                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13115                broadcastIntentLocked(null, null, intent,
13116                        null, new IIntentReceiver.Stub() {
13117                            @Override
13118                            public void performReceive(Intent intent, int resultCode, String data,
13119                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13120                                    throws RemoteException {
13121                            }
13122                        }, 0, null, null,
13123                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13124                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13125            } catch (Throwable t) {
13126                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13127            } finally {
13128                Binder.restoreCallingIdentity(ident);
13129            }
13130            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13131            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13132        }
13133    }
13134
13135    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13136        synchronized (this) {
13137            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13138        }
13139    }
13140
13141    void skipCurrentReceiverLocked(ProcessRecord app) {
13142        for (BroadcastQueue queue : mBroadcastQueues) {
13143            queue.skipCurrentReceiverLocked(app);
13144        }
13145    }
13146
13147    /**
13148     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13149     * The application process will exit immediately after this call returns.
13150     * @param app object of the crashing app, null for the system server
13151     * @param crashInfo describing the exception
13152     */
13153    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13154        ProcessRecord r = findAppProcess(app, "Crash");
13155        final String processName = app == null ? "system_server"
13156                : (r == null ? "unknown" : r.processName);
13157
13158        handleApplicationCrashInner("crash", r, processName, crashInfo);
13159    }
13160
13161    /* Native crash reporting uses this inner version because it needs to be somewhat
13162     * decoupled from the AM-managed cleanup lifecycle
13163     */
13164    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13165            ApplicationErrorReport.CrashInfo crashInfo) {
13166        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13167                UserHandle.getUserId(Binder.getCallingUid()), processName,
13168                r == null ? -1 : r.info.flags,
13169                crashInfo.exceptionClassName,
13170                crashInfo.exceptionMessage,
13171                crashInfo.throwFileName,
13172                crashInfo.throwLineNumber);
13173
13174        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13175
13176        mAppErrors.crashApplication(r, crashInfo);
13177    }
13178
13179    public void handleApplicationStrictModeViolation(
13180            IBinder app,
13181            int violationMask,
13182            StrictMode.ViolationInfo info) {
13183        ProcessRecord r = findAppProcess(app, "StrictMode");
13184        if (r == null) {
13185            return;
13186        }
13187
13188        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13189            Integer stackFingerprint = info.hashCode();
13190            boolean logIt = true;
13191            synchronized (mAlreadyLoggedViolatedStacks) {
13192                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13193                    logIt = false;
13194                    // TODO: sub-sample into EventLog for these, with
13195                    // the info.durationMillis?  Then we'd get
13196                    // the relative pain numbers, without logging all
13197                    // the stack traces repeatedly.  We'd want to do
13198                    // likewise in the client code, which also does
13199                    // dup suppression, before the Binder call.
13200                } else {
13201                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13202                        mAlreadyLoggedViolatedStacks.clear();
13203                    }
13204                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13205                }
13206            }
13207            if (logIt) {
13208                logStrictModeViolationToDropBox(r, info);
13209            }
13210        }
13211
13212        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13213            AppErrorResult result = new AppErrorResult();
13214            synchronized (this) {
13215                final long origId = Binder.clearCallingIdentity();
13216
13217                Message msg = Message.obtain();
13218                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13219                HashMap<String, Object> data = new HashMap<String, Object>();
13220                data.put("result", result);
13221                data.put("app", r);
13222                data.put("violationMask", violationMask);
13223                data.put("info", info);
13224                msg.obj = data;
13225                mUiHandler.sendMessage(msg);
13226
13227                Binder.restoreCallingIdentity(origId);
13228            }
13229            int res = result.get();
13230            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13231        }
13232    }
13233
13234    // Depending on the policy in effect, there could be a bunch of
13235    // these in quick succession so we try to batch these together to
13236    // minimize disk writes, number of dropbox entries, and maximize
13237    // compression, by having more fewer, larger records.
13238    private void logStrictModeViolationToDropBox(
13239            ProcessRecord process,
13240            StrictMode.ViolationInfo info) {
13241        if (info == null) {
13242            return;
13243        }
13244        final boolean isSystemApp = process == null ||
13245                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13246                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13247        final String processName = process == null ? "unknown" : process.processName;
13248        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13249        final DropBoxManager dbox = (DropBoxManager)
13250                mContext.getSystemService(Context.DROPBOX_SERVICE);
13251
13252        // Exit early if the dropbox isn't configured to accept this report type.
13253        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13254
13255        boolean bufferWasEmpty;
13256        boolean needsFlush;
13257        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13258        synchronized (sb) {
13259            bufferWasEmpty = sb.length() == 0;
13260            appendDropBoxProcessHeaders(process, processName, sb);
13261            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13262            sb.append("System-App: ").append(isSystemApp).append("\n");
13263            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13264            if (info.violationNumThisLoop != 0) {
13265                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13266            }
13267            if (info.numAnimationsRunning != 0) {
13268                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13269            }
13270            if (info.broadcastIntentAction != null) {
13271                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13272            }
13273            if (info.durationMillis != -1) {
13274                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13275            }
13276            if (info.numInstances != -1) {
13277                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13278            }
13279            if (info.tags != null) {
13280                for (String tag : info.tags) {
13281                    sb.append("Span-Tag: ").append(tag).append("\n");
13282                }
13283            }
13284            sb.append("\n");
13285            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13286                sb.append(info.crashInfo.stackTrace);
13287                sb.append("\n");
13288            }
13289            if (info.message != null) {
13290                sb.append(info.message);
13291                sb.append("\n");
13292            }
13293
13294            // Only buffer up to ~64k.  Various logging bits truncate
13295            // things at 128k.
13296            needsFlush = (sb.length() > 64 * 1024);
13297        }
13298
13299        // Flush immediately if the buffer's grown too large, or this
13300        // is a non-system app.  Non-system apps are isolated with a
13301        // different tag & policy and not batched.
13302        //
13303        // Batching is useful during internal testing with
13304        // StrictMode settings turned up high.  Without batching,
13305        // thousands of separate files could be created on boot.
13306        if (!isSystemApp || needsFlush) {
13307            new Thread("Error dump: " + dropboxTag) {
13308                @Override
13309                public void run() {
13310                    String report;
13311                    synchronized (sb) {
13312                        report = sb.toString();
13313                        sb.delete(0, sb.length());
13314                        sb.trimToSize();
13315                    }
13316                    if (report.length() != 0) {
13317                        dbox.addText(dropboxTag, report);
13318                    }
13319                }
13320            }.start();
13321            return;
13322        }
13323
13324        // System app batching:
13325        if (!bufferWasEmpty) {
13326            // An existing dropbox-writing thread is outstanding, so
13327            // we don't need to start it up.  The existing thread will
13328            // catch the buffer appends we just did.
13329            return;
13330        }
13331
13332        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13333        // (After this point, we shouldn't access AMS internal data structures.)
13334        new Thread("Error dump: " + dropboxTag) {
13335            @Override
13336            public void run() {
13337                // 5 second sleep to let stacks arrive and be batched together
13338                try {
13339                    Thread.sleep(5000);  // 5 seconds
13340                } catch (InterruptedException e) {}
13341
13342                String errorReport;
13343                synchronized (mStrictModeBuffer) {
13344                    errorReport = mStrictModeBuffer.toString();
13345                    if (errorReport.length() == 0) {
13346                        return;
13347                    }
13348                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13349                    mStrictModeBuffer.trimToSize();
13350                }
13351                dbox.addText(dropboxTag, errorReport);
13352            }
13353        }.start();
13354    }
13355
13356    /**
13357     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13358     * @param app object of the crashing app, null for the system server
13359     * @param tag reported by the caller
13360     * @param system whether this wtf is coming from the system
13361     * @param crashInfo describing the context of the error
13362     * @return true if the process should exit immediately (WTF is fatal)
13363     */
13364    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13365            final ApplicationErrorReport.CrashInfo crashInfo) {
13366        final int callingUid = Binder.getCallingUid();
13367        final int callingPid = Binder.getCallingPid();
13368
13369        if (system) {
13370            // If this is coming from the system, we could very well have low-level
13371            // system locks held, so we want to do this all asynchronously.  And we
13372            // never want this to become fatal, so there is that too.
13373            mHandler.post(new Runnable() {
13374                @Override public void run() {
13375                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13376                }
13377            });
13378            return false;
13379        }
13380
13381        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13382                crashInfo);
13383
13384        if (r != null && r.pid != Process.myPid() &&
13385                Settings.Global.getInt(mContext.getContentResolver(),
13386                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13387            mAppErrors.crashApplication(r, crashInfo);
13388            return true;
13389        } else {
13390            return false;
13391        }
13392    }
13393
13394    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13395            final ApplicationErrorReport.CrashInfo crashInfo) {
13396        final ProcessRecord r = findAppProcess(app, "WTF");
13397        final String processName = app == null ? "system_server"
13398                : (r == null ? "unknown" : r.processName);
13399
13400        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13401                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13402
13403        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13404
13405        return r;
13406    }
13407
13408    /**
13409     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13410     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13411     */
13412    private ProcessRecord findAppProcess(IBinder app, String reason) {
13413        if (app == null) {
13414            return null;
13415        }
13416
13417        synchronized (this) {
13418            final int NP = mProcessNames.getMap().size();
13419            for (int ip=0; ip<NP; ip++) {
13420                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13421                final int NA = apps.size();
13422                for (int ia=0; ia<NA; ia++) {
13423                    ProcessRecord p = apps.valueAt(ia);
13424                    if (p.thread != null && p.thread.asBinder() == app) {
13425                        return p;
13426                    }
13427                }
13428            }
13429
13430            Slog.w(TAG, "Can't find mystery application for " + reason
13431                    + " from pid=" + Binder.getCallingPid()
13432                    + " uid=" + Binder.getCallingUid() + ": " + app);
13433            return null;
13434        }
13435    }
13436
13437    /**
13438     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13439     * to append various headers to the dropbox log text.
13440     */
13441    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13442            StringBuilder sb) {
13443        // Watchdog thread ends up invoking this function (with
13444        // a null ProcessRecord) to add the stack file to dropbox.
13445        // Do not acquire a lock on this (am) in such cases, as it
13446        // could cause a potential deadlock, if and when watchdog
13447        // is invoked due to unavailability of lock on am and it
13448        // would prevent watchdog from killing system_server.
13449        if (process == null) {
13450            sb.append("Process: ").append(processName).append("\n");
13451            return;
13452        }
13453        // Note: ProcessRecord 'process' is guarded by the service
13454        // instance.  (notably process.pkgList, which could otherwise change
13455        // concurrently during execution of this method)
13456        synchronized (this) {
13457            sb.append("Process: ").append(processName).append("\n");
13458            int flags = process.info.flags;
13459            IPackageManager pm = AppGlobals.getPackageManager();
13460            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13461            for (int ip=0; ip<process.pkgList.size(); ip++) {
13462                String pkg = process.pkgList.keyAt(ip);
13463                sb.append("Package: ").append(pkg);
13464                try {
13465                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13466                    if (pi != null) {
13467                        sb.append(" v").append(pi.versionCode);
13468                        if (pi.versionName != null) {
13469                            sb.append(" (").append(pi.versionName).append(")");
13470                        }
13471                    }
13472                } catch (RemoteException e) {
13473                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13474                }
13475                sb.append("\n");
13476            }
13477        }
13478    }
13479
13480    private static String processClass(ProcessRecord process) {
13481        if (process == null || process.pid == MY_PID) {
13482            return "system_server";
13483        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13484            return "system_app";
13485        } else {
13486            return "data_app";
13487        }
13488    }
13489
13490    private volatile long mWtfClusterStart;
13491    private volatile int mWtfClusterCount;
13492
13493    /**
13494     * Write a description of an error (crash, WTF, ANR) to the drop box.
13495     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13496     * @param process which caused the error, null means the system server
13497     * @param activity which triggered the error, null if unknown
13498     * @param parent activity related to the error, null if unknown
13499     * @param subject line related to the error, null if absent
13500     * @param report in long form describing the error, null if absent
13501     * @param logFile to include in the report, null if none
13502     * @param crashInfo giving an application stack trace, null if absent
13503     */
13504    public void addErrorToDropBox(String eventType,
13505            ProcessRecord process, String processName, ActivityRecord activity,
13506            ActivityRecord parent, String subject,
13507            final String report, final File logFile,
13508            final ApplicationErrorReport.CrashInfo crashInfo) {
13509        // NOTE -- this must never acquire the ActivityManagerService lock,
13510        // otherwise the watchdog may be prevented from resetting the system.
13511
13512        final String dropboxTag = processClass(process) + "_" + eventType;
13513        final DropBoxManager dbox = (DropBoxManager)
13514                mContext.getSystemService(Context.DROPBOX_SERVICE);
13515
13516        // Exit early if the dropbox isn't configured to accept this report type.
13517        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13518
13519        // Rate-limit how often we're willing to do the heavy lifting below to
13520        // collect and record logs; currently 5 logs per 10 second period.
13521        final long now = SystemClock.elapsedRealtime();
13522        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13523            mWtfClusterStart = now;
13524            mWtfClusterCount = 1;
13525        } else {
13526            if (mWtfClusterCount++ >= 5) return;
13527        }
13528
13529        final StringBuilder sb = new StringBuilder(1024);
13530        appendDropBoxProcessHeaders(process, processName, sb);
13531        if (process != null) {
13532            sb.append("Foreground: ")
13533                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13534                    .append("\n");
13535        }
13536        if (activity != null) {
13537            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13538        }
13539        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13540            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13541        }
13542        if (parent != null && parent != activity) {
13543            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13544        }
13545        if (subject != null) {
13546            sb.append("Subject: ").append(subject).append("\n");
13547        }
13548        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13549        if (Debug.isDebuggerConnected()) {
13550            sb.append("Debugger: Connected\n");
13551        }
13552        sb.append("\n");
13553
13554        // Do the rest in a worker thread to avoid blocking the caller on I/O
13555        // (After this point, we shouldn't access AMS internal data structures.)
13556        Thread worker = new Thread("Error dump: " + dropboxTag) {
13557            @Override
13558            public void run() {
13559                if (report != null) {
13560                    sb.append(report);
13561                }
13562                if (logFile != null) {
13563                    try {
13564                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13565                                    "\n\n[[TRUNCATED]]"));
13566                    } catch (IOException e) {
13567                        Slog.e(TAG, "Error reading " + logFile, e);
13568                    }
13569                }
13570                if (crashInfo != null && crashInfo.stackTrace != null) {
13571                    sb.append(crashInfo.stackTrace);
13572                }
13573
13574                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13575                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13576                if (lines > 0) {
13577                    sb.append("\n");
13578
13579                    // Merge several logcat streams, and take the last N lines
13580                    InputStreamReader input = null;
13581                    try {
13582                        java.lang.Process logcat = new ProcessBuilder(
13583                                "/system/bin/timeout", "-k", "15s", "10s",
13584                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13585                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13586                                        .redirectErrorStream(true).start();
13587
13588                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13589                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13590                        input = new InputStreamReader(logcat.getInputStream());
13591
13592                        int num;
13593                        char[] buf = new char[8192];
13594                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13595                    } catch (IOException e) {
13596                        Slog.e(TAG, "Error running logcat", e);
13597                    } finally {
13598                        if (input != null) try { input.close(); } catch (IOException e) {}
13599                    }
13600                }
13601
13602                dbox.addText(dropboxTag, sb.toString());
13603            }
13604        };
13605
13606        if (process == null) {
13607            // If process is null, we are being called from some internal code
13608            // and may be about to die -- run this synchronously.
13609            worker.run();
13610        } else {
13611            worker.start();
13612        }
13613    }
13614
13615    @Override
13616    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13617        enforceNotIsolatedCaller("getProcessesInErrorState");
13618        // assume our apps are happy - lazy create the list
13619        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13620
13621        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13622                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13623        int userId = UserHandle.getUserId(Binder.getCallingUid());
13624
13625        synchronized (this) {
13626
13627            // iterate across all processes
13628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13629                ProcessRecord app = mLruProcesses.get(i);
13630                if (!allUsers && app.userId != userId) {
13631                    continue;
13632                }
13633                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13634                    // This one's in trouble, so we'll generate a report for it
13635                    // crashes are higher priority (in case there's a crash *and* an anr)
13636                    ActivityManager.ProcessErrorStateInfo report = null;
13637                    if (app.crashing) {
13638                        report = app.crashingReport;
13639                    } else if (app.notResponding) {
13640                        report = app.notRespondingReport;
13641                    }
13642
13643                    if (report != null) {
13644                        if (errList == null) {
13645                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13646                        }
13647                        errList.add(report);
13648                    } else {
13649                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13650                                " crashing = " + app.crashing +
13651                                " notResponding = " + app.notResponding);
13652                    }
13653                }
13654            }
13655        }
13656
13657        return errList;
13658    }
13659
13660    static int procStateToImportance(int procState, int memAdj,
13661            ActivityManager.RunningAppProcessInfo currApp) {
13662        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13663        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13664            currApp.lru = memAdj;
13665        } else {
13666            currApp.lru = 0;
13667        }
13668        return imp;
13669    }
13670
13671    private void fillInProcMemInfo(ProcessRecord app,
13672            ActivityManager.RunningAppProcessInfo outInfo) {
13673        outInfo.pid = app.pid;
13674        outInfo.uid = app.info.uid;
13675        if (mHeavyWeightProcess == app) {
13676            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13677        }
13678        if (app.persistent) {
13679            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13680        }
13681        if (app.activities.size() > 0) {
13682            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13683        }
13684        outInfo.lastTrimLevel = app.trimMemoryLevel;
13685        int adj = app.curAdj;
13686        int procState = app.curProcState;
13687        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13688        outInfo.importanceReasonCode = app.adjTypeCode;
13689        outInfo.processState = app.curProcState;
13690    }
13691
13692    @Override
13693    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13694        enforceNotIsolatedCaller("getRunningAppProcesses");
13695
13696        final int callingUid = Binder.getCallingUid();
13697
13698        // Lazy instantiation of list
13699        List<ActivityManager.RunningAppProcessInfo> runList = null;
13700        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13701                callingUid) == PackageManager.PERMISSION_GRANTED;
13702        final int userId = UserHandle.getUserId(callingUid);
13703        final boolean allUids = isGetTasksAllowed(
13704                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13705
13706        synchronized (this) {
13707            // Iterate across all processes
13708            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13709                ProcessRecord app = mLruProcesses.get(i);
13710                if ((!allUsers && app.userId != userId)
13711                        || (!allUids && app.uid != callingUid)) {
13712                    continue;
13713                }
13714                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13715                    // Generate process state info for running application
13716                    ActivityManager.RunningAppProcessInfo currApp =
13717                        new ActivityManager.RunningAppProcessInfo(app.processName,
13718                                app.pid, app.getPackageList());
13719                    fillInProcMemInfo(app, currApp);
13720                    if (app.adjSource instanceof ProcessRecord) {
13721                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13722                        currApp.importanceReasonImportance =
13723                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13724                                        app.adjSourceProcState);
13725                    } else if (app.adjSource instanceof ActivityRecord) {
13726                        ActivityRecord r = (ActivityRecord)app.adjSource;
13727                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13728                    }
13729                    if (app.adjTarget instanceof ComponentName) {
13730                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13731                    }
13732                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13733                    //        + " lru=" + currApp.lru);
13734                    if (runList == null) {
13735                        runList = new ArrayList<>();
13736                    }
13737                    runList.add(currApp);
13738                }
13739            }
13740        }
13741        return runList;
13742    }
13743
13744    @Override
13745    public List<ApplicationInfo> getRunningExternalApplications() {
13746        enforceNotIsolatedCaller("getRunningExternalApplications");
13747        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13748        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13749        if (runningApps != null && runningApps.size() > 0) {
13750            Set<String> extList = new HashSet<String>();
13751            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13752                if (app.pkgList != null) {
13753                    for (String pkg : app.pkgList) {
13754                        extList.add(pkg);
13755                    }
13756                }
13757            }
13758            IPackageManager pm = AppGlobals.getPackageManager();
13759            for (String pkg : extList) {
13760                try {
13761                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13762                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13763                        retList.add(info);
13764                    }
13765                } catch (RemoteException e) {
13766                }
13767            }
13768        }
13769        return retList;
13770    }
13771
13772    @Override
13773    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13774        enforceNotIsolatedCaller("getMyMemoryState");
13775        synchronized (this) {
13776            ProcessRecord proc;
13777            synchronized (mPidsSelfLocked) {
13778                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13779            }
13780            fillInProcMemInfo(proc, outInfo);
13781        }
13782    }
13783
13784    @Override
13785    public int getMemoryTrimLevel() {
13786        enforceNotIsolatedCaller("getMyMemoryState");
13787        synchronized (this) {
13788            return mLastMemoryLevel;
13789        }
13790    }
13791
13792    @Override
13793    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13794            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13795        (new ActivityManagerShellCommand(this, false)).exec(
13796                this, in, out, err, args, resultReceiver);
13797    }
13798
13799    @Override
13800    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13801        if (checkCallingPermission(android.Manifest.permission.DUMP)
13802                != PackageManager.PERMISSION_GRANTED) {
13803            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13804                    + Binder.getCallingPid()
13805                    + ", uid=" + Binder.getCallingUid()
13806                    + " without permission "
13807                    + android.Manifest.permission.DUMP);
13808            return;
13809        }
13810
13811        boolean dumpAll = false;
13812        boolean dumpClient = false;
13813        boolean dumpCheckin = false;
13814        boolean dumpCheckinFormat = false;
13815        String dumpPackage = null;
13816
13817        int opti = 0;
13818        while (opti < args.length) {
13819            String opt = args[opti];
13820            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13821                break;
13822            }
13823            opti++;
13824            if ("-a".equals(opt)) {
13825                dumpAll = true;
13826            } else if ("-c".equals(opt)) {
13827                dumpClient = true;
13828            } else if ("-p".equals(opt)) {
13829                if (opti < args.length) {
13830                    dumpPackage = args[opti];
13831                    opti++;
13832                } else {
13833                    pw.println("Error: -p option requires package argument");
13834                    return;
13835                }
13836                dumpClient = true;
13837            } else if ("--checkin".equals(opt)) {
13838                dumpCheckin = dumpCheckinFormat = true;
13839            } else if ("-C".equals(opt)) {
13840                dumpCheckinFormat = true;
13841            } else if ("-h".equals(opt)) {
13842                ActivityManagerShellCommand.dumpHelp(pw, true);
13843                return;
13844            } else {
13845                pw.println("Unknown argument: " + opt + "; use -h for help");
13846            }
13847        }
13848
13849        long origId = Binder.clearCallingIdentity();
13850        boolean more = false;
13851        // Is the caller requesting to dump a particular piece of data?
13852        if (opti < args.length) {
13853            String cmd = args[opti];
13854            opti++;
13855            if ("activities".equals(cmd) || "a".equals(cmd)) {
13856                synchronized (this) {
13857                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13858                }
13859            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13860                synchronized (this) {
13861                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13862                }
13863            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13864                String[] newArgs;
13865                String name;
13866                if (opti >= args.length) {
13867                    name = null;
13868                    newArgs = EMPTY_STRING_ARRAY;
13869                } else {
13870                    dumpPackage = args[opti];
13871                    opti++;
13872                    newArgs = new String[args.length - opti];
13873                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13874                            args.length - opti);
13875                }
13876                synchronized (this) {
13877                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13878                }
13879            } else if ("broadcast-stats".equals(cmd)) {
13880                String[] newArgs;
13881                String name;
13882                if (opti >= args.length) {
13883                    name = null;
13884                    newArgs = EMPTY_STRING_ARRAY;
13885                } else {
13886                    dumpPackage = args[opti];
13887                    opti++;
13888                    newArgs = new String[args.length - opti];
13889                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13890                            args.length - opti);
13891                }
13892                synchronized (this) {
13893                    if (dumpCheckinFormat) {
13894                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13895                                dumpPackage);
13896                    } else {
13897                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13898                    }
13899                }
13900            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13901                String[] newArgs;
13902                String name;
13903                if (opti >= args.length) {
13904                    name = null;
13905                    newArgs = EMPTY_STRING_ARRAY;
13906                } else {
13907                    dumpPackage = args[opti];
13908                    opti++;
13909                    newArgs = new String[args.length - opti];
13910                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13911                            args.length - opti);
13912                }
13913                synchronized (this) {
13914                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13915                }
13916            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13917                String[] newArgs;
13918                String name;
13919                if (opti >= args.length) {
13920                    name = null;
13921                    newArgs = EMPTY_STRING_ARRAY;
13922                } else {
13923                    dumpPackage = args[opti];
13924                    opti++;
13925                    newArgs = new String[args.length - opti];
13926                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13927                            args.length - opti);
13928                }
13929                synchronized (this) {
13930                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13931                }
13932            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13933                synchronized (this) {
13934                    dumpOomLocked(fd, pw, args, opti, true);
13935                }
13936            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13937                synchronized (this) {
13938                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13939                }
13940            } else if ("provider".equals(cmd)) {
13941                String[] newArgs;
13942                String name;
13943                if (opti >= args.length) {
13944                    name = null;
13945                    newArgs = EMPTY_STRING_ARRAY;
13946                } else {
13947                    name = args[opti];
13948                    opti++;
13949                    newArgs = new String[args.length - opti];
13950                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13951                }
13952                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13953                    pw.println("No providers match: " + name);
13954                    pw.println("Use -h for help.");
13955                }
13956            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13957                synchronized (this) {
13958                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13959                }
13960            } else if ("service".equals(cmd)) {
13961                String[] newArgs;
13962                String name;
13963                if (opti >= args.length) {
13964                    name = null;
13965                    newArgs = EMPTY_STRING_ARRAY;
13966                } else {
13967                    name = args[opti];
13968                    opti++;
13969                    newArgs = new String[args.length - opti];
13970                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13971                            args.length - opti);
13972                }
13973                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13974                    pw.println("No services match: " + name);
13975                    pw.println("Use -h for help.");
13976                }
13977            } else if ("package".equals(cmd)) {
13978                String[] newArgs;
13979                if (opti >= args.length) {
13980                    pw.println("package: no package name specified");
13981                    pw.println("Use -h for help.");
13982                } else {
13983                    dumpPackage = args[opti];
13984                    opti++;
13985                    newArgs = new String[args.length - opti];
13986                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13987                            args.length - opti);
13988                    args = newArgs;
13989                    opti = 0;
13990                    more = true;
13991                }
13992            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13993                synchronized (this) {
13994                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13995                }
13996            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13997                if (dumpClient) {
13998                    ActiveServices.ServiceDumper dumper;
13999                    synchronized (this) {
14000                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14001                                dumpPackage);
14002                    }
14003                    dumper.dumpWithClient();
14004                } else {
14005                    synchronized (this) {
14006                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14007                                dumpPackage).dumpLocked();
14008                    }
14009                }
14010            } else if ("locks".equals(cmd)) {
14011                LockGuard.dump(fd, pw, args);
14012            } else {
14013                // Dumping a single activity?
14014                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14015                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14016                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14017                    if (res < 0) {
14018                        pw.println("Bad activity command, or no activities match: " + cmd);
14019                        pw.println("Use -h for help.");
14020                    }
14021                }
14022            }
14023            if (!more) {
14024                Binder.restoreCallingIdentity(origId);
14025                return;
14026            }
14027        }
14028
14029        // No piece of data specified, dump everything.
14030        if (dumpCheckinFormat) {
14031            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14032        } else if (dumpClient) {
14033            ActiveServices.ServiceDumper sdumper;
14034            synchronized (this) {
14035                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14036                pw.println();
14037                if (dumpAll) {
14038                    pw.println("-------------------------------------------------------------------------------");
14039                }
14040                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14041                pw.println();
14042                if (dumpAll) {
14043                    pw.println("-------------------------------------------------------------------------------");
14044                }
14045                if (dumpAll || dumpPackage != null) {
14046                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14047                    pw.println();
14048                    if (dumpAll) {
14049                        pw.println("-------------------------------------------------------------------------------");
14050                    }
14051                }
14052                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14053                pw.println();
14054                if (dumpAll) {
14055                    pw.println("-------------------------------------------------------------------------------");
14056                }
14057                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14058                pw.println();
14059                if (dumpAll) {
14060                    pw.println("-------------------------------------------------------------------------------");
14061                }
14062                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14063                        dumpPackage);
14064            }
14065            sdumper.dumpWithClient();
14066            pw.println();
14067            synchronized (this) {
14068                if (dumpAll) {
14069                    pw.println("-------------------------------------------------------------------------------");
14070                }
14071                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14072                pw.println();
14073                if (dumpAll) {
14074                    pw.println("-------------------------------------------------------------------------------");
14075                }
14076                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14077                if (mAssociations.size() > 0) {
14078                    pw.println();
14079                    if (dumpAll) {
14080                        pw.println("-------------------------------------------------------------------------------");
14081                    }
14082                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14083                }
14084                pw.println();
14085                if (dumpAll) {
14086                    pw.println("-------------------------------------------------------------------------------");
14087                }
14088                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14089            }
14090
14091        } else {
14092            synchronized (this) {
14093                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14094                pw.println();
14095                if (dumpAll) {
14096                    pw.println("-------------------------------------------------------------------------------");
14097                }
14098                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14099                pw.println();
14100                if (dumpAll) {
14101                    pw.println("-------------------------------------------------------------------------------");
14102                }
14103                if (dumpAll || dumpPackage != null) {
14104                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14105                    pw.println();
14106                    if (dumpAll) {
14107                        pw.println("-------------------------------------------------------------------------------");
14108                    }
14109                }
14110                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14111                pw.println();
14112                if (dumpAll) {
14113                    pw.println("-------------------------------------------------------------------------------");
14114                }
14115                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14116                pw.println();
14117                if (dumpAll) {
14118                    pw.println("-------------------------------------------------------------------------------");
14119                }
14120                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14121                        .dumpLocked();
14122                pw.println();
14123                if (dumpAll) {
14124                    pw.println("-------------------------------------------------------------------------------");
14125                }
14126                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14127                pw.println();
14128                if (dumpAll) {
14129                    pw.println("-------------------------------------------------------------------------------");
14130                }
14131                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14132                if (mAssociations.size() > 0) {
14133                    pw.println();
14134                    if (dumpAll) {
14135                        pw.println("-------------------------------------------------------------------------------");
14136                    }
14137                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14138                }
14139                pw.println();
14140                if (dumpAll) {
14141                    pw.println("-------------------------------------------------------------------------------");
14142                }
14143                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14144            }
14145        }
14146        Binder.restoreCallingIdentity(origId);
14147    }
14148
14149    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14150            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14151        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14152
14153        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14154                dumpPackage);
14155        boolean needSep = printedAnything;
14156
14157        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14158                dumpPackage, needSep, "  mFocusedActivity: ");
14159        if (printed) {
14160            printedAnything = true;
14161            needSep = false;
14162        }
14163
14164        if (dumpPackage == null) {
14165            if (needSep) {
14166                pw.println();
14167            }
14168            needSep = true;
14169            printedAnything = true;
14170            mStackSupervisor.dump(pw, "  ");
14171        }
14172
14173        if (!printedAnything) {
14174            pw.println("  (nothing)");
14175        }
14176    }
14177
14178    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14179            int opti, boolean dumpAll, String dumpPackage) {
14180        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14181
14182        boolean printedAnything = false;
14183
14184        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14185            boolean printedHeader = false;
14186
14187            final int N = mRecentTasks.size();
14188            for (int i=0; i<N; i++) {
14189                TaskRecord tr = mRecentTasks.get(i);
14190                if (dumpPackage != null) {
14191                    if (tr.realActivity == null ||
14192                            !dumpPackage.equals(tr.realActivity)) {
14193                        continue;
14194                    }
14195                }
14196                if (!printedHeader) {
14197                    pw.println("  Recent tasks:");
14198                    printedHeader = true;
14199                    printedAnything = true;
14200                }
14201                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14202                        pw.println(tr);
14203                if (dumpAll) {
14204                    mRecentTasks.get(i).dump(pw, "    ");
14205                }
14206            }
14207        }
14208
14209        if (!printedAnything) {
14210            pw.println("  (nothing)");
14211        }
14212    }
14213
14214    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14215            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14216        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14217
14218        int dumpUid = 0;
14219        if (dumpPackage != null) {
14220            IPackageManager pm = AppGlobals.getPackageManager();
14221            try {
14222                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14223            } catch (RemoteException e) {
14224            }
14225        }
14226
14227        boolean printedAnything = false;
14228
14229        final long now = SystemClock.uptimeMillis();
14230
14231        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14232            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14233                    = mAssociations.valueAt(i1);
14234            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14235                SparseArray<ArrayMap<String, Association>> sourceUids
14236                        = targetComponents.valueAt(i2);
14237                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14238                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14239                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14240                        Association ass = sourceProcesses.valueAt(i4);
14241                        if (dumpPackage != null) {
14242                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14243                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14244                                continue;
14245                            }
14246                        }
14247                        printedAnything = true;
14248                        pw.print("  ");
14249                        pw.print(ass.mTargetProcess);
14250                        pw.print("/");
14251                        UserHandle.formatUid(pw, ass.mTargetUid);
14252                        pw.print(" <- ");
14253                        pw.print(ass.mSourceProcess);
14254                        pw.print("/");
14255                        UserHandle.formatUid(pw, ass.mSourceUid);
14256                        pw.println();
14257                        pw.print("    via ");
14258                        pw.print(ass.mTargetComponent.flattenToShortString());
14259                        pw.println();
14260                        pw.print("    ");
14261                        long dur = ass.mTime;
14262                        if (ass.mNesting > 0) {
14263                            dur += now - ass.mStartTime;
14264                        }
14265                        TimeUtils.formatDuration(dur, pw);
14266                        pw.print(" (");
14267                        pw.print(ass.mCount);
14268                        pw.print(" times)");
14269                        pw.print("  ");
14270                        for (int i=0; i<ass.mStateTimes.length; i++) {
14271                            long amt = ass.mStateTimes[i];
14272                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14273                                amt += now - ass.mLastStateUptime;
14274                            }
14275                            if (amt != 0) {
14276                                pw.print(" ");
14277                                pw.print(ProcessList.makeProcStateString(
14278                                            i + ActivityManager.MIN_PROCESS_STATE));
14279                                pw.print("=");
14280                                TimeUtils.formatDuration(amt, pw);
14281                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14282                                    pw.print("*");
14283                                }
14284                            }
14285                        }
14286                        pw.println();
14287                        if (ass.mNesting > 0) {
14288                            pw.print("    Currently active: ");
14289                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14290                            pw.println();
14291                        }
14292                    }
14293                }
14294            }
14295
14296        }
14297
14298        if (!printedAnything) {
14299            pw.println("  (nothing)");
14300        }
14301    }
14302
14303    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14304            String header, boolean needSep) {
14305        boolean printed = false;
14306        int whichAppId = -1;
14307        if (dumpPackage != null) {
14308            try {
14309                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14310                        dumpPackage, 0);
14311                whichAppId = UserHandle.getAppId(info.uid);
14312            } catch (NameNotFoundException e) {
14313                e.printStackTrace();
14314            }
14315        }
14316        for (int i=0; i<uids.size(); i++) {
14317            UidRecord uidRec = uids.valueAt(i);
14318            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14319                continue;
14320            }
14321            if (!printed) {
14322                printed = true;
14323                if (needSep) {
14324                    pw.println();
14325                }
14326                pw.print("  ");
14327                pw.println(header);
14328                needSep = true;
14329            }
14330            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14331            pw.print(": "); pw.println(uidRec);
14332        }
14333        return printed;
14334    }
14335
14336    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14337            int opti, boolean dumpAll, String dumpPackage) {
14338        boolean needSep = false;
14339        boolean printedAnything = false;
14340        int numPers = 0;
14341
14342        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14343
14344        if (dumpAll) {
14345            final int NP = mProcessNames.getMap().size();
14346            for (int ip=0; ip<NP; ip++) {
14347                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14348                final int NA = procs.size();
14349                for (int ia=0; ia<NA; ia++) {
14350                    ProcessRecord r = procs.valueAt(ia);
14351                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14352                        continue;
14353                    }
14354                    if (!needSep) {
14355                        pw.println("  All known processes:");
14356                        needSep = true;
14357                        printedAnything = true;
14358                    }
14359                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14360                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14361                        pw.print(" "); pw.println(r);
14362                    r.dump(pw, "    ");
14363                    if (r.persistent) {
14364                        numPers++;
14365                    }
14366                }
14367            }
14368        }
14369
14370        if (mIsolatedProcesses.size() > 0) {
14371            boolean printed = false;
14372            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14373                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14374                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14375                    continue;
14376                }
14377                if (!printed) {
14378                    if (needSep) {
14379                        pw.println();
14380                    }
14381                    pw.println("  Isolated process list (sorted by uid):");
14382                    printedAnything = true;
14383                    printed = true;
14384                    needSep = true;
14385                }
14386                pw.println(String.format("%sIsolated #%2d: %s",
14387                        "    ", i, r.toString()));
14388            }
14389        }
14390
14391        if (mActiveUids.size() > 0) {
14392            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14393                printedAnything = needSep = true;
14394            }
14395        }
14396        if (mValidateUids.size() > 0) {
14397            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14398                printedAnything = needSep = true;
14399            }
14400        }
14401
14402        if (mLruProcesses.size() > 0) {
14403            if (needSep) {
14404                pw.println();
14405            }
14406            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14407                    pw.print(" total, non-act at ");
14408                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14409                    pw.print(", non-svc at ");
14410                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14411                    pw.println("):");
14412            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14413            needSep = true;
14414            printedAnything = true;
14415        }
14416
14417        if (dumpAll || dumpPackage != null) {
14418            synchronized (mPidsSelfLocked) {
14419                boolean printed = false;
14420                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14421                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14422                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14423                        continue;
14424                    }
14425                    if (!printed) {
14426                        if (needSep) pw.println();
14427                        needSep = true;
14428                        pw.println("  PID mappings:");
14429                        printed = true;
14430                        printedAnything = true;
14431                    }
14432                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14433                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14434                }
14435            }
14436        }
14437
14438        if (mForegroundProcesses.size() > 0) {
14439            synchronized (mPidsSelfLocked) {
14440                boolean printed = false;
14441                for (int i=0; i<mForegroundProcesses.size(); i++) {
14442                    ProcessRecord r = mPidsSelfLocked.get(
14443                            mForegroundProcesses.valueAt(i).pid);
14444                    if (dumpPackage != null && (r == null
14445                            || !r.pkgList.containsKey(dumpPackage))) {
14446                        continue;
14447                    }
14448                    if (!printed) {
14449                        if (needSep) pw.println();
14450                        needSep = true;
14451                        pw.println("  Foreground Processes:");
14452                        printed = true;
14453                        printedAnything = true;
14454                    }
14455                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14456                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14457                }
14458            }
14459        }
14460
14461        if (mPersistentStartingProcesses.size() > 0) {
14462            if (needSep) pw.println();
14463            needSep = true;
14464            printedAnything = true;
14465            pw.println("  Persisent processes that are starting:");
14466            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14467                    "Starting Norm", "Restarting PERS", dumpPackage);
14468        }
14469
14470        if (mRemovedProcesses.size() > 0) {
14471            if (needSep) pw.println();
14472            needSep = true;
14473            printedAnything = true;
14474            pw.println("  Processes that are being removed:");
14475            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14476                    "Removed Norm", "Removed PERS", dumpPackage);
14477        }
14478
14479        if (mProcessesOnHold.size() > 0) {
14480            if (needSep) pw.println();
14481            needSep = true;
14482            printedAnything = true;
14483            pw.println("  Processes that are on old until the system is ready:");
14484            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14485                    "OnHold Norm", "OnHold PERS", dumpPackage);
14486        }
14487
14488        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14489
14490        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14491        if (needSep) {
14492            printedAnything = true;
14493        }
14494
14495        if (dumpPackage == null) {
14496            pw.println();
14497            needSep = false;
14498            mUserController.dump(pw, dumpAll);
14499        }
14500        if (mHomeProcess != null && (dumpPackage == null
14501                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14502            if (needSep) {
14503                pw.println();
14504                needSep = false;
14505            }
14506            pw.println("  mHomeProcess: " + mHomeProcess);
14507        }
14508        if (mPreviousProcess != null && (dumpPackage == null
14509                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14510            if (needSep) {
14511                pw.println();
14512                needSep = false;
14513            }
14514            pw.println("  mPreviousProcess: " + mPreviousProcess);
14515        }
14516        if (dumpAll) {
14517            StringBuilder sb = new StringBuilder(128);
14518            sb.append("  mPreviousProcessVisibleTime: ");
14519            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14520            pw.println(sb);
14521        }
14522        if (mHeavyWeightProcess != null && (dumpPackage == null
14523                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14524            if (needSep) {
14525                pw.println();
14526                needSep = false;
14527            }
14528            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14529        }
14530        if (dumpPackage == null) {
14531            pw.println("  mConfiguration: " + mConfiguration);
14532        }
14533        if (dumpAll) {
14534            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14535            if (mCompatModePackages.getPackages().size() > 0) {
14536                boolean printed = false;
14537                for (Map.Entry<String, Integer> entry
14538                        : mCompatModePackages.getPackages().entrySet()) {
14539                    String pkg = entry.getKey();
14540                    int mode = entry.getValue();
14541                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14542                        continue;
14543                    }
14544                    if (!printed) {
14545                        pw.println("  mScreenCompatPackages:");
14546                        printed = true;
14547                    }
14548                    pw.print("    "); pw.print(pkg); pw.print(": ");
14549                            pw.print(mode); pw.println();
14550                }
14551            }
14552        }
14553        if (dumpPackage == null) {
14554            pw.println("  mWakefulness="
14555                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14556            pw.println("  mSleepTokens=" + mSleepTokens);
14557            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14558                    + lockScreenShownToString());
14559            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14560            if (mRunningVoice != null) {
14561                pw.println("  mRunningVoice=" + mRunningVoice);
14562                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14563            }
14564        }
14565        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14566                || mOrigWaitForDebugger) {
14567            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14568                    || dumpPackage.equals(mOrigDebugApp)) {
14569                if (needSep) {
14570                    pw.println();
14571                    needSep = false;
14572                }
14573                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14574                        + " mDebugTransient=" + mDebugTransient
14575                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14576            }
14577        }
14578        if (mCurAppTimeTracker != null) {
14579            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14580        }
14581        if (mMemWatchProcesses.getMap().size() > 0) {
14582            pw.println("  Mem watch processes:");
14583            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14584                    = mMemWatchProcesses.getMap();
14585            for (int i=0; i<procs.size(); i++) {
14586                final String proc = procs.keyAt(i);
14587                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14588                for (int j=0; j<uids.size(); j++) {
14589                    if (needSep) {
14590                        pw.println();
14591                        needSep = false;
14592                    }
14593                    StringBuilder sb = new StringBuilder();
14594                    sb.append("    ").append(proc).append('/');
14595                    UserHandle.formatUid(sb, uids.keyAt(j));
14596                    Pair<Long, String> val = uids.valueAt(j);
14597                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14598                    if (val.second != null) {
14599                        sb.append(", report to ").append(val.second);
14600                    }
14601                    pw.println(sb.toString());
14602                }
14603            }
14604            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14605            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14606            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14607                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14608        }
14609        if (mTrackAllocationApp != null) {
14610            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14611                if (needSep) {
14612                    pw.println();
14613                    needSep = false;
14614                }
14615                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14616            }
14617        }
14618        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14619                || mProfileFd != null) {
14620            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14621                if (needSep) {
14622                    pw.println();
14623                    needSep = false;
14624                }
14625                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14626                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14627                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14628                        + mAutoStopProfiler);
14629                pw.println("  mProfileType=" + mProfileType);
14630            }
14631        }
14632        if (mNativeDebuggingApp != null) {
14633            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14634                if (needSep) {
14635                    pw.println();
14636                    needSep = false;
14637                }
14638                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14639            }
14640        }
14641        if (dumpPackage == null) {
14642            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14643                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14644                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14645            }
14646            if (mController != null) {
14647                pw.println("  mController=" + mController
14648                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14649            }
14650            if (dumpAll) {
14651                pw.println("  Total persistent processes: " + numPers);
14652                pw.println("  mProcessesReady=" + mProcessesReady
14653                        + " mSystemReady=" + mSystemReady
14654                        + " mBooted=" + mBooted
14655                        + " mFactoryTest=" + mFactoryTest);
14656                pw.println("  mBooting=" + mBooting
14657                        + " mCallFinishBooting=" + mCallFinishBooting
14658                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14659                pw.print("  mLastPowerCheckRealtime=");
14660                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14661                        pw.println("");
14662                pw.print("  mLastPowerCheckUptime=");
14663                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14664                        pw.println("");
14665                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14666                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14667                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14668                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14669                        + " (" + mLruProcesses.size() + " total)"
14670                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14671                        + " mNumServiceProcs=" + mNumServiceProcs
14672                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14673                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14674                        + " mLastMemoryLevel=" + mLastMemoryLevel
14675                        + " mLastNumProcesses=" + mLastNumProcesses);
14676                long now = SystemClock.uptimeMillis();
14677                pw.print("  mLastIdleTime=");
14678                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14679                        pw.print(" mLowRamSinceLastIdle=");
14680                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14681                        pw.println();
14682            }
14683        }
14684
14685        if (!printedAnything) {
14686            pw.println("  (nothing)");
14687        }
14688    }
14689
14690    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14691            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14692        if (mProcessesToGc.size() > 0) {
14693            boolean printed = false;
14694            long now = SystemClock.uptimeMillis();
14695            for (int i=0; i<mProcessesToGc.size(); i++) {
14696                ProcessRecord proc = mProcessesToGc.get(i);
14697                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14698                    continue;
14699                }
14700                if (!printed) {
14701                    if (needSep) pw.println();
14702                    needSep = true;
14703                    pw.println("  Processes that are waiting to GC:");
14704                    printed = true;
14705                }
14706                pw.print("    Process "); pw.println(proc);
14707                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14708                        pw.print(", last gced=");
14709                        pw.print(now-proc.lastRequestedGc);
14710                        pw.print(" ms ago, last lowMem=");
14711                        pw.print(now-proc.lastLowMemory);
14712                        pw.println(" ms ago");
14713
14714            }
14715        }
14716        return needSep;
14717    }
14718
14719    void printOomLevel(PrintWriter pw, String name, int adj) {
14720        pw.print("    ");
14721        if (adj >= 0) {
14722            pw.print(' ');
14723            if (adj < 10) pw.print(' ');
14724        } else {
14725            if (adj > -10) pw.print(' ');
14726        }
14727        pw.print(adj);
14728        pw.print(": ");
14729        pw.print(name);
14730        pw.print(" (");
14731        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14732        pw.println(")");
14733    }
14734
14735    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14736            int opti, boolean dumpAll) {
14737        boolean needSep = false;
14738
14739        if (mLruProcesses.size() > 0) {
14740            if (needSep) pw.println();
14741            needSep = true;
14742            pw.println("  OOM levels:");
14743            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14744            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14745            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14746            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14747            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14748            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14749            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14750            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14751            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14752            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14753            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14754            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14755            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14756            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14757
14758            if (needSep) pw.println();
14759            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14760                    pw.print(" total, non-act at ");
14761                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14762                    pw.print(", non-svc at ");
14763                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14764                    pw.println("):");
14765            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14766            needSep = true;
14767        }
14768
14769        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14770
14771        pw.println();
14772        pw.println("  mHomeProcess: " + mHomeProcess);
14773        pw.println("  mPreviousProcess: " + mPreviousProcess);
14774        if (mHeavyWeightProcess != null) {
14775            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14776        }
14777
14778        return true;
14779    }
14780
14781    /**
14782     * There are three ways to call this:
14783     *  - no provider specified: dump all the providers
14784     *  - a flattened component name that matched an existing provider was specified as the
14785     *    first arg: dump that one provider
14786     *  - the first arg isn't the flattened component name of an existing provider:
14787     *    dump all providers whose component contains the first arg as a substring
14788     */
14789    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14790            int opti, boolean dumpAll) {
14791        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14792    }
14793
14794    static class ItemMatcher {
14795        ArrayList<ComponentName> components;
14796        ArrayList<String> strings;
14797        ArrayList<Integer> objects;
14798        boolean all;
14799
14800        ItemMatcher() {
14801            all = true;
14802        }
14803
14804        void build(String name) {
14805            ComponentName componentName = ComponentName.unflattenFromString(name);
14806            if (componentName != null) {
14807                if (components == null) {
14808                    components = new ArrayList<ComponentName>();
14809                }
14810                components.add(componentName);
14811                all = false;
14812            } else {
14813                int objectId = 0;
14814                // Not a '/' separated full component name; maybe an object ID?
14815                try {
14816                    objectId = Integer.parseInt(name, 16);
14817                    if (objects == null) {
14818                        objects = new ArrayList<Integer>();
14819                    }
14820                    objects.add(objectId);
14821                    all = false;
14822                } catch (RuntimeException e) {
14823                    // Not an integer; just do string match.
14824                    if (strings == null) {
14825                        strings = new ArrayList<String>();
14826                    }
14827                    strings.add(name);
14828                    all = false;
14829                }
14830            }
14831        }
14832
14833        int build(String[] args, int opti) {
14834            for (; opti<args.length; opti++) {
14835                String name = args[opti];
14836                if ("--".equals(name)) {
14837                    return opti+1;
14838                }
14839                build(name);
14840            }
14841            return opti;
14842        }
14843
14844        boolean match(Object object, ComponentName comp) {
14845            if (all) {
14846                return true;
14847            }
14848            if (components != null) {
14849                for (int i=0; i<components.size(); i++) {
14850                    if (components.get(i).equals(comp)) {
14851                        return true;
14852                    }
14853                }
14854            }
14855            if (objects != null) {
14856                for (int i=0; i<objects.size(); i++) {
14857                    if (System.identityHashCode(object) == objects.get(i)) {
14858                        return true;
14859                    }
14860                }
14861            }
14862            if (strings != null) {
14863                String flat = comp.flattenToString();
14864                for (int i=0; i<strings.size(); i++) {
14865                    if (flat.contains(strings.get(i))) {
14866                        return true;
14867                    }
14868                }
14869            }
14870            return false;
14871        }
14872    }
14873
14874    /**
14875     * There are three things that cmd can be:
14876     *  - a flattened component name that matches an existing activity
14877     *  - the cmd arg isn't the flattened component name of an existing activity:
14878     *    dump all activity whose component contains the cmd as a substring
14879     *  - A hex number of the ActivityRecord object instance.
14880     */
14881    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14882            int opti, boolean dumpAll) {
14883        ArrayList<ActivityRecord> activities;
14884
14885        synchronized (this) {
14886            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14887        }
14888
14889        if (activities.size() <= 0) {
14890            return false;
14891        }
14892
14893        String[] newArgs = new String[args.length - opti];
14894        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14895
14896        TaskRecord lastTask = null;
14897        boolean needSep = false;
14898        for (int i=activities.size()-1; i>=0; i--) {
14899            ActivityRecord r = activities.get(i);
14900            if (needSep) {
14901                pw.println();
14902            }
14903            needSep = true;
14904            synchronized (this) {
14905                if (lastTask != r.task) {
14906                    lastTask = r.task;
14907                    pw.print("TASK "); pw.print(lastTask.affinity);
14908                            pw.print(" id="); pw.println(lastTask.taskId);
14909                    if (dumpAll) {
14910                        lastTask.dump(pw, "  ");
14911                    }
14912                }
14913            }
14914            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14915        }
14916        return true;
14917    }
14918
14919    /**
14920     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14921     * there is a thread associated with the activity.
14922     */
14923    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14924            final ActivityRecord r, String[] args, boolean dumpAll) {
14925        String innerPrefix = prefix + "  ";
14926        synchronized (this) {
14927            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14928                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14929                    pw.print(" pid=");
14930                    if (r.app != null) pw.println(r.app.pid);
14931                    else pw.println("(not running)");
14932            if (dumpAll) {
14933                r.dump(pw, innerPrefix);
14934            }
14935        }
14936        if (r.app != null && r.app.thread != null) {
14937            // flush anything that is already in the PrintWriter since the thread is going
14938            // to write to the file descriptor directly
14939            pw.flush();
14940            try {
14941                TransferPipe tp = new TransferPipe();
14942                try {
14943                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14944                            r.appToken, innerPrefix, args);
14945                    tp.go(fd);
14946                } finally {
14947                    tp.kill();
14948                }
14949            } catch (IOException e) {
14950                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14951            } catch (RemoteException e) {
14952                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14953            }
14954        }
14955    }
14956
14957    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14958            int opti, boolean dumpAll, String dumpPackage) {
14959        boolean needSep = false;
14960        boolean onlyHistory = false;
14961        boolean printedAnything = false;
14962
14963        if ("history".equals(dumpPackage)) {
14964            if (opti < args.length && "-s".equals(args[opti])) {
14965                dumpAll = false;
14966            }
14967            onlyHistory = true;
14968            dumpPackage = null;
14969        }
14970
14971        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14972        if (!onlyHistory && dumpAll) {
14973            if (mRegisteredReceivers.size() > 0) {
14974                boolean printed = false;
14975                Iterator it = mRegisteredReceivers.values().iterator();
14976                while (it.hasNext()) {
14977                    ReceiverList r = (ReceiverList)it.next();
14978                    if (dumpPackage != null && (r.app == null ||
14979                            !dumpPackage.equals(r.app.info.packageName))) {
14980                        continue;
14981                    }
14982                    if (!printed) {
14983                        pw.println("  Registered Receivers:");
14984                        needSep = true;
14985                        printed = true;
14986                        printedAnything = true;
14987                    }
14988                    pw.print("  * "); pw.println(r);
14989                    r.dump(pw, "    ");
14990                }
14991            }
14992
14993            if (mReceiverResolver.dump(pw, needSep ?
14994                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14995                    "    ", dumpPackage, false, false)) {
14996                needSep = true;
14997                printedAnything = true;
14998            }
14999        }
15000
15001        for (BroadcastQueue q : mBroadcastQueues) {
15002            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15003            printedAnything |= needSep;
15004        }
15005
15006        needSep = true;
15007
15008        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15009            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15010                if (needSep) {
15011                    pw.println();
15012                }
15013                needSep = true;
15014                printedAnything = true;
15015                pw.print("  Sticky broadcasts for user ");
15016                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15017                StringBuilder sb = new StringBuilder(128);
15018                for (Map.Entry<String, ArrayList<Intent>> ent
15019                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15020                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15021                    if (dumpAll) {
15022                        pw.println(":");
15023                        ArrayList<Intent> intents = ent.getValue();
15024                        final int N = intents.size();
15025                        for (int i=0; i<N; i++) {
15026                            sb.setLength(0);
15027                            sb.append("    Intent: ");
15028                            intents.get(i).toShortString(sb, false, true, false, false);
15029                            pw.println(sb.toString());
15030                            Bundle bundle = intents.get(i).getExtras();
15031                            if (bundle != null) {
15032                                pw.print("      ");
15033                                pw.println(bundle.toString());
15034                            }
15035                        }
15036                    } else {
15037                        pw.println("");
15038                    }
15039                }
15040            }
15041        }
15042
15043        if (!onlyHistory && dumpAll) {
15044            pw.println();
15045            for (BroadcastQueue queue : mBroadcastQueues) {
15046                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15047                        + queue.mBroadcastsScheduled);
15048            }
15049            pw.println("  mHandler:");
15050            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15051            needSep = true;
15052            printedAnything = true;
15053        }
15054
15055        if (!printedAnything) {
15056            pw.println("  (nothing)");
15057        }
15058    }
15059
15060    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15061            int opti, boolean dumpAll, String dumpPackage) {
15062        if (mCurBroadcastStats == null) {
15063            return;
15064        }
15065
15066        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15067        final long now = SystemClock.elapsedRealtime();
15068        if (mLastBroadcastStats != null) {
15069            pw.print("  Last stats (from ");
15070            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15071            pw.print(" to ");
15072            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15073            pw.print(", ");
15074            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15075                    - mLastBroadcastStats.mStartUptime, pw);
15076            pw.println(" uptime):");
15077            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15078                pw.println("    (nothing)");
15079            }
15080            pw.println();
15081        }
15082        pw.print("  Current stats (from ");
15083        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15084        pw.print(" to now, ");
15085        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15086                - mCurBroadcastStats.mStartUptime, pw);
15087        pw.println(" uptime):");
15088        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15089            pw.println("    (nothing)");
15090        }
15091    }
15092
15093    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15094            int opti, boolean fullCheckin, String dumpPackage) {
15095        if (mCurBroadcastStats == null) {
15096            return;
15097        }
15098
15099        if (mLastBroadcastStats != null) {
15100            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15101            if (fullCheckin) {
15102                mLastBroadcastStats = null;
15103                return;
15104            }
15105        }
15106        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15107        if (fullCheckin) {
15108            mCurBroadcastStats = null;
15109        }
15110    }
15111
15112    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15113            int opti, boolean dumpAll, String dumpPackage) {
15114        boolean needSep;
15115        boolean printedAnything = false;
15116
15117        ItemMatcher matcher = new ItemMatcher();
15118        matcher.build(args, opti);
15119
15120        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15121
15122        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15123        printedAnything |= needSep;
15124
15125        if (mLaunchingProviders.size() > 0) {
15126            boolean printed = false;
15127            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15128                ContentProviderRecord r = mLaunchingProviders.get(i);
15129                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15130                    continue;
15131                }
15132                if (!printed) {
15133                    if (needSep) pw.println();
15134                    needSep = true;
15135                    pw.println("  Launching content providers:");
15136                    printed = true;
15137                    printedAnything = true;
15138                }
15139                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15140                        pw.println(r);
15141            }
15142        }
15143
15144        if (!printedAnything) {
15145            pw.println("  (nothing)");
15146        }
15147    }
15148
15149    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15150            int opti, boolean dumpAll, String dumpPackage) {
15151        boolean needSep = false;
15152        boolean printedAnything = false;
15153
15154        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15155
15156        if (mGrantedUriPermissions.size() > 0) {
15157            boolean printed = false;
15158            int dumpUid = -2;
15159            if (dumpPackage != null) {
15160                try {
15161                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15162                            MATCH_UNINSTALLED_PACKAGES, 0);
15163                } catch (NameNotFoundException e) {
15164                    dumpUid = -1;
15165                }
15166            }
15167            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15168                int uid = mGrantedUriPermissions.keyAt(i);
15169                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15170                    continue;
15171                }
15172                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15173                if (!printed) {
15174                    if (needSep) pw.println();
15175                    needSep = true;
15176                    pw.println("  Granted Uri Permissions:");
15177                    printed = true;
15178                    printedAnything = true;
15179                }
15180                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15181                for (UriPermission perm : perms.values()) {
15182                    pw.print("    "); pw.println(perm);
15183                    if (dumpAll) {
15184                        perm.dump(pw, "      ");
15185                    }
15186                }
15187            }
15188        }
15189
15190        if (!printedAnything) {
15191            pw.println("  (nothing)");
15192        }
15193    }
15194
15195    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15196            int opti, boolean dumpAll, String dumpPackage) {
15197        boolean printed = false;
15198
15199        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15200
15201        if (mIntentSenderRecords.size() > 0) {
15202            Iterator<WeakReference<PendingIntentRecord>> it
15203                    = mIntentSenderRecords.values().iterator();
15204            while (it.hasNext()) {
15205                WeakReference<PendingIntentRecord> ref = it.next();
15206                PendingIntentRecord rec = ref != null ? ref.get(): null;
15207                if (dumpPackage != null && (rec == null
15208                        || !dumpPackage.equals(rec.key.packageName))) {
15209                    continue;
15210                }
15211                printed = true;
15212                if (rec != null) {
15213                    pw.print("  * "); pw.println(rec);
15214                    if (dumpAll) {
15215                        rec.dump(pw, "    ");
15216                    }
15217                } else {
15218                    pw.print("  * "); pw.println(ref);
15219                }
15220            }
15221        }
15222
15223        if (!printed) {
15224            pw.println("  (nothing)");
15225        }
15226    }
15227
15228    private static final int dumpProcessList(PrintWriter pw,
15229            ActivityManagerService service, List list,
15230            String prefix, String normalLabel, String persistentLabel,
15231            String dumpPackage) {
15232        int numPers = 0;
15233        final int N = list.size()-1;
15234        for (int i=N; i>=0; i--) {
15235            ProcessRecord r = (ProcessRecord)list.get(i);
15236            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15237                continue;
15238            }
15239            pw.println(String.format("%s%s #%2d: %s",
15240                    prefix, (r.persistent ? persistentLabel : normalLabel),
15241                    i, r.toString()));
15242            if (r.persistent) {
15243                numPers++;
15244            }
15245        }
15246        return numPers;
15247    }
15248
15249    private static final boolean dumpProcessOomList(PrintWriter pw,
15250            ActivityManagerService service, List<ProcessRecord> origList,
15251            String prefix, String normalLabel, String persistentLabel,
15252            boolean inclDetails, String dumpPackage) {
15253
15254        ArrayList<Pair<ProcessRecord, Integer>> list
15255                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15256        for (int i=0; i<origList.size(); i++) {
15257            ProcessRecord r = origList.get(i);
15258            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15259                continue;
15260            }
15261            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15262        }
15263
15264        if (list.size() <= 0) {
15265            return false;
15266        }
15267
15268        Comparator<Pair<ProcessRecord, Integer>> comparator
15269                = new Comparator<Pair<ProcessRecord, Integer>>() {
15270            @Override
15271            public int compare(Pair<ProcessRecord, Integer> object1,
15272                    Pair<ProcessRecord, Integer> object2) {
15273                if (object1.first.setAdj != object2.first.setAdj) {
15274                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15275                }
15276                if (object1.first.setProcState != object2.first.setProcState) {
15277                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15278                }
15279                if (object1.second.intValue() != object2.second.intValue()) {
15280                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15281                }
15282                return 0;
15283            }
15284        };
15285
15286        Collections.sort(list, comparator);
15287
15288        final long curRealtime = SystemClock.elapsedRealtime();
15289        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15290        final long curUptime = SystemClock.uptimeMillis();
15291        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15292
15293        for (int i=list.size()-1; i>=0; i--) {
15294            ProcessRecord r = list.get(i).first;
15295            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15296            char schedGroup;
15297            switch (r.setSchedGroup) {
15298                case ProcessList.SCHED_GROUP_BACKGROUND:
15299                    schedGroup = 'B';
15300                    break;
15301                case ProcessList.SCHED_GROUP_DEFAULT:
15302                    schedGroup = 'F';
15303                    break;
15304                case ProcessList.SCHED_GROUP_TOP_APP:
15305                    schedGroup = 'T';
15306                    break;
15307                default:
15308                    schedGroup = '?';
15309                    break;
15310            }
15311            char foreground;
15312            if (r.foregroundActivities) {
15313                foreground = 'A';
15314            } else if (r.foregroundServices) {
15315                foreground = 'S';
15316            } else {
15317                foreground = ' ';
15318            }
15319            String procState = ProcessList.makeProcStateString(r.curProcState);
15320            pw.print(prefix);
15321            pw.print(r.persistent ? persistentLabel : normalLabel);
15322            pw.print(" #");
15323            int num = (origList.size()-1)-list.get(i).second;
15324            if (num < 10) pw.print(' ');
15325            pw.print(num);
15326            pw.print(": ");
15327            pw.print(oomAdj);
15328            pw.print(' ');
15329            pw.print(schedGroup);
15330            pw.print('/');
15331            pw.print(foreground);
15332            pw.print('/');
15333            pw.print(procState);
15334            pw.print(" trm:");
15335            if (r.trimMemoryLevel < 10) pw.print(' ');
15336            pw.print(r.trimMemoryLevel);
15337            pw.print(' ');
15338            pw.print(r.toShortString());
15339            pw.print(" (");
15340            pw.print(r.adjType);
15341            pw.println(')');
15342            if (r.adjSource != null || r.adjTarget != null) {
15343                pw.print(prefix);
15344                pw.print("    ");
15345                if (r.adjTarget instanceof ComponentName) {
15346                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15347                } else if (r.adjTarget != null) {
15348                    pw.print(r.adjTarget.toString());
15349                } else {
15350                    pw.print("{null}");
15351                }
15352                pw.print("<=");
15353                if (r.adjSource instanceof ProcessRecord) {
15354                    pw.print("Proc{");
15355                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15356                    pw.println("}");
15357                } else if (r.adjSource != null) {
15358                    pw.println(r.adjSource.toString());
15359                } else {
15360                    pw.println("{null}");
15361                }
15362            }
15363            if (inclDetails) {
15364                pw.print(prefix);
15365                pw.print("    ");
15366                pw.print("oom: max="); pw.print(r.maxAdj);
15367                pw.print(" curRaw="); pw.print(r.curRawAdj);
15368                pw.print(" setRaw="); pw.print(r.setRawAdj);
15369                pw.print(" cur="); pw.print(r.curAdj);
15370                pw.print(" set="); pw.println(r.setAdj);
15371                pw.print(prefix);
15372                pw.print("    ");
15373                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15374                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15375                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15376                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15377                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15378                pw.println();
15379                pw.print(prefix);
15380                pw.print("    ");
15381                pw.print("cached="); pw.print(r.cached);
15382                pw.print(" empty="); pw.print(r.empty);
15383                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15384
15385                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15386                    if (r.lastWakeTime != 0) {
15387                        long wtime;
15388                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15389                        synchronized (stats) {
15390                            wtime = stats.getProcessWakeTime(r.info.uid,
15391                                    r.pid, curRealtime);
15392                        }
15393                        long timeUsed = wtime - r.lastWakeTime;
15394                        pw.print(prefix);
15395                        pw.print("    ");
15396                        pw.print("keep awake over ");
15397                        TimeUtils.formatDuration(realtimeSince, pw);
15398                        pw.print(" used ");
15399                        TimeUtils.formatDuration(timeUsed, pw);
15400                        pw.print(" (");
15401                        pw.print((timeUsed*100)/realtimeSince);
15402                        pw.println("%)");
15403                    }
15404                    if (r.lastCpuTime != 0) {
15405                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15406                        pw.print(prefix);
15407                        pw.print("    ");
15408                        pw.print("run cpu over ");
15409                        TimeUtils.formatDuration(uptimeSince, pw);
15410                        pw.print(" used ");
15411                        TimeUtils.formatDuration(timeUsed, pw);
15412                        pw.print(" (");
15413                        pw.print((timeUsed*100)/uptimeSince);
15414                        pw.println("%)");
15415                    }
15416                }
15417            }
15418        }
15419        return true;
15420    }
15421
15422    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15423            String[] args) {
15424        ArrayList<ProcessRecord> procs;
15425        synchronized (this) {
15426            if (args != null && args.length > start
15427                    && args[start].charAt(0) != '-') {
15428                procs = new ArrayList<ProcessRecord>();
15429                int pid = -1;
15430                try {
15431                    pid = Integer.parseInt(args[start]);
15432                } catch (NumberFormatException e) {
15433                }
15434                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15435                    ProcessRecord proc = mLruProcesses.get(i);
15436                    if (proc.pid == pid) {
15437                        procs.add(proc);
15438                    } else if (allPkgs && proc.pkgList != null
15439                            && proc.pkgList.containsKey(args[start])) {
15440                        procs.add(proc);
15441                    } else if (proc.processName.equals(args[start])) {
15442                        procs.add(proc);
15443                    }
15444                }
15445                if (procs.size() <= 0) {
15446                    return null;
15447                }
15448            } else {
15449                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15450            }
15451        }
15452        return procs;
15453    }
15454
15455    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15456            PrintWriter pw, String[] args) {
15457        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15458        if (procs == null) {
15459            pw.println("No process found for: " + args[0]);
15460            return;
15461        }
15462
15463        long uptime = SystemClock.uptimeMillis();
15464        long realtime = SystemClock.elapsedRealtime();
15465        pw.println("Applications Graphics Acceleration Info:");
15466        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15467
15468        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15469            ProcessRecord r = procs.get(i);
15470            if (r.thread != null) {
15471                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15472                pw.flush();
15473                try {
15474                    TransferPipe tp = new TransferPipe();
15475                    try {
15476                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15477                        tp.go(fd);
15478                    } finally {
15479                        tp.kill();
15480                    }
15481                } catch (IOException e) {
15482                    pw.println("Failure while dumping the app: " + r);
15483                    pw.flush();
15484                } catch (RemoteException e) {
15485                    pw.println("Got a RemoteException while dumping the app " + r);
15486                    pw.flush();
15487                }
15488            }
15489        }
15490    }
15491
15492    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15493        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15494        if (procs == null) {
15495            pw.println("No process found for: " + args[0]);
15496            return;
15497        }
15498
15499        pw.println("Applications Database Info:");
15500
15501        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15502            ProcessRecord r = procs.get(i);
15503            if (r.thread != null) {
15504                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15505                pw.flush();
15506                try {
15507                    TransferPipe tp = new TransferPipe();
15508                    try {
15509                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15510                        tp.go(fd);
15511                    } finally {
15512                        tp.kill();
15513                    }
15514                } catch (IOException e) {
15515                    pw.println("Failure while dumping the app: " + r);
15516                    pw.flush();
15517                } catch (RemoteException e) {
15518                    pw.println("Got a RemoteException while dumping the app " + r);
15519                    pw.flush();
15520                }
15521            }
15522        }
15523    }
15524
15525    final static class MemItem {
15526        final boolean isProc;
15527        final String label;
15528        final String shortLabel;
15529        final long pss;
15530        final long swapPss;
15531        final int id;
15532        final boolean hasActivities;
15533        ArrayList<MemItem> subitems;
15534
15535        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15536                boolean _hasActivities) {
15537            isProc = true;
15538            label = _label;
15539            shortLabel = _shortLabel;
15540            pss = _pss;
15541            swapPss = _swapPss;
15542            id = _id;
15543            hasActivities = _hasActivities;
15544        }
15545
15546        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15547            isProc = false;
15548            label = _label;
15549            shortLabel = _shortLabel;
15550            pss = _pss;
15551            swapPss = _swapPss;
15552            id = _id;
15553            hasActivities = false;
15554        }
15555    }
15556
15557    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15558            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15559        if (sort && !isCompact) {
15560            Collections.sort(items, new Comparator<MemItem>() {
15561                @Override
15562                public int compare(MemItem lhs, MemItem rhs) {
15563                    if (lhs.pss < rhs.pss) {
15564                        return 1;
15565                    } else if (lhs.pss > rhs.pss) {
15566                        return -1;
15567                    }
15568                    return 0;
15569                }
15570            });
15571        }
15572
15573        for (int i=0; i<items.size(); i++) {
15574            MemItem mi = items.get(i);
15575            if (!isCompact) {
15576                if (dumpSwapPss) {
15577                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15578                            mi.label, stringifyKBSize(mi.swapPss));
15579                } else {
15580                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15581                }
15582            } else if (mi.isProc) {
15583                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15584                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15585                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15586                pw.println(mi.hasActivities ? ",a" : ",e");
15587            } else {
15588                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15589                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15590            }
15591            if (mi.subitems != null) {
15592                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15593                        true, isCompact, dumpSwapPss);
15594            }
15595        }
15596    }
15597
15598    // These are in KB.
15599    static final long[] DUMP_MEM_BUCKETS = new long[] {
15600        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15601        120*1024, 160*1024, 200*1024,
15602        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15603        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15604    };
15605
15606    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15607            boolean stackLike) {
15608        int start = label.lastIndexOf('.');
15609        if (start >= 0) start++;
15610        else start = 0;
15611        int end = label.length();
15612        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15613            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15614                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15615                out.append(bucket);
15616                out.append(stackLike ? "MB." : "MB ");
15617                out.append(label, start, end);
15618                return;
15619            }
15620        }
15621        out.append(memKB/1024);
15622        out.append(stackLike ? "MB." : "MB ");
15623        out.append(label, start, end);
15624    }
15625
15626    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15627            ProcessList.NATIVE_ADJ,
15628            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15629            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15630            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15631            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15632            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15633            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15634    };
15635    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15636            "Native",
15637            "System", "Persistent", "Persistent Service", "Foreground",
15638            "Visible", "Perceptible",
15639            "Heavy Weight", "Backup",
15640            "A Services", "Home",
15641            "Previous", "B Services", "Cached"
15642    };
15643    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15644            "native",
15645            "sys", "pers", "persvc", "fore",
15646            "vis", "percept",
15647            "heavy", "backup",
15648            "servicea", "home",
15649            "prev", "serviceb", "cached"
15650    };
15651
15652    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15653            long realtime, boolean isCheckinRequest, boolean isCompact) {
15654        if (isCompact) {
15655            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15656        }
15657        if (isCheckinRequest || isCompact) {
15658            // short checkin version
15659            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15660        } else {
15661            pw.println("Applications Memory Usage (in Kilobytes):");
15662            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15663        }
15664    }
15665
15666    private static final int KSM_SHARED = 0;
15667    private static final int KSM_SHARING = 1;
15668    private static final int KSM_UNSHARED = 2;
15669    private static final int KSM_VOLATILE = 3;
15670
15671    private final long[] getKsmInfo() {
15672        long[] longOut = new long[4];
15673        final int[] SINGLE_LONG_FORMAT = new int[] {
15674            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15675        };
15676        long[] longTmp = new long[1];
15677        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15678                SINGLE_LONG_FORMAT, null, longTmp, null);
15679        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15680        longTmp[0] = 0;
15681        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15682                SINGLE_LONG_FORMAT, null, longTmp, null);
15683        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15684        longTmp[0] = 0;
15685        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15686                SINGLE_LONG_FORMAT, null, longTmp, null);
15687        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15688        longTmp[0] = 0;
15689        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15690                SINGLE_LONG_FORMAT, null, longTmp, null);
15691        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15692        return longOut;
15693    }
15694
15695    private static String stringifySize(long size, int order) {
15696        Locale locale = Locale.US;
15697        switch (order) {
15698            case 1:
15699                return String.format(locale, "%,13d", size);
15700            case 1024:
15701                return String.format(locale, "%,9dK", size / 1024);
15702            case 1024 * 1024:
15703                return String.format(locale, "%,5dM", size / 1024 / 1024);
15704            case 1024 * 1024 * 1024:
15705                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15706            default:
15707                throw new IllegalArgumentException("Invalid size order");
15708        }
15709    }
15710
15711    private static String stringifyKBSize(long size) {
15712        return stringifySize(size * 1024, 1024);
15713    }
15714
15715    // Update this version number in case you change the 'compact' format
15716    private static final int MEMINFO_COMPACT_VERSION = 1;
15717
15718    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15719            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15720        boolean dumpDetails = false;
15721        boolean dumpFullDetails = false;
15722        boolean dumpDalvik = false;
15723        boolean dumpSummaryOnly = false;
15724        boolean dumpUnreachable = false;
15725        boolean oomOnly = false;
15726        boolean isCompact = false;
15727        boolean localOnly = false;
15728        boolean packages = false;
15729        boolean isCheckinRequest = false;
15730        boolean dumpSwapPss = false;
15731
15732        int opti = 0;
15733        while (opti < args.length) {
15734            String opt = args[opti];
15735            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15736                break;
15737            }
15738            opti++;
15739            if ("-a".equals(opt)) {
15740                dumpDetails = true;
15741                dumpFullDetails = true;
15742                dumpDalvik = true;
15743                dumpSwapPss = true;
15744            } else if ("-d".equals(opt)) {
15745                dumpDalvik = true;
15746            } else if ("-c".equals(opt)) {
15747                isCompact = true;
15748            } else if ("-s".equals(opt)) {
15749                dumpDetails = true;
15750                dumpSummaryOnly = true;
15751            } else if ("-S".equals(opt)) {
15752                dumpSwapPss = true;
15753            } else if ("--unreachable".equals(opt)) {
15754                dumpUnreachable = true;
15755            } else if ("--oom".equals(opt)) {
15756                oomOnly = true;
15757            } else if ("--local".equals(opt)) {
15758                localOnly = true;
15759            } else if ("--package".equals(opt)) {
15760                packages = true;
15761            } else if ("--checkin".equals(opt)) {
15762                isCheckinRequest = true;
15763
15764            } else if ("-h".equals(opt)) {
15765                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15766                pw.println("  -a: include all available information for each process.");
15767                pw.println("  -d: include dalvik details.");
15768                pw.println("  -c: dump in a compact machine-parseable representation.");
15769                pw.println("  -s: dump only summary of application memory usage.");
15770                pw.println("  -S: dump also SwapPss.");
15771                pw.println("  --oom: only show processes organized by oom adj.");
15772                pw.println("  --local: only collect details locally, don't call process.");
15773                pw.println("  --package: interpret process arg as package, dumping all");
15774                pw.println("             processes that have loaded that package.");
15775                pw.println("  --checkin: dump data for a checkin");
15776                pw.println("If [process] is specified it can be the name or ");
15777                pw.println("pid of a specific process to dump.");
15778                return;
15779            } else {
15780                pw.println("Unknown argument: " + opt + "; use -h for help");
15781            }
15782        }
15783
15784        long uptime = SystemClock.uptimeMillis();
15785        long realtime = SystemClock.elapsedRealtime();
15786        final long[] tmpLong = new long[1];
15787
15788        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15789        if (procs == null) {
15790            // No Java processes.  Maybe they want to print a native process.
15791            if (args != null && args.length > opti
15792                    && args[opti].charAt(0) != '-') {
15793                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15794                        = new ArrayList<ProcessCpuTracker.Stats>();
15795                updateCpuStatsNow();
15796                int findPid = -1;
15797                try {
15798                    findPid = Integer.parseInt(args[opti]);
15799                } catch (NumberFormatException e) {
15800                }
15801                synchronized (mProcessCpuTracker) {
15802                    final int N = mProcessCpuTracker.countStats();
15803                    for (int i=0; i<N; i++) {
15804                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15805                        if (st.pid == findPid || (st.baseName != null
15806                                && st.baseName.equals(args[opti]))) {
15807                            nativeProcs.add(st);
15808                        }
15809                    }
15810                }
15811                if (nativeProcs.size() > 0) {
15812                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15813                            isCompact);
15814                    Debug.MemoryInfo mi = null;
15815                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15816                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15817                        final int pid = r.pid;
15818                        if (!isCheckinRequest && dumpDetails) {
15819                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15820                        }
15821                        if (mi == null) {
15822                            mi = new Debug.MemoryInfo();
15823                        }
15824                        if (dumpDetails || (!brief && !oomOnly)) {
15825                            Debug.getMemoryInfo(pid, mi);
15826                        } else {
15827                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15828                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15829                        }
15830                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15831                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15832                        if (isCheckinRequest) {
15833                            pw.println();
15834                        }
15835                    }
15836                    return;
15837                }
15838            }
15839            pw.println("No process found for: " + args[opti]);
15840            return;
15841        }
15842
15843        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15844            dumpDetails = true;
15845        }
15846
15847        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15848
15849        String[] innerArgs = new String[args.length-opti];
15850        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15851
15852        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15853        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15854        long nativePss = 0;
15855        long nativeSwapPss = 0;
15856        long dalvikPss = 0;
15857        long dalvikSwapPss = 0;
15858        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15859                EmptyArray.LONG;
15860        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15861                EmptyArray.LONG;
15862        long otherPss = 0;
15863        long otherSwapPss = 0;
15864        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15865        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15866
15867        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15868        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15869        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15870                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15871
15872        long totalPss = 0;
15873        long totalSwapPss = 0;
15874        long cachedPss = 0;
15875        long cachedSwapPss = 0;
15876        boolean hasSwapPss = false;
15877
15878        Debug.MemoryInfo mi = null;
15879        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15880            final ProcessRecord r = procs.get(i);
15881            final IApplicationThread thread;
15882            final int pid;
15883            final int oomAdj;
15884            final boolean hasActivities;
15885            synchronized (this) {
15886                thread = r.thread;
15887                pid = r.pid;
15888                oomAdj = r.getSetAdjWithServices();
15889                hasActivities = r.activities.size() > 0;
15890            }
15891            if (thread != null) {
15892                if (!isCheckinRequest && dumpDetails) {
15893                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15894                }
15895                if (mi == null) {
15896                    mi = new Debug.MemoryInfo();
15897                }
15898                if (dumpDetails || (!brief && !oomOnly)) {
15899                    Debug.getMemoryInfo(pid, mi);
15900                    hasSwapPss = mi.hasSwappedOutPss;
15901                } else {
15902                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15903                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15904                }
15905                if (dumpDetails) {
15906                    if (localOnly) {
15907                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15908                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15909                        if (isCheckinRequest) {
15910                            pw.println();
15911                        }
15912                    } else {
15913                        try {
15914                            pw.flush();
15915                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15916                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15917                        } catch (RemoteException e) {
15918                            if (!isCheckinRequest) {
15919                                pw.println("Got RemoteException!");
15920                                pw.flush();
15921                            }
15922                        }
15923                    }
15924                }
15925
15926                final long myTotalPss = mi.getTotalPss();
15927                final long myTotalUss = mi.getTotalUss();
15928                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15929
15930                synchronized (this) {
15931                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15932                        // Record this for posterity if the process has been stable.
15933                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15934                    }
15935                }
15936
15937                if (!isCheckinRequest && mi != null) {
15938                    totalPss += myTotalPss;
15939                    totalSwapPss += myTotalSwapPss;
15940                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15941                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15942                            myTotalSwapPss, pid, hasActivities);
15943                    procMems.add(pssItem);
15944                    procMemsMap.put(pid, pssItem);
15945
15946                    nativePss += mi.nativePss;
15947                    nativeSwapPss += mi.nativeSwappedOutPss;
15948                    dalvikPss += mi.dalvikPss;
15949                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15950                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15951                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15952                        dalvikSubitemSwapPss[j] +=
15953                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15954                    }
15955                    otherPss += mi.otherPss;
15956                    otherSwapPss += mi.otherSwappedOutPss;
15957                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15958                        long mem = mi.getOtherPss(j);
15959                        miscPss[j] += mem;
15960                        otherPss -= mem;
15961                        mem = mi.getOtherSwappedOutPss(j);
15962                        miscSwapPss[j] += mem;
15963                        otherSwapPss -= mem;
15964                    }
15965
15966                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15967                        cachedPss += myTotalPss;
15968                        cachedSwapPss += myTotalSwapPss;
15969                    }
15970
15971                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15972                        if (oomIndex == (oomPss.length - 1)
15973                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15974                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15975                            oomPss[oomIndex] += myTotalPss;
15976                            oomSwapPss[oomIndex] += myTotalSwapPss;
15977                            if (oomProcs[oomIndex] == null) {
15978                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15979                            }
15980                            oomProcs[oomIndex].add(pssItem);
15981                            break;
15982                        }
15983                    }
15984                }
15985            }
15986        }
15987
15988        long nativeProcTotalPss = 0;
15989
15990        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15991            // If we are showing aggregations, also look for native processes to
15992            // include so that our aggregations are more accurate.
15993            updateCpuStatsNow();
15994            mi = null;
15995            synchronized (mProcessCpuTracker) {
15996                final int N = mProcessCpuTracker.countStats();
15997                for (int i=0; i<N; i++) {
15998                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15999                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16000                        if (mi == null) {
16001                            mi = new Debug.MemoryInfo();
16002                        }
16003                        if (!brief && !oomOnly) {
16004                            Debug.getMemoryInfo(st.pid, mi);
16005                        } else {
16006                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16007                            mi.nativePrivateDirty = (int)tmpLong[0];
16008                        }
16009
16010                        final long myTotalPss = mi.getTotalPss();
16011                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16012                        totalPss += myTotalPss;
16013                        nativeProcTotalPss += myTotalPss;
16014
16015                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16016                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16017                        procMems.add(pssItem);
16018
16019                        nativePss += mi.nativePss;
16020                        nativeSwapPss += mi.nativeSwappedOutPss;
16021                        dalvikPss += mi.dalvikPss;
16022                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16023                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16024                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16025                            dalvikSubitemSwapPss[j] +=
16026                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16027                        }
16028                        otherPss += mi.otherPss;
16029                        otherSwapPss += mi.otherSwappedOutPss;
16030                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16031                            long mem = mi.getOtherPss(j);
16032                            miscPss[j] += mem;
16033                            otherPss -= mem;
16034                            mem = mi.getOtherSwappedOutPss(j);
16035                            miscSwapPss[j] += mem;
16036                            otherSwapPss -= mem;
16037                        }
16038                        oomPss[0] += myTotalPss;
16039                        oomSwapPss[0] += myTotalSwapPss;
16040                        if (oomProcs[0] == null) {
16041                            oomProcs[0] = new ArrayList<MemItem>();
16042                        }
16043                        oomProcs[0].add(pssItem);
16044                    }
16045                }
16046            }
16047
16048            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16049
16050            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16051            final MemItem dalvikItem =
16052                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16053            if (dalvikSubitemPss.length > 0) {
16054                dalvikItem.subitems = new ArrayList<MemItem>();
16055                for (int j=0; j<dalvikSubitemPss.length; j++) {
16056                    final String name = Debug.MemoryInfo.getOtherLabel(
16057                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16058                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16059                                    dalvikSubitemSwapPss[j], j));
16060                }
16061            }
16062            catMems.add(dalvikItem);
16063            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16064            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16065                String label = Debug.MemoryInfo.getOtherLabel(j);
16066                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16067            }
16068
16069            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16070            for (int j=0; j<oomPss.length; j++) {
16071                if (oomPss[j] != 0) {
16072                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16073                            : DUMP_MEM_OOM_LABEL[j];
16074                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16075                            DUMP_MEM_OOM_ADJ[j]);
16076                    item.subitems = oomProcs[j];
16077                    oomMems.add(item);
16078                }
16079            }
16080
16081            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16082            if (!brief && !oomOnly && !isCompact) {
16083                pw.println();
16084                pw.println("Total PSS by process:");
16085                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16086                pw.println();
16087            }
16088            if (!isCompact) {
16089                pw.println("Total PSS by OOM adjustment:");
16090            }
16091            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16092            if (!brief && !oomOnly) {
16093                PrintWriter out = categoryPw != null ? categoryPw : pw;
16094                if (!isCompact) {
16095                    out.println();
16096                    out.println("Total PSS by category:");
16097                }
16098                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16099            }
16100            if (!isCompact) {
16101                pw.println();
16102            }
16103            MemInfoReader memInfo = new MemInfoReader();
16104            memInfo.readMemInfo();
16105            if (nativeProcTotalPss > 0) {
16106                synchronized (this) {
16107                    final long cachedKb = memInfo.getCachedSizeKb();
16108                    final long freeKb = memInfo.getFreeSizeKb();
16109                    final long zramKb = memInfo.getZramTotalSizeKb();
16110                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16111                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16112                            kernelKb*1024, nativeProcTotalPss*1024);
16113                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16114                            nativeProcTotalPss);
16115                }
16116            }
16117            if (!brief) {
16118                if (!isCompact) {
16119                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16120                    pw.print(" (status ");
16121                    switch (mLastMemoryLevel) {
16122                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16123                            pw.println("normal)");
16124                            break;
16125                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16126                            pw.println("moderate)");
16127                            break;
16128                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16129                            pw.println("low)");
16130                            break;
16131                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16132                            pw.println("critical)");
16133                            break;
16134                        default:
16135                            pw.print(mLastMemoryLevel);
16136                            pw.println(")");
16137                            break;
16138                    }
16139                    pw.print(" Free RAM: ");
16140                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16141                            + memInfo.getFreeSizeKb()));
16142                    pw.print(" (");
16143                    pw.print(stringifyKBSize(cachedPss));
16144                    pw.print(" cached pss + ");
16145                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16146                    pw.print(" cached kernel + ");
16147                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16148                    pw.println(" free)");
16149                } else {
16150                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16151                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16152                            + memInfo.getFreeSizeKb()); pw.print(",");
16153                    pw.println(totalPss - cachedPss);
16154                }
16155            }
16156            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16157                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16158                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16159            if (!isCompact) {
16160                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16161                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16162                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16163                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16164                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16165            } else {
16166                pw.print("lostram,"); pw.println(lostRAM);
16167            }
16168            if (!brief) {
16169                if (memInfo.getZramTotalSizeKb() != 0) {
16170                    if (!isCompact) {
16171                        pw.print("     ZRAM: ");
16172                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16173                                pw.print(" physical used for ");
16174                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16175                                        - memInfo.getSwapFreeSizeKb()));
16176                                pw.print(" in swap (");
16177                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16178                                pw.println(" total swap)");
16179                    } else {
16180                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16181                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16182                                pw.println(memInfo.getSwapFreeSizeKb());
16183                    }
16184                }
16185                final long[] ksm = getKsmInfo();
16186                if (!isCompact) {
16187                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16188                            || ksm[KSM_VOLATILE] != 0) {
16189                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16190                                pw.print(" saved from shared ");
16191                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16192                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16193                                pw.print(" unshared; ");
16194                                pw.print(stringifyKBSize(
16195                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16196                    }
16197                    pw.print("   Tuning: ");
16198                    pw.print(ActivityManager.staticGetMemoryClass());
16199                    pw.print(" (large ");
16200                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16201                    pw.print("), oom ");
16202                    pw.print(stringifySize(
16203                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16204                    pw.print(", restore limit ");
16205                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16206                    if (ActivityManager.isLowRamDeviceStatic()) {
16207                        pw.print(" (low-ram)");
16208                    }
16209                    if (ActivityManager.isHighEndGfx()) {
16210                        pw.print(" (high-end-gfx)");
16211                    }
16212                    pw.println();
16213                } else {
16214                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16215                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16216                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16217                    pw.print("tuning,");
16218                    pw.print(ActivityManager.staticGetMemoryClass());
16219                    pw.print(',');
16220                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16221                    pw.print(',');
16222                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16223                    if (ActivityManager.isLowRamDeviceStatic()) {
16224                        pw.print(",low-ram");
16225                    }
16226                    if (ActivityManager.isHighEndGfx()) {
16227                        pw.print(",high-end-gfx");
16228                    }
16229                    pw.println();
16230                }
16231            }
16232        }
16233    }
16234
16235    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16236            long memtrack, String name) {
16237        sb.append("  ");
16238        sb.append(ProcessList.makeOomAdjString(oomAdj));
16239        sb.append(' ');
16240        sb.append(ProcessList.makeProcStateString(procState));
16241        sb.append(' ');
16242        ProcessList.appendRamKb(sb, pss);
16243        sb.append(": ");
16244        sb.append(name);
16245        if (memtrack > 0) {
16246            sb.append(" (");
16247            sb.append(stringifyKBSize(memtrack));
16248            sb.append(" memtrack)");
16249        }
16250    }
16251
16252    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16253        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16254        sb.append(" (pid ");
16255        sb.append(mi.pid);
16256        sb.append(") ");
16257        sb.append(mi.adjType);
16258        sb.append('\n');
16259        if (mi.adjReason != null) {
16260            sb.append("                      ");
16261            sb.append(mi.adjReason);
16262            sb.append('\n');
16263        }
16264    }
16265
16266    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16267        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16268        for (int i=0, N=memInfos.size(); i<N; i++) {
16269            ProcessMemInfo mi = memInfos.get(i);
16270            infoMap.put(mi.pid, mi);
16271        }
16272        updateCpuStatsNow();
16273        long[] memtrackTmp = new long[1];
16274        synchronized (mProcessCpuTracker) {
16275            final int N = mProcessCpuTracker.countStats();
16276            for (int i=0; i<N; i++) {
16277                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16278                if (st.vsize > 0) {
16279                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16280                    if (pss > 0) {
16281                        if (infoMap.indexOfKey(st.pid) < 0) {
16282                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16283                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16284                            mi.pss = pss;
16285                            mi.memtrack = memtrackTmp[0];
16286                            memInfos.add(mi);
16287                        }
16288                    }
16289                }
16290            }
16291        }
16292
16293        long totalPss = 0;
16294        long totalMemtrack = 0;
16295        for (int i=0, N=memInfos.size(); i<N; i++) {
16296            ProcessMemInfo mi = memInfos.get(i);
16297            if (mi.pss == 0) {
16298                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16299                mi.memtrack = memtrackTmp[0];
16300            }
16301            totalPss += mi.pss;
16302            totalMemtrack += mi.memtrack;
16303        }
16304        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16305            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16306                if (lhs.oomAdj != rhs.oomAdj) {
16307                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16308                }
16309                if (lhs.pss != rhs.pss) {
16310                    return lhs.pss < rhs.pss ? 1 : -1;
16311                }
16312                return 0;
16313            }
16314        });
16315
16316        StringBuilder tag = new StringBuilder(128);
16317        StringBuilder stack = new StringBuilder(128);
16318        tag.append("Low on memory -- ");
16319        appendMemBucket(tag, totalPss, "total", false);
16320        appendMemBucket(stack, totalPss, "total", true);
16321
16322        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16323        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16324        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16325
16326        boolean firstLine = true;
16327        int lastOomAdj = Integer.MIN_VALUE;
16328        long extraNativeRam = 0;
16329        long extraNativeMemtrack = 0;
16330        long cachedPss = 0;
16331        for (int i=0, N=memInfos.size(); i<N; i++) {
16332            ProcessMemInfo mi = memInfos.get(i);
16333
16334            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16335                cachedPss += mi.pss;
16336            }
16337
16338            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16339                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16340                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16341                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16342                if (lastOomAdj != mi.oomAdj) {
16343                    lastOomAdj = mi.oomAdj;
16344                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16345                        tag.append(" / ");
16346                    }
16347                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16348                        if (firstLine) {
16349                            stack.append(":");
16350                            firstLine = false;
16351                        }
16352                        stack.append("\n\t at ");
16353                    } else {
16354                        stack.append("$");
16355                    }
16356                } else {
16357                    tag.append(" ");
16358                    stack.append("$");
16359                }
16360                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16361                    appendMemBucket(tag, mi.pss, mi.name, false);
16362                }
16363                appendMemBucket(stack, mi.pss, mi.name, true);
16364                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16365                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16366                    stack.append("(");
16367                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16368                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16369                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16370                            stack.append(":");
16371                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16372                        }
16373                    }
16374                    stack.append(")");
16375                }
16376            }
16377
16378            appendMemInfo(fullNativeBuilder, mi);
16379            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16380                // The short form only has native processes that are >= 512K.
16381                if (mi.pss >= 512) {
16382                    appendMemInfo(shortNativeBuilder, mi);
16383                } else {
16384                    extraNativeRam += mi.pss;
16385                    extraNativeMemtrack += mi.memtrack;
16386                }
16387            } else {
16388                // Short form has all other details, but if we have collected RAM
16389                // from smaller native processes let's dump a summary of that.
16390                if (extraNativeRam > 0) {
16391                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16392                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16393                    shortNativeBuilder.append('\n');
16394                    extraNativeRam = 0;
16395                }
16396                appendMemInfo(fullJavaBuilder, mi);
16397            }
16398        }
16399
16400        fullJavaBuilder.append("           ");
16401        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16402        fullJavaBuilder.append(": TOTAL");
16403        if (totalMemtrack > 0) {
16404            fullJavaBuilder.append(" (");
16405            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16406            fullJavaBuilder.append(" memtrack)");
16407        } else {
16408        }
16409        fullJavaBuilder.append("\n");
16410
16411        MemInfoReader memInfo = new MemInfoReader();
16412        memInfo.readMemInfo();
16413        final long[] infos = memInfo.getRawInfo();
16414
16415        StringBuilder memInfoBuilder = new StringBuilder(1024);
16416        Debug.getMemInfo(infos);
16417        memInfoBuilder.append("  MemInfo: ");
16418        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16419        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16420        memInfoBuilder.append(stringifyKBSize(
16421                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16422        memInfoBuilder.append(stringifyKBSize(
16423                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16424        memInfoBuilder.append(stringifyKBSize(
16425                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16426        memInfoBuilder.append("           ");
16427        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16428        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16429        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16430        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16431        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16432            memInfoBuilder.append("  ZRAM: ");
16433            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16434            memInfoBuilder.append(" RAM, ");
16435            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16436            memInfoBuilder.append(" swap total, ");
16437            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16438            memInfoBuilder.append(" swap free\n");
16439        }
16440        final long[] ksm = getKsmInfo();
16441        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16442                || ksm[KSM_VOLATILE] != 0) {
16443            memInfoBuilder.append("  KSM: ");
16444            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16445            memInfoBuilder.append(" saved from shared ");
16446            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16447            memInfoBuilder.append("\n       ");
16448            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16449            memInfoBuilder.append(" unshared; ");
16450            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16451            memInfoBuilder.append(" volatile\n");
16452        }
16453        memInfoBuilder.append("  Free RAM: ");
16454        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16455                + memInfo.getFreeSizeKb()));
16456        memInfoBuilder.append("\n");
16457        memInfoBuilder.append("  Used RAM: ");
16458        memInfoBuilder.append(stringifyKBSize(
16459                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16460        memInfoBuilder.append("\n");
16461        memInfoBuilder.append("  Lost RAM: ");
16462        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16463                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16464                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16465        memInfoBuilder.append("\n");
16466        Slog.i(TAG, "Low on memory:");
16467        Slog.i(TAG, shortNativeBuilder.toString());
16468        Slog.i(TAG, fullJavaBuilder.toString());
16469        Slog.i(TAG, memInfoBuilder.toString());
16470
16471        StringBuilder dropBuilder = new StringBuilder(1024);
16472        /*
16473        StringWriter oomSw = new StringWriter();
16474        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16475        StringWriter catSw = new StringWriter();
16476        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16477        String[] emptyArgs = new String[] { };
16478        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16479        oomPw.flush();
16480        String oomString = oomSw.toString();
16481        */
16482        dropBuilder.append("Low on memory:");
16483        dropBuilder.append(stack);
16484        dropBuilder.append('\n');
16485        dropBuilder.append(fullNativeBuilder);
16486        dropBuilder.append(fullJavaBuilder);
16487        dropBuilder.append('\n');
16488        dropBuilder.append(memInfoBuilder);
16489        dropBuilder.append('\n');
16490        /*
16491        dropBuilder.append(oomString);
16492        dropBuilder.append('\n');
16493        */
16494        StringWriter catSw = new StringWriter();
16495        synchronized (ActivityManagerService.this) {
16496            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16497            String[] emptyArgs = new String[] { };
16498            catPw.println();
16499            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16500            catPw.println();
16501            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16502                    false, null).dumpLocked();
16503            catPw.println();
16504            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16505            catPw.flush();
16506        }
16507        dropBuilder.append(catSw.toString());
16508        addErrorToDropBox("lowmem", null, "system_server", null,
16509                null, tag.toString(), dropBuilder.toString(), null, null);
16510        //Slog.i(TAG, "Sent to dropbox:");
16511        //Slog.i(TAG, dropBuilder.toString());
16512        synchronized (ActivityManagerService.this) {
16513            long now = SystemClock.uptimeMillis();
16514            if (mLastMemUsageReportTime < now) {
16515                mLastMemUsageReportTime = now;
16516            }
16517        }
16518    }
16519
16520    /**
16521     * Searches array of arguments for the specified string
16522     * @param args array of argument strings
16523     * @param value value to search for
16524     * @return true if the value is contained in the array
16525     */
16526    private static boolean scanArgs(String[] args, String value) {
16527        if (args != null) {
16528            for (String arg : args) {
16529                if (value.equals(arg)) {
16530                    return true;
16531                }
16532            }
16533        }
16534        return false;
16535    }
16536
16537    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16538            ContentProviderRecord cpr, boolean always) {
16539        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16540
16541        if (!inLaunching || always) {
16542            synchronized (cpr) {
16543                cpr.launchingApp = null;
16544                cpr.notifyAll();
16545            }
16546            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16547            String names[] = cpr.info.authority.split(";");
16548            for (int j = 0; j < names.length; j++) {
16549                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16550            }
16551        }
16552
16553        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16554            ContentProviderConnection conn = cpr.connections.get(i);
16555            if (conn.waiting) {
16556                // If this connection is waiting for the provider, then we don't
16557                // need to mess with its process unless we are always removing
16558                // or for some reason the provider is not currently launching.
16559                if (inLaunching && !always) {
16560                    continue;
16561                }
16562            }
16563            ProcessRecord capp = conn.client;
16564            conn.dead = true;
16565            if (conn.stableCount > 0) {
16566                if (!capp.persistent && capp.thread != null
16567                        && capp.pid != 0
16568                        && capp.pid != MY_PID) {
16569                    capp.kill("depends on provider "
16570                            + cpr.name.flattenToShortString()
16571                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16572                }
16573            } else if (capp.thread != null && conn.provider.provider != null) {
16574                try {
16575                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16576                } catch (RemoteException e) {
16577                }
16578                // In the protocol here, we don't expect the client to correctly
16579                // clean up this connection, we'll just remove it.
16580                cpr.connections.remove(i);
16581                if (conn.client.conProviders.remove(conn)) {
16582                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16583                }
16584            }
16585        }
16586
16587        if (inLaunching && always) {
16588            mLaunchingProviders.remove(cpr);
16589        }
16590        return inLaunching;
16591    }
16592
16593    /**
16594     * Main code for cleaning up a process when it has gone away.  This is
16595     * called both as a result of the process dying, or directly when stopping
16596     * a process when running in single process mode.
16597     *
16598     * @return Returns true if the given process has been restarted, so the
16599     * app that was passed in must remain on the process lists.
16600     */
16601    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16602            boolean restarting, boolean allowRestart, int index) {
16603        if (index >= 0) {
16604            removeLruProcessLocked(app);
16605            ProcessList.remove(app.pid);
16606        }
16607
16608        mProcessesToGc.remove(app);
16609        mPendingPssProcesses.remove(app);
16610
16611        // Dismiss any open dialogs.
16612        if (app.crashDialog != null && !app.forceCrashReport) {
16613            app.crashDialog.dismiss();
16614            app.crashDialog = null;
16615        }
16616        if (app.anrDialog != null) {
16617            app.anrDialog.dismiss();
16618            app.anrDialog = null;
16619        }
16620        if (app.waitDialog != null) {
16621            app.waitDialog.dismiss();
16622            app.waitDialog = null;
16623        }
16624
16625        app.crashing = false;
16626        app.notResponding = false;
16627
16628        app.resetPackageList(mProcessStats);
16629        app.unlinkDeathRecipient();
16630        app.makeInactive(mProcessStats);
16631        app.waitingToKill = null;
16632        app.forcingToForeground = null;
16633        updateProcessForegroundLocked(app, false, false);
16634        app.foregroundActivities = false;
16635        app.hasShownUi = false;
16636        app.treatLikeActivity = false;
16637        app.hasAboveClient = false;
16638        app.hasClientActivities = false;
16639
16640        mServices.killServicesLocked(app, allowRestart);
16641
16642        boolean restart = false;
16643
16644        // Remove published content providers.
16645        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16646            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16647            final boolean always = app.bad || !allowRestart;
16648            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16649            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16650                // We left the provider in the launching list, need to
16651                // restart it.
16652                restart = true;
16653            }
16654
16655            cpr.provider = null;
16656            cpr.proc = null;
16657        }
16658        app.pubProviders.clear();
16659
16660        // Take care of any launching providers waiting for this process.
16661        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16662            restart = true;
16663        }
16664
16665        // Unregister from connected content providers.
16666        if (!app.conProviders.isEmpty()) {
16667            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16668                ContentProviderConnection conn = app.conProviders.get(i);
16669                conn.provider.connections.remove(conn);
16670                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16671                        conn.provider.name);
16672            }
16673            app.conProviders.clear();
16674        }
16675
16676        // At this point there may be remaining entries in mLaunchingProviders
16677        // where we were the only one waiting, so they are no longer of use.
16678        // Look for these and clean up if found.
16679        // XXX Commented out for now.  Trying to figure out a way to reproduce
16680        // the actual situation to identify what is actually going on.
16681        if (false) {
16682            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16683                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16684                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16685                    synchronized (cpr) {
16686                        cpr.launchingApp = null;
16687                        cpr.notifyAll();
16688                    }
16689                }
16690            }
16691        }
16692
16693        skipCurrentReceiverLocked(app);
16694
16695        // Unregister any receivers.
16696        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16697            removeReceiverLocked(app.receivers.valueAt(i));
16698        }
16699        app.receivers.clear();
16700
16701        // If the app is undergoing backup, tell the backup manager about it
16702        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16703            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16704                    + mBackupTarget.appInfo + " died during backup");
16705            try {
16706                IBackupManager bm = IBackupManager.Stub.asInterface(
16707                        ServiceManager.getService(Context.BACKUP_SERVICE));
16708                bm.agentDisconnected(app.info.packageName);
16709            } catch (RemoteException e) {
16710                // can't happen; backup manager is local
16711            }
16712        }
16713
16714        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16715            ProcessChangeItem item = mPendingProcessChanges.get(i);
16716            if (item.pid == app.pid) {
16717                mPendingProcessChanges.remove(i);
16718                mAvailProcessChanges.add(item);
16719            }
16720        }
16721        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16722                null).sendToTarget();
16723
16724        // If the caller is restarting this app, then leave it in its
16725        // current lists and let the caller take care of it.
16726        if (restarting) {
16727            return false;
16728        }
16729
16730        if (!app.persistent || app.isolated) {
16731            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16732                    "Removing non-persistent process during cleanup: " + app);
16733            removeProcessNameLocked(app.processName, app.uid);
16734            if (mHeavyWeightProcess == app) {
16735                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16736                        mHeavyWeightProcess.userId, 0));
16737                mHeavyWeightProcess = null;
16738            }
16739        } else if (!app.removed) {
16740            // This app is persistent, so we need to keep its record around.
16741            // If it is not already on the pending app list, add it there
16742            // and start a new process for it.
16743            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16744                mPersistentStartingProcesses.add(app);
16745                restart = true;
16746            }
16747        }
16748        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16749                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16750        mProcessesOnHold.remove(app);
16751
16752        if (app == mHomeProcess) {
16753            mHomeProcess = null;
16754        }
16755        if (app == mPreviousProcess) {
16756            mPreviousProcess = null;
16757        }
16758
16759        if (restart && !app.isolated) {
16760            // We have components that still need to be running in the
16761            // process, so re-launch it.
16762            if (index < 0) {
16763                ProcessList.remove(app.pid);
16764            }
16765            addProcessNameLocked(app);
16766            startProcessLocked(app, "restart", app.processName);
16767            return true;
16768        } else if (app.pid > 0 && app.pid != MY_PID) {
16769            // Goodbye!
16770            boolean removed;
16771            synchronized (mPidsSelfLocked) {
16772                mPidsSelfLocked.remove(app.pid);
16773                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16774            }
16775            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16776            if (app.isolated) {
16777                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16778            }
16779            app.setPid(0);
16780        }
16781        return false;
16782    }
16783
16784    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16785        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16786            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16787            if (cpr.launchingApp == app) {
16788                return true;
16789            }
16790        }
16791        return false;
16792    }
16793
16794    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16795        // Look through the content providers we are waiting to have launched,
16796        // and if any run in this process then either schedule a restart of
16797        // the process or kill the client waiting for it if this process has
16798        // gone bad.
16799        boolean restart = false;
16800        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16801            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16802            if (cpr.launchingApp == app) {
16803                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16804                    restart = true;
16805                } else {
16806                    removeDyingProviderLocked(app, cpr, true);
16807                }
16808            }
16809        }
16810        return restart;
16811    }
16812
16813    // =========================================================
16814    // SERVICES
16815    // =========================================================
16816
16817    @Override
16818    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16819            int flags) {
16820        enforceNotIsolatedCaller("getServices");
16821        synchronized (this) {
16822            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16823        }
16824    }
16825
16826    @Override
16827    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16828        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16829        synchronized (this) {
16830            return mServices.getRunningServiceControlPanelLocked(name);
16831        }
16832    }
16833
16834    @Override
16835    public ComponentName startService(IApplicationThread caller, Intent service,
16836            String resolvedType, String callingPackage, int userId)
16837            throws TransactionTooLargeException {
16838        enforceNotIsolatedCaller("startService");
16839        // Refuse possible leaked file descriptors
16840        if (service != null && service.hasFileDescriptors() == true) {
16841            throw new IllegalArgumentException("File descriptors passed in Intent");
16842        }
16843
16844        if (callingPackage == null) {
16845            throw new IllegalArgumentException("callingPackage cannot be null");
16846        }
16847
16848        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16849                "startService: " + service + " type=" + resolvedType);
16850        synchronized(this) {
16851            final int callingPid = Binder.getCallingPid();
16852            final int callingUid = Binder.getCallingUid();
16853            final long origId = Binder.clearCallingIdentity();
16854            ComponentName res = mServices.startServiceLocked(caller, service,
16855                    resolvedType, callingPid, callingUid, callingPackage, userId);
16856            Binder.restoreCallingIdentity(origId);
16857            return res;
16858        }
16859    }
16860
16861    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16862            String callingPackage, int userId)
16863            throws TransactionTooLargeException {
16864        synchronized(this) {
16865            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16866                    "startServiceInPackage: " + service + " type=" + resolvedType);
16867            final long origId = Binder.clearCallingIdentity();
16868            ComponentName res = mServices.startServiceLocked(null, service,
16869                    resolvedType, -1, uid, callingPackage, userId);
16870            Binder.restoreCallingIdentity(origId);
16871            return res;
16872        }
16873    }
16874
16875    @Override
16876    public int stopService(IApplicationThread caller, Intent service,
16877            String resolvedType, int userId) {
16878        enforceNotIsolatedCaller("stopService");
16879        // Refuse possible leaked file descriptors
16880        if (service != null && service.hasFileDescriptors() == true) {
16881            throw new IllegalArgumentException("File descriptors passed in Intent");
16882        }
16883
16884        synchronized(this) {
16885            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16886        }
16887    }
16888
16889    @Override
16890    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16891        enforceNotIsolatedCaller("peekService");
16892        // Refuse possible leaked file descriptors
16893        if (service != null && service.hasFileDescriptors() == true) {
16894            throw new IllegalArgumentException("File descriptors passed in Intent");
16895        }
16896
16897        if (callingPackage == null) {
16898            throw new IllegalArgumentException("callingPackage cannot be null");
16899        }
16900
16901        synchronized(this) {
16902            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16903        }
16904    }
16905
16906    @Override
16907    public boolean stopServiceToken(ComponentName className, IBinder token,
16908            int startId) {
16909        synchronized(this) {
16910            return mServices.stopServiceTokenLocked(className, token, startId);
16911        }
16912    }
16913
16914    @Override
16915    public void setServiceForeground(ComponentName className, IBinder token,
16916            int id, Notification notification, int flags) {
16917        synchronized(this) {
16918            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16919        }
16920    }
16921
16922    @Override
16923    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16924            boolean requireFull, String name, String callerPackage) {
16925        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16926                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16927    }
16928
16929    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16930            String className, int flags) {
16931        boolean result = false;
16932        // For apps that don't have pre-defined UIDs, check for permission
16933        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16934            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16935                if (ActivityManager.checkUidPermission(
16936                        INTERACT_ACROSS_USERS,
16937                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16938                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16939                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16940                            + " requests FLAG_SINGLE_USER, but app does not hold "
16941                            + INTERACT_ACROSS_USERS;
16942                    Slog.w(TAG, msg);
16943                    throw new SecurityException(msg);
16944                }
16945                // Permission passed
16946                result = true;
16947            }
16948        } else if ("system".equals(componentProcessName)) {
16949            result = true;
16950        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16951            // Phone app and persistent apps are allowed to export singleuser providers.
16952            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16953                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16954        }
16955        if (DEBUG_MU) Slog.v(TAG_MU,
16956                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16957                + Integer.toHexString(flags) + ") = " + result);
16958        return result;
16959    }
16960
16961    /**
16962     * Checks to see if the caller is in the same app as the singleton
16963     * component, or the component is in a special app. It allows special apps
16964     * to export singleton components but prevents exporting singleton
16965     * components for regular apps.
16966     */
16967    boolean isValidSingletonCall(int callingUid, int componentUid) {
16968        int componentAppId = UserHandle.getAppId(componentUid);
16969        return UserHandle.isSameApp(callingUid, componentUid)
16970                || componentAppId == Process.SYSTEM_UID
16971                || componentAppId == Process.PHONE_UID
16972                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16973                        == PackageManager.PERMISSION_GRANTED;
16974    }
16975
16976    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16977            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16978            int userId) throws TransactionTooLargeException {
16979        enforceNotIsolatedCaller("bindService");
16980
16981        // Refuse possible leaked file descriptors
16982        if (service != null && service.hasFileDescriptors() == true) {
16983            throw new IllegalArgumentException("File descriptors passed in Intent");
16984        }
16985
16986        if (callingPackage == null) {
16987            throw new IllegalArgumentException("callingPackage cannot be null");
16988        }
16989
16990        synchronized(this) {
16991            return mServices.bindServiceLocked(caller, token, service,
16992                    resolvedType, connection, flags, callingPackage, userId);
16993        }
16994    }
16995
16996    public boolean unbindService(IServiceConnection connection) {
16997        synchronized (this) {
16998            return mServices.unbindServiceLocked(connection);
16999        }
17000    }
17001
17002    public void publishService(IBinder token, Intent intent, IBinder service) {
17003        // Refuse possible leaked file descriptors
17004        if (intent != null && intent.hasFileDescriptors() == true) {
17005            throw new IllegalArgumentException("File descriptors passed in Intent");
17006        }
17007
17008        synchronized(this) {
17009            if (!(token instanceof ServiceRecord)) {
17010                throw new IllegalArgumentException("Invalid service token");
17011            }
17012            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17013        }
17014    }
17015
17016    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17017        // Refuse possible leaked file descriptors
17018        if (intent != null && intent.hasFileDescriptors() == true) {
17019            throw new IllegalArgumentException("File descriptors passed in Intent");
17020        }
17021
17022        synchronized(this) {
17023            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17024        }
17025    }
17026
17027    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17028        synchronized(this) {
17029            if (!(token instanceof ServiceRecord)) {
17030                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17031                throw new IllegalArgumentException("Invalid service token");
17032            }
17033            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17034        }
17035    }
17036
17037    // =========================================================
17038    // BACKUP AND RESTORE
17039    // =========================================================
17040
17041    // Cause the target app to be launched if necessary and its backup agent
17042    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17043    // activity manager to announce its creation.
17044    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17045        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17046                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17047        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17048
17049        synchronized(this) {
17050            // !!! TODO: currently no check here that we're already bound
17051            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17052            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17053            synchronized (stats) {
17054                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17055            }
17056
17057            // Backup agent is now in use, its package can't be stopped.
17058            try {
17059                AppGlobals.getPackageManager().setPackageStoppedState(
17060                        app.packageName, false, UserHandle.getUserId(app.uid));
17061            } catch (RemoteException e) {
17062            } catch (IllegalArgumentException e) {
17063                Slog.w(TAG, "Failed trying to unstop package "
17064                        + app.packageName + ": " + e);
17065            }
17066
17067            BackupRecord r = new BackupRecord(ss, app, backupMode);
17068            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17069                    ? new ComponentName(app.packageName, app.backupAgentName)
17070                    : new ComponentName("android", "FullBackupAgent");
17071            // startProcessLocked() returns existing proc's record if it's already running
17072            ProcessRecord proc = startProcessLocked(app.processName, app,
17073                    false, 0, "backup", hostingName, false, false, false);
17074            if (proc == null) {
17075                Slog.e(TAG, "Unable to start backup agent process " + r);
17076                return false;
17077            }
17078
17079            // If the app is a regular app (uid >= 10000) and not the system server or phone
17080            // process, etc, then mark it as being in full backup so that certain calls to the
17081            // process can be blocked. This is not reset to false anywhere because we kill the
17082            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17083            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17084                proc.inFullBackup = true;
17085            }
17086            r.app = proc;
17087            mBackupTarget = r;
17088            mBackupAppName = app.packageName;
17089
17090            // Try not to kill the process during backup
17091            updateOomAdjLocked(proc);
17092
17093            // If the process is already attached, schedule the creation of the backup agent now.
17094            // If it is not yet live, this will be done when it attaches to the framework.
17095            if (proc.thread != null) {
17096                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17097                try {
17098                    proc.thread.scheduleCreateBackupAgent(app,
17099                            compatibilityInfoForPackageLocked(app), backupMode);
17100                } catch (RemoteException e) {
17101                    // Will time out on the backup manager side
17102                }
17103            } else {
17104                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17105            }
17106            // Invariants: at this point, the target app process exists and the application
17107            // is either already running or in the process of coming up.  mBackupTarget and
17108            // mBackupAppName describe the app, so that when it binds back to the AM we
17109            // know that it's scheduled for a backup-agent operation.
17110        }
17111
17112        return true;
17113    }
17114
17115    @Override
17116    public void clearPendingBackup() {
17117        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17118        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17119
17120        synchronized (this) {
17121            mBackupTarget = null;
17122            mBackupAppName = null;
17123        }
17124    }
17125
17126    // A backup agent has just come up
17127    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17128        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17129                + " = " + agent);
17130
17131        synchronized(this) {
17132            if (!agentPackageName.equals(mBackupAppName)) {
17133                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17134                return;
17135            }
17136        }
17137
17138        long oldIdent = Binder.clearCallingIdentity();
17139        try {
17140            IBackupManager bm = IBackupManager.Stub.asInterface(
17141                    ServiceManager.getService(Context.BACKUP_SERVICE));
17142            bm.agentConnected(agentPackageName, agent);
17143        } catch (RemoteException e) {
17144            // can't happen; the backup manager service is local
17145        } catch (Exception e) {
17146            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17147            e.printStackTrace();
17148        } finally {
17149            Binder.restoreCallingIdentity(oldIdent);
17150        }
17151    }
17152
17153    // done with this agent
17154    public void unbindBackupAgent(ApplicationInfo appInfo) {
17155        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17156        if (appInfo == null) {
17157            Slog.w(TAG, "unbind backup agent for null app");
17158            return;
17159        }
17160
17161        synchronized(this) {
17162            try {
17163                if (mBackupAppName == null) {
17164                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17165                    return;
17166                }
17167
17168                if (!mBackupAppName.equals(appInfo.packageName)) {
17169                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17170                    return;
17171                }
17172
17173                // Not backing this app up any more; reset its OOM adjustment
17174                final ProcessRecord proc = mBackupTarget.app;
17175                updateOomAdjLocked(proc);
17176
17177                // If the app crashed during backup, 'thread' will be null here
17178                if (proc.thread != null) {
17179                    try {
17180                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17181                                compatibilityInfoForPackageLocked(appInfo));
17182                    } catch (Exception e) {
17183                        Slog.e(TAG, "Exception when unbinding backup agent:");
17184                        e.printStackTrace();
17185                    }
17186                }
17187            } finally {
17188                mBackupTarget = null;
17189                mBackupAppName = null;
17190            }
17191        }
17192    }
17193    // =========================================================
17194    // BROADCASTS
17195    // =========================================================
17196
17197    boolean isPendingBroadcastProcessLocked(int pid) {
17198        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17199                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17200    }
17201
17202    void skipPendingBroadcastLocked(int pid) {
17203            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17204            for (BroadcastQueue queue : mBroadcastQueues) {
17205                queue.skipPendingBroadcastLocked(pid);
17206            }
17207    }
17208
17209    // The app just attached; send any pending broadcasts that it should receive
17210    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17211        boolean didSomething = false;
17212        for (BroadcastQueue queue : mBroadcastQueues) {
17213            didSomething |= queue.sendPendingBroadcastsLocked(app);
17214        }
17215        return didSomething;
17216    }
17217
17218    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17219            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17220        enforceNotIsolatedCaller("registerReceiver");
17221        ArrayList<Intent> stickyIntents = null;
17222        ProcessRecord callerApp = null;
17223        int callingUid;
17224        int callingPid;
17225        synchronized(this) {
17226            if (caller != null) {
17227                callerApp = getRecordForAppLocked(caller);
17228                if (callerApp == null) {
17229                    throw new SecurityException(
17230                            "Unable to find app for caller " + caller
17231                            + " (pid=" + Binder.getCallingPid()
17232                            + ") when registering receiver " + receiver);
17233                }
17234                if (callerApp.info.uid != Process.SYSTEM_UID &&
17235                        !callerApp.pkgList.containsKey(callerPackage) &&
17236                        !"android".equals(callerPackage)) {
17237                    throw new SecurityException("Given caller package " + callerPackage
17238                            + " is not running in process " + callerApp);
17239                }
17240                callingUid = callerApp.info.uid;
17241                callingPid = callerApp.pid;
17242            } else {
17243                callerPackage = null;
17244                callingUid = Binder.getCallingUid();
17245                callingPid = Binder.getCallingPid();
17246            }
17247
17248            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17249                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17250
17251            Iterator<String> actions = filter.actionsIterator();
17252            if (actions == null) {
17253                ArrayList<String> noAction = new ArrayList<String>(1);
17254                noAction.add(null);
17255                actions = noAction.iterator();
17256            }
17257
17258            // Collect stickies of users
17259            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17260            while (actions.hasNext()) {
17261                String action = actions.next();
17262                for (int id : userIds) {
17263                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17264                    if (stickies != null) {
17265                        ArrayList<Intent> intents = stickies.get(action);
17266                        if (intents != null) {
17267                            if (stickyIntents == null) {
17268                                stickyIntents = new ArrayList<Intent>();
17269                            }
17270                            stickyIntents.addAll(intents);
17271                        }
17272                    }
17273                }
17274            }
17275        }
17276
17277        ArrayList<Intent> allSticky = null;
17278        if (stickyIntents != null) {
17279            final ContentResolver resolver = mContext.getContentResolver();
17280            // Look for any matching sticky broadcasts...
17281            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17282                Intent intent = stickyIntents.get(i);
17283                // If intent has scheme "content", it will need to acccess
17284                // provider that needs to lock mProviderMap in ActivityThread
17285                // and also it may need to wait application response, so we
17286                // cannot lock ActivityManagerService here.
17287                if (filter.match(resolver, intent, true, TAG) >= 0) {
17288                    if (allSticky == null) {
17289                        allSticky = new ArrayList<Intent>();
17290                    }
17291                    allSticky.add(intent);
17292                }
17293            }
17294        }
17295
17296        // The first sticky in the list is returned directly back to the client.
17297        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17298        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17299        if (receiver == null) {
17300            return sticky;
17301        }
17302
17303        synchronized (this) {
17304            if (callerApp != null && (callerApp.thread == null
17305                    || callerApp.thread.asBinder() != caller.asBinder())) {
17306                // Original caller already died
17307                return null;
17308            }
17309            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17310            if (rl == null) {
17311                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17312                        userId, receiver);
17313                if (rl.app != null) {
17314                    rl.app.receivers.add(rl);
17315                } else {
17316                    try {
17317                        receiver.asBinder().linkToDeath(rl, 0);
17318                    } catch (RemoteException e) {
17319                        return sticky;
17320                    }
17321                    rl.linkedToDeath = true;
17322                }
17323                mRegisteredReceivers.put(receiver.asBinder(), rl);
17324            } else if (rl.uid != callingUid) {
17325                throw new IllegalArgumentException(
17326                        "Receiver requested to register for uid " + callingUid
17327                        + " was previously registered for uid " + rl.uid);
17328            } else if (rl.pid != callingPid) {
17329                throw new IllegalArgumentException(
17330                        "Receiver requested to register for pid " + callingPid
17331                        + " was previously registered for pid " + rl.pid);
17332            } else if (rl.userId != userId) {
17333                throw new IllegalArgumentException(
17334                        "Receiver requested to register for user " + userId
17335                        + " was previously registered for user " + rl.userId);
17336            }
17337            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17338                    permission, callingUid, userId);
17339            rl.add(bf);
17340            if (!bf.debugCheck()) {
17341                Slog.w(TAG, "==> For Dynamic broadcast");
17342            }
17343            mReceiverResolver.addFilter(bf);
17344
17345            // Enqueue broadcasts for all existing stickies that match
17346            // this filter.
17347            if (allSticky != null) {
17348                ArrayList receivers = new ArrayList();
17349                receivers.add(bf);
17350
17351                final int stickyCount = allSticky.size();
17352                for (int i = 0; i < stickyCount; i++) {
17353                    Intent intent = allSticky.get(i);
17354                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17355                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17356                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17357                            null, 0, null, null, false, true, true, -1);
17358                    queue.enqueueParallelBroadcastLocked(r);
17359                    queue.scheduleBroadcastsLocked();
17360                }
17361            }
17362
17363            return sticky;
17364        }
17365    }
17366
17367    public void unregisterReceiver(IIntentReceiver receiver) {
17368        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17369
17370        final long origId = Binder.clearCallingIdentity();
17371        try {
17372            boolean doTrim = false;
17373
17374            synchronized(this) {
17375                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17376                if (rl != null) {
17377                    final BroadcastRecord r = rl.curBroadcast;
17378                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17379                        final boolean doNext = r.queue.finishReceiverLocked(
17380                                r, r.resultCode, r.resultData, r.resultExtras,
17381                                r.resultAbort, false);
17382                        if (doNext) {
17383                            doTrim = true;
17384                            r.queue.processNextBroadcast(false);
17385                        }
17386                    }
17387
17388                    if (rl.app != null) {
17389                        rl.app.receivers.remove(rl);
17390                    }
17391                    removeReceiverLocked(rl);
17392                    if (rl.linkedToDeath) {
17393                        rl.linkedToDeath = false;
17394                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17395                    }
17396                }
17397            }
17398
17399            // If we actually concluded any broadcasts, we might now be able
17400            // to trim the recipients' apps from our working set
17401            if (doTrim) {
17402                trimApplications();
17403                return;
17404            }
17405
17406        } finally {
17407            Binder.restoreCallingIdentity(origId);
17408        }
17409    }
17410
17411    void removeReceiverLocked(ReceiverList rl) {
17412        mRegisteredReceivers.remove(rl.receiver.asBinder());
17413        for (int i = rl.size() - 1; i >= 0; i--) {
17414            mReceiverResolver.removeFilter(rl.get(i));
17415        }
17416    }
17417
17418    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17419        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17420            ProcessRecord r = mLruProcesses.get(i);
17421            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17422                try {
17423                    r.thread.dispatchPackageBroadcast(cmd, packages);
17424                } catch (RemoteException ex) {
17425                }
17426            }
17427        }
17428    }
17429
17430    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17431            int callingUid, int[] users) {
17432        // TODO: come back and remove this assumption to triage all broadcasts
17433        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17434
17435        List<ResolveInfo> receivers = null;
17436        try {
17437            HashSet<ComponentName> singleUserReceivers = null;
17438            boolean scannedFirstReceivers = false;
17439            for (int user : users) {
17440                // Skip users that have Shell restrictions, with exception of always permitted
17441                // Shell broadcasts
17442                if (callingUid == Process.SHELL_UID
17443                        && mUserController.hasUserRestriction(
17444                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17445                        && !isPermittedShellBroadcast(intent)) {
17446                    continue;
17447                }
17448                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17449                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17450                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17451                    // If this is not the system user, we need to check for
17452                    // any receivers that should be filtered out.
17453                    for (int i=0; i<newReceivers.size(); i++) {
17454                        ResolveInfo ri = newReceivers.get(i);
17455                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17456                            newReceivers.remove(i);
17457                            i--;
17458                        }
17459                    }
17460                }
17461                if (newReceivers != null && newReceivers.size() == 0) {
17462                    newReceivers = null;
17463                }
17464                if (receivers == null) {
17465                    receivers = newReceivers;
17466                } else if (newReceivers != null) {
17467                    // We need to concatenate the additional receivers
17468                    // found with what we have do far.  This would be easy,
17469                    // but we also need to de-dup any receivers that are
17470                    // singleUser.
17471                    if (!scannedFirstReceivers) {
17472                        // Collect any single user receivers we had already retrieved.
17473                        scannedFirstReceivers = true;
17474                        for (int i=0; i<receivers.size(); i++) {
17475                            ResolveInfo ri = receivers.get(i);
17476                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17477                                ComponentName cn = new ComponentName(
17478                                        ri.activityInfo.packageName, ri.activityInfo.name);
17479                                if (singleUserReceivers == null) {
17480                                    singleUserReceivers = new HashSet<ComponentName>();
17481                                }
17482                                singleUserReceivers.add(cn);
17483                            }
17484                        }
17485                    }
17486                    // Add the new results to the existing results, tracking
17487                    // and de-dupping single user receivers.
17488                    for (int i=0; i<newReceivers.size(); i++) {
17489                        ResolveInfo ri = newReceivers.get(i);
17490                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17491                            ComponentName cn = new ComponentName(
17492                                    ri.activityInfo.packageName, ri.activityInfo.name);
17493                            if (singleUserReceivers == null) {
17494                                singleUserReceivers = new HashSet<ComponentName>();
17495                            }
17496                            if (!singleUserReceivers.contains(cn)) {
17497                                singleUserReceivers.add(cn);
17498                                receivers.add(ri);
17499                            }
17500                        } else {
17501                            receivers.add(ri);
17502                        }
17503                    }
17504                }
17505            }
17506        } catch (RemoteException ex) {
17507            // pm is in same process, this will never happen.
17508        }
17509        return receivers;
17510    }
17511
17512    private boolean isPermittedShellBroadcast(Intent intent) {
17513        // remote bugreport should always be allowed to be taken
17514        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17515    }
17516
17517    final int broadcastIntentLocked(ProcessRecord callerApp,
17518            String callerPackage, Intent intent, String resolvedType,
17519            IIntentReceiver resultTo, int resultCode, String resultData,
17520            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17521            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17522        intent = new Intent(intent);
17523
17524        // By default broadcasts do not go to stopped apps.
17525        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17526
17527        // If we have not finished booting, don't allow this to launch new processes.
17528        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17529            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17530        }
17531
17532        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17533                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17534                + " ordered=" + ordered + " userid=" + userId);
17535        if ((resultTo != null) && !ordered) {
17536            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17537        }
17538
17539        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17540                ALLOW_NON_FULL, "broadcast", callerPackage);
17541
17542        // Make sure that the user who is receiving this broadcast is running.
17543        // If not, we will just skip it. Make an exception for shutdown broadcasts
17544        // and upgrade steps.
17545
17546        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17547            if ((callingUid != Process.SYSTEM_UID
17548                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17549                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17550                Slog.w(TAG, "Skipping broadcast of " + intent
17551                        + ": user " + userId + " is stopped");
17552                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17553            }
17554        }
17555
17556        BroadcastOptions brOptions = null;
17557        if (bOptions != null) {
17558            brOptions = new BroadcastOptions(bOptions);
17559            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17560                // See if the caller is allowed to do this.  Note we are checking against
17561                // the actual real caller (not whoever provided the operation as say a
17562                // PendingIntent), because that who is actually supplied the arguments.
17563                if (checkComponentPermission(
17564                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17565                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17566                        != PackageManager.PERMISSION_GRANTED) {
17567                    String msg = "Permission Denial: " + intent.getAction()
17568                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17569                            + ", uid=" + callingUid + ")"
17570                            + " requires "
17571                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17572                    Slog.w(TAG, msg);
17573                    throw new SecurityException(msg);
17574                }
17575            }
17576        }
17577
17578        // Verify that protected broadcasts are only being sent by system code,
17579        // and that system code is only sending protected broadcasts.
17580        final String action = intent.getAction();
17581        final boolean isProtectedBroadcast;
17582        try {
17583            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17584        } catch (RemoteException e) {
17585            Slog.w(TAG, "Remote exception", e);
17586            return ActivityManager.BROADCAST_SUCCESS;
17587        }
17588
17589        final boolean isCallerSystem;
17590        switch (UserHandle.getAppId(callingUid)) {
17591            case Process.ROOT_UID:
17592            case Process.SYSTEM_UID:
17593            case Process.PHONE_UID:
17594            case Process.BLUETOOTH_UID:
17595            case Process.NFC_UID:
17596                isCallerSystem = true;
17597                break;
17598            default:
17599                isCallerSystem = (callerApp != null) && callerApp.persistent;
17600                break;
17601        }
17602
17603        if (isCallerSystem) {
17604            if (isProtectedBroadcast
17605                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17606                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17607                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17608                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17609                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17610                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17611                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17612                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17613                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17614                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17615                // Broadcast is either protected, or it's a public action that
17616                // we've relaxed, so it's fine for system internals to send.
17617            } else {
17618                // The vast majority of broadcasts sent from system internals
17619                // should be protected to avoid security holes, so yell loudly
17620                // to ensure we examine these cases.
17621                if (callerApp != null) {
17622                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17623                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17624                            new Throwable());
17625                } else {
17626                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17627                            + " from system uid " + UserHandle.formatUid(callingUid)
17628                            + " pkg " + callerPackage,
17629                            new Throwable());
17630                }
17631            }
17632
17633        } else {
17634            if (isProtectedBroadcast) {
17635                String msg = "Permission Denial: not allowed to send broadcast "
17636                        + action + " from pid="
17637                        + callingPid + ", uid=" + callingUid;
17638                Slog.w(TAG, msg);
17639                throw new SecurityException(msg);
17640
17641            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17642                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17643                // Special case for compatibility: we don't want apps to send this,
17644                // but historically it has not been protected and apps may be using it
17645                // to poke their own app widget.  So, instead of making it protected,
17646                // just limit it to the caller.
17647                if (callerPackage == null) {
17648                    String msg = "Permission Denial: not allowed to send broadcast "
17649                            + action + " from unknown caller.";
17650                    Slog.w(TAG, msg);
17651                    throw new SecurityException(msg);
17652                } else if (intent.getComponent() != null) {
17653                    // They are good enough to send to an explicit component...  verify
17654                    // it is being sent to the calling app.
17655                    if (!intent.getComponent().getPackageName().equals(
17656                            callerPackage)) {
17657                        String msg = "Permission Denial: not allowed to send broadcast "
17658                                + action + " to "
17659                                + intent.getComponent().getPackageName() + " from "
17660                                + callerPackage;
17661                        Slog.w(TAG, msg);
17662                        throw new SecurityException(msg);
17663                    }
17664                } else {
17665                    // Limit broadcast to their own package.
17666                    intent.setPackage(callerPackage);
17667                }
17668            }
17669        }
17670
17671        if (action != null) {
17672            switch (action) {
17673                case Intent.ACTION_UID_REMOVED:
17674                case Intent.ACTION_PACKAGE_REMOVED:
17675                case Intent.ACTION_PACKAGE_CHANGED:
17676                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17677                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17678                case Intent.ACTION_PACKAGES_SUSPENDED:
17679                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17680                    // Handle special intents: if this broadcast is from the package
17681                    // manager about a package being removed, we need to remove all of
17682                    // its activities from the history stack.
17683                    if (checkComponentPermission(
17684                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17685                            callingPid, callingUid, -1, true)
17686                            != PackageManager.PERMISSION_GRANTED) {
17687                        String msg = "Permission Denial: " + intent.getAction()
17688                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17689                                + ", uid=" + callingUid + ")"
17690                                + " requires "
17691                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17692                        Slog.w(TAG, msg);
17693                        throw new SecurityException(msg);
17694                    }
17695                    switch (action) {
17696                        case Intent.ACTION_UID_REMOVED:
17697                            final Bundle intentExtras = intent.getExtras();
17698                            final int uid = intentExtras != null
17699                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17700                            if (uid >= 0) {
17701                                mBatteryStatsService.removeUid(uid);
17702                                mAppOpsService.uidRemoved(uid);
17703                            }
17704                            break;
17705                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17706                            // If resources are unavailable just force stop all those packages
17707                            // and flush the attribute cache as well.
17708                            String list[] =
17709                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17710                            if (list != null && list.length > 0) {
17711                                for (int i = 0; i < list.length; i++) {
17712                                    forceStopPackageLocked(list[i], -1, false, true, true,
17713                                            false, false, userId, "storage unmount");
17714                                }
17715                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17716                                sendPackageBroadcastLocked(
17717                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17718                                        userId);
17719                            }
17720                            break;
17721                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17722                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17723                            break;
17724                        case Intent.ACTION_PACKAGE_REMOVED:
17725                        case Intent.ACTION_PACKAGE_CHANGED:
17726                            Uri data = intent.getData();
17727                            String ssp;
17728                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17729                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17730                                final boolean replacing =
17731                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17732                                final boolean killProcess =
17733                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17734                                final boolean fullUninstall = removed && !replacing;
17735                                if (removed) {
17736                                    if (killProcess) {
17737                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17738                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17739                                                false, true, true, false, fullUninstall, userId,
17740                                                removed ? "pkg removed" : "pkg changed");
17741                                    }
17742                                    final int cmd = killProcess
17743                                            ? IApplicationThread.PACKAGE_REMOVED
17744                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17745                                    sendPackageBroadcastLocked(cmd,
17746                                            new String[] {ssp}, userId);
17747                                    if (fullUninstall) {
17748                                        mAppOpsService.packageRemoved(
17749                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17750
17751                                        // Remove all permissions granted from/to this package
17752                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17753
17754                                        removeTasksByPackageNameLocked(ssp, userId);
17755                                        mBatteryStatsService.notePackageUninstalled(ssp);
17756                                    }
17757                                } else {
17758                                    if (killProcess) {
17759                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17760                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17761                                                userId, ProcessList.INVALID_ADJ,
17762                                                false, true, true, false, "change " + ssp);
17763                                    }
17764                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17765                                            intent.getStringArrayExtra(
17766                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17767                                }
17768                            }
17769                            break;
17770                        case Intent.ACTION_PACKAGES_SUSPENDED:
17771                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17772                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17773                                    intent.getAction());
17774                            final String[] packageNames = intent.getStringArrayExtra(
17775                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17776                            final int userHandle = intent.getIntExtra(
17777                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17778
17779                            synchronized(ActivityManagerService.this) {
17780                                mRecentTasks.onPackagesSuspendedChanged(
17781                                        packageNames, suspended, userHandle);
17782                            }
17783                            break;
17784                    }
17785                    break;
17786                case Intent.ACTION_PACKAGE_REPLACED:
17787                {
17788                    final Uri data = intent.getData();
17789                    final String ssp;
17790                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17791                        final ApplicationInfo aInfo =
17792                                getPackageManagerInternalLocked().getApplicationInfo(
17793                                        ssp,
17794                                        userId);
17795                        if (aInfo == null) {
17796                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17797                                    + " ssp=" + ssp + " data=" + data);
17798                            return ActivityManager.BROADCAST_SUCCESS;
17799                        }
17800                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17801                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17802                                new String[] {ssp}, userId);
17803                    }
17804                    break;
17805                }
17806                case Intent.ACTION_PACKAGE_ADDED:
17807                {
17808                    // Special case for adding a package: by default turn on compatibility mode.
17809                    Uri data = intent.getData();
17810                    String ssp;
17811                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17812                        final boolean replacing =
17813                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17814                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17815
17816                        try {
17817                            ApplicationInfo ai = AppGlobals.getPackageManager().
17818                                    getApplicationInfo(ssp, 0, 0);
17819                            mBatteryStatsService.notePackageInstalled(ssp,
17820                                    ai != null ? ai.versionCode : 0);
17821                        } catch (RemoteException e) {
17822                        }
17823                    }
17824                    break;
17825                }
17826                case Intent.ACTION_TIMEZONE_CHANGED:
17827                    // If this is the time zone changed action, queue up a message that will reset
17828                    // the timezone of all currently running processes. This message will get
17829                    // queued up before the broadcast happens.
17830                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17831                    break;
17832                case Intent.ACTION_TIME_CHANGED:
17833                    // If the user set the time, let all running processes know.
17834                    final int is24Hour =
17835                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17836                                    : 0;
17837                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17838                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17839                    synchronized (stats) {
17840                        stats.noteCurrentTimeChangedLocked();
17841                    }
17842                    break;
17843                case Intent.ACTION_CLEAR_DNS_CACHE:
17844                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17845                    break;
17846                case Proxy.PROXY_CHANGE_ACTION:
17847                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17848                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17849                    break;
17850                case android.hardware.Camera.ACTION_NEW_PICTURE:
17851                case android.hardware.Camera.ACTION_NEW_VIDEO:
17852                    // These broadcasts are no longer allowed by the system, since they can
17853                    // cause significant thrashing at a crictical point (using the camera).
17854                    // Apps should use JobScehduler to monitor for media provider changes.
17855                    Slog.w(TAG, action + " no longer allowed; dropping from "
17856                            + UserHandle.formatUid(callingUid));
17857                    // Lie; we don't want to crash the app.
17858                    return ActivityManager.BROADCAST_SUCCESS;
17859            }
17860        }
17861
17862        // Add to the sticky list if requested.
17863        if (sticky) {
17864            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17865                    callingPid, callingUid)
17866                    != PackageManager.PERMISSION_GRANTED) {
17867                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17868                        + callingPid + ", uid=" + callingUid
17869                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17870                Slog.w(TAG, msg);
17871                throw new SecurityException(msg);
17872            }
17873            if (requiredPermissions != null && requiredPermissions.length > 0) {
17874                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17875                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17876                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17877            }
17878            if (intent.getComponent() != null) {
17879                throw new SecurityException(
17880                        "Sticky broadcasts can't target a specific component");
17881            }
17882            // We use userId directly here, since the "all" target is maintained
17883            // as a separate set of sticky broadcasts.
17884            if (userId != UserHandle.USER_ALL) {
17885                // But first, if this is not a broadcast to all users, then
17886                // make sure it doesn't conflict with an existing broadcast to
17887                // all users.
17888                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17889                        UserHandle.USER_ALL);
17890                if (stickies != null) {
17891                    ArrayList<Intent> list = stickies.get(intent.getAction());
17892                    if (list != null) {
17893                        int N = list.size();
17894                        int i;
17895                        for (i=0; i<N; i++) {
17896                            if (intent.filterEquals(list.get(i))) {
17897                                throw new IllegalArgumentException(
17898                                        "Sticky broadcast " + intent + " for user "
17899                                        + userId + " conflicts with existing global broadcast");
17900                            }
17901                        }
17902                    }
17903                }
17904            }
17905            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17906            if (stickies == null) {
17907                stickies = new ArrayMap<>();
17908                mStickyBroadcasts.put(userId, stickies);
17909            }
17910            ArrayList<Intent> list = stickies.get(intent.getAction());
17911            if (list == null) {
17912                list = new ArrayList<>();
17913                stickies.put(intent.getAction(), list);
17914            }
17915            final int stickiesCount = list.size();
17916            int i;
17917            for (i = 0; i < stickiesCount; i++) {
17918                if (intent.filterEquals(list.get(i))) {
17919                    // This sticky already exists, replace it.
17920                    list.set(i, new Intent(intent));
17921                    break;
17922                }
17923            }
17924            if (i >= stickiesCount) {
17925                list.add(new Intent(intent));
17926            }
17927        }
17928
17929        int[] users;
17930        if (userId == UserHandle.USER_ALL) {
17931            // Caller wants broadcast to go to all started users.
17932            users = mUserController.getStartedUserArrayLocked();
17933        } else {
17934            // Caller wants broadcast to go to one specific user.
17935            users = new int[] {userId};
17936        }
17937
17938        // Figure out who all will receive this broadcast.
17939        List receivers = null;
17940        List<BroadcastFilter> registeredReceivers = null;
17941        // Need to resolve the intent to interested receivers...
17942        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17943                 == 0) {
17944            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17945        }
17946        if (intent.getComponent() == null) {
17947            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17948                // Query one target user at a time, excluding shell-restricted users
17949                for (int i = 0; i < users.length; i++) {
17950                    if (mUserController.hasUserRestriction(
17951                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17952                        continue;
17953                    }
17954                    List<BroadcastFilter> registeredReceiversForUser =
17955                            mReceiverResolver.queryIntent(intent,
17956                                    resolvedType, false, users[i]);
17957                    if (registeredReceivers == null) {
17958                        registeredReceivers = registeredReceiversForUser;
17959                    } else if (registeredReceiversForUser != null) {
17960                        registeredReceivers.addAll(registeredReceiversForUser);
17961                    }
17962                }
17963            } else {
17964                registeredReceivers = mReceiverResolver.queryIntent(intent,
17965                        resolvedType, false, userId);
17966            }
17967        }
17968
17969        final boolean replacePending =
17970                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17971
17972        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17973                + " replacePending=" + replacePending);
17974
17975        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17976        if (!ordered && NR > 0) {
17977            // If we are not serializing this broadcast, then send the
17978            // registered receivers separately so they don't wait for the
17979            // components to be launched.
17980            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17981            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17982                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17983                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17984                    resultExtras, ordered, sticky, false, userId);
17985            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17986            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17987            if (!replaced) {
17988                queue.enqueueParallelBroadcastLocked(r);
17989                queue.scheduleBroadcastsLocked();
17990            }
17991            registeredReceivers = null;
17992            NR = 0;
17993        }
17994
17995        // Merge into one list.
17996        int ir = 0;
17997        if (receivers != null) {
17998            // A special case for PACKAGE_ADDED: do not allow the package
17999            // being added to see this broadcast.  This prevents them from
18000            // using this as a back door to get run as soon as they are
18001            // installed.  Maybe in the future we want to have a special install
18002            // broadcast or such for apps, but we'd like to deliberately make
18003            // this decision.
18004            String skipPackages[] = null;
18005            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18006                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18007                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18008                Uri data = intent.getData();
18009                if (data != null) {
18010                    String pkgName = data.getSchemeSpecificPart();
18011                    if (pkgName != null) {
18012                        skipPackages = new String[] { pkgName };
18013                    }
18014                }
18015            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18016                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18017            }
18018            if (skipPackages != null && (skipPackages.length > 0)) {
18019                for (String skipPackage : skipPackages) {
18020                    if (skipPackage != null) {
18021                        int NT = receivers.size();
18022                        for (int it=0; it<NT; it++) {
18023                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18024                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18025                                receivers.remove(it);
18026                                it--;
18027                                NT--;
18028                            }
18029                        }
18030                    }
18031                }
18032            }
18033
18034            int NT = receivers != null ? receivers.size() : 0;
18035            int it = 0;
18036            ResolveInfo curt = null;
18037            BroadcastFilter curr = null;
18038            while (it < NT && ir < NR) {
18039                if (curt == null) {
18040                    curt = (ResolveInfo)receivers.get(it);
18041                }
18042                if (curr == null) {
18043                    curr = registeredReceivers.get(ir);
18044                }
18045                if (curr.getPriority() >= curt.priority) {
18046                    // Insert this broadcast record into the final list.
18047                    receivers.add(it, curr);
18048                    ir++;
18049                    curr = null;
18050                    it++;
18051                    NT++;
18052                } else {
18053                    // Skip to the next ResolveInfo in the final list.
18054                    it++;
18055                    curt = null;
18056                }
18057            }
18058        }
18059        while (ir < NR) {
18060            if (receivers == null) {
18061                receivers = new ArrayList();
18062            }
18063            receivers.add(registeredReceivers.get(ir));
18064            ir++;
18065        }
18066
18067        if ((receivers != null && receivers.size() > 0)
18068                || resultTo != null) {
18069            BroadcastQueue queue = broadcastQueueForIntent(intent);
18070            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18071                    callerPackage, callingPid, callingUid, resolvedType,
18072                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18073                    resultData, resultExtras, ordered, sticky, false, userId);
18074
18075            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18076                    + ": prev had " + queue.mOrderedBroadcasts.size());
18077            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18078                    "Enqueueing broadcast " + r.intent.getAction());
18079
18080            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18081            if (!replaced) {
18082                queue.enqueueOrderedBroadcastLocked(r);
18083                queue.scheduleBroadcastsLocked();
18084            }
18085        } else {
18086            // There was nobody interested in the broadcast, but we still want to record
18087            // that it happened.
18088            if (intent.getComponent() == null && intent.getPackage() == null
18089                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18090                // This was an implicit broadcast... let's record it for posterity.
18091                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18092            }
18093        }
18094
18095        return ActivityManager.BROADCAST_SUCCESS;
18096    }
18097
18098    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18099            int skipCount, long dispatchTime) {
18100        final long now = SystemClock.elapsedRealtime();
18101        if (mCurBroadcastStats == null ||
18102                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18103            mLastBroadcastStats = mCurBroadcastStats;
18104            if (mLastBroadcastStats != null) {
18105                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18106                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18107            }
18108            mCurBroadcastStats = new BroadcastStats();
18109        }
18110        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18111    }
18112
18113    final Intent verifyBroadcastLocked(Intent intent) {
18114        // Refuse possible leaked file descriptors
18115        if (intent != null && intent.hasFileDescriptors() == true) {
18116            throw new IllegalArgumentException("File descriptors passed in Intent");
18117        }
18118
18119        int flags = intent.getFlags();
18120
18121        if (!mProcessesReady) {
18122            // if the caller really truly claims to know what they're doing, go
18123            // ahead and allow the broadcast without launching any receivers
18124            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18125                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18126            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18127                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18128                        + " before boot completion");
18129                throw new IllegalStateException("Cannot broadcast before boot completed");
18130            }
18131        }
18132
18133        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18134            throw new IllegalArgumentException(
18135                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18136        }
18137
18138        return intent;
18139    }
18140
18141    public final int broadcastIntent(IApplicationThread caller,
18142            Intent intent, String resolvedType, IIntentReceiver resultTo,
18143            int resultCode, String resultData, Bundle resultExtras,
18144            String[] requiredPermissions, int appOp, Bundle bOptions,
18145            boolean serialized, boolean sticky, int userId) {
18146        enforceNotIsolatedCaller("broadcastIntent");
18147        synchronized(this) {
18148            intent = verifyBroadcastLocked(intent);
18149
18150            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18151            final int callingPid = Binder.getCallingPid();
18152            final int callingUid = Binder.getCallingUid();
18153            final long origId = Binder.clearCallingIdentity();
18154            int res = broadcastIntentLocked(callerApp,
18155                    callerApp != null ? callerApp.info.packageName : null,
18156                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18157                    requiredPermissions, appOp, bOptions, serialized, sticky,
18158                    callingPid, callingUid, userId);
18159            Binder.restoreCallingIdentity(origId);
18160            return res;
18161        }
18162    }
18163
18164
18165    int broadcastIntentInPackage(String packageName, int uid,
18166            Intent intent, String resolvedType, IIntentReceiver resultTo,
18167            int resultCode, String resultData, Bundle resultExtras,
18168            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18169            int userId) {
18170        synchronized(this) {
18171            intent = verifyBroadcastLocked(intent);
18172
18173            final long origId = Binder.clearCallingIdentity();
18174            String[] requiredPermissions = requiredPermission == null ? null
18175                    : new String[] {requiredPermission};
18176            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18177                    resultTo, resultCode, resultData, resultExtras,
18178                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18179                    sticky, -1, uid, userId);
18180            Binder.restoreCallingIdentity(origId);
18181            return res;
18182        }
18183    }
18184
18185    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18186        // Refuse possible leaked file descriptors
18187        if (intent != null && intent.hasFileDescriptors() == true) {
18188            throw new IllegalArgumentException("File descriptors passed in Intent");
18189        }
18190
18191        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18192                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18193
18194        synchronized(this) {
18195            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18196                    != PackageManager.PERMISSION_GRANTED) {
18197                String msg = "Permission Denial: unbroadcastIntent() from pid="
18198                        + Binder.getCallingPid()
18199                        + ", uid=" + Binder.getCallingUid()
18200                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18201                Slog.w(TAG, msg);
18202                throw new SecurityException(msg);
18203            }
18204            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18205            if (stickies != null) {
18206                ArrayList<Intent> list = stickies.get(intent.getAction());
18207                if (list != null) {
18208                    int N = list.size();
18209                    int i;
18210                    for (i=0; i<N; i++) {
18211                        if (intent.filterEquals(list.get(i))) {
18212                            list.remove(i);
18213                            break;
18214                        }
18215                    }
18216                    if (list.size() <= 0) {
18217                        stickies.remove(intent.getAction());
18218                    }
18219                }
18220                if (stickies.size() <= 0) {
18221                    mStickyBroadcasts.remove(userId);
18222                }
18223            }
18224        }
18225    }
18226
18227    void backgroundServicesFinishedLocked(int userId) {
18228        for (BroadcastQueue queue : mBroadcastQueues) {
18229            queue.backgroundServicesFinishedLocked(userId);
18230        }
18231    }
18232
18233    public void finishReceiver(IBinder who, int resultCode, String resultData,
18234            Bundle resultExtras, boolean resultAbort, int flags) {
18235        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18236
18237        // Refuse possible leaked file descriptors
18238        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18239            throw new IllegalArgumentException("File descriptors passed in Bundle");
18240        }
18241
18242        final long origId = Binder.clearCallingIdentity();
18243        try {
18244            boolean doNext = false;
18245            BroadcastRecord r;
18246
18247            synchronized(this) {
18248                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18249                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18250                r = queue.getMatchingOrderedReceiver(who);
18251                if (r != null) {
18252                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18253                        resultData, resultExtras, resultAbort, true);
18254                }
18255            }
18256
18257            if (doNext) {
18258                r.queue.processNextBroadcast(false);
18259            }
18260            trimApplications();
18261        } finally {
18262            Binder.restoreCallingIdentity(origId);
18263        }
18264    }
18265
18266    // =========================================================
18267    // INSTRUMENTATION
18268    // =========================================================
18269
18270    public boolean startInstrumentation(ComponentName className,
18271            String profileFile, int flags, Bundle arguments,
18272            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18273            int userId, String abiOverride) {
18274        enforceNotIsolatedCaller("startInstrumentation");
18275        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18276                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18277        // Refuse possible leaked file descriptors
18278        if (arguments != null && arguments.hasFileDescriptors()) {
18279            throw new IllegalArgumentException("File descriptors passed in Bundle");
18280        }
18281
18282        synchronized(this) {
18283            InstrumentationInfo ii = null;
18284            ApplicationInfo ai = null;
18285            try {
18286                ii = mContext.getPackageManager().getInstrumentationInfo(
18287                    className, STOCK_PM_FLAGS);
18288                ai = AppGlobals.getPackageManager().getApplicationInfo(
18289                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18290            } catch (PackageManager.NameNotFoundException e) {
18291            } catch (RemoteException e) {
18292            }
18293            if (ii == null) {
18294                reportStartInstrumentationFailureLocked(watcher, className,
18295                        "Unable to find instrumentation info for: " + className);
18296                return false;
18297            }
18298            if (ai == null) {
18299                reportStartInstrumentationFailureLocked(watcher, className,
18300                        "Unable to find instrumentation target package: " + ii.targetPackage);
18301                return false;
18302            }
18303            if (!ai.hasCode()) {
18304                reportStartInstrumentationFailureLocked(watcher, className,
18305                        "Instrumentation target has no code: " + ii.targetPackage);
18306                return false;
18307            }
18308
18309            int match = mContext.getPackageManager().checkSignatures(
18310                    ii.targetPackage, ii.packageName);
18311            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18312                String msg = "Permission Denial: starting instrumentation "
18313                        + className + " from pid="
18314                        + Binder.getCallingPid()
18315                        + ", uid=" + Binder.getCallingPid()
18316                        + " not allowed because package " + ii.packageName
18317                        + " does not have a signature matching the target "
18318                        + ii.targetPackage;
18319                reportStartInstrumentationFailureLocked(watcher, className, msg);
18320                throw new SecurityException(msg);
18321            }
18322
18323            final long origId = Binder.clearCallingIdentity();
18324            // Instrumentation can kill and relaunch even persistent processes
18325            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18326                    "start instr");
18327            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18328            app.instrumentationClass = className;
18329            app.instrumentationInfo = ai;
18330            app.instrumentationProfileFile = profileFile;
18331            app.instrumentationArguments = arguments;
18332            app.instrumentationWatcher = watcher;
18333            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18334            app.instrumentationResultClass = className;
18335            Binder.restoreCallingIdentity(origId);
18336        }
18337
18338        return true;
18339    }
18340
18341    /**
18342     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18343     * error to the logs, but if somebody is watching, send the report there too.  This enables
18344     * the "am" command to report errors with more information.
18345     *
18346     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18347     * @param cn The component name of the instrumentation.
18348     * @param report The error report.
18349     */
18350    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18351            ComponentName cn, String report) {
18352        Slog.w(TAG, report);
18353        if (watcher != null) {
18354            Bundle results = new Bundle();
18355            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18356            results.putString("Error", report);
18357            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18358        }
18359    }
18360
18361    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18362        if (app.instrumentationWatcher != null) {
18363            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18364                    app.instrumentationClass, resultCode, results);
18365        }
18366
18367        // Can't call out of the system process with a lock held, so post a message.
18368        if (app.instrumentationUiAutomationConnection != null) {
18369            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18370                    app.instrumentationUiAutomationConnection).sendToTarget();
18371        }
18372
18373        app.instrumentationWatcher = null;
18374        app.instrumentationUiAutomationConnection = null;
18375        app.instrumentationClass = null;
18376        app.instrumentationInfo = null;
18377        app.instrumentationProfileFile = null;
18378        app.instrumentationArguments = null;
18379
18380        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18381                "finished inst");
18382    }
18383
18384    public void finishInstrumentation(IApplicationThread target,
18385            int resultCode, Bundle results) {
18386        int userId = UserHandle.getCallingUserId();
18387        // Refuse possible leaked file descriptors
18388        if (results != null && results.hasFileDescriptors()) {
18389            throw new IllegalArgumentException("File descriptors passed in Intent");
18390        }
18391
18392        synchronized(this) {
18393            ProcessRecord app = getRecordForAppLocked(target);
18394            if (app == null) {
18395                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18396                return;
18397            }
18398            final long origId = Binder.clearCallingIdentity();
18399            finishInstrumentationLocked(app, resultCode, results);
18400            Binder.restoreCallingIdentity(origId);
18401        }
18402    }
18403
18404    // =========================================================
18405    // CONFIGURATION
18406    // =========================================================
18407
18408    public ConfigurationInfo getDeviceConfigurationInfo() {
18409        ConfigurationInfo config = new ConfigurationInfo();
18410        synchronized (this) {
18411            config.reqTouchScreen = mConfiguration.touchscreen;
18412            config.reqKeyboardType = mConfiguration.keyboard;
18413            config.reqNavigation = mConfiguration.navigation;
18414            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18415                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18416                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18417            }
18418            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18419                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18420                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18421            }
18422            config.reqGlEsVersion = GL_ES_VERSION;
18423        }
18424        return config;
18425    }
18426
18427    ActivityStack getFocusedStack() {
18428        return mStackSupervisor.getFocusedStack();
18429    }
18430
18431    @Override
18432    public int getFocusedStackId() throws RemoteException {
18433        ActivityStack focusedStack = getFocusedStack();
18434        if (focusedStack != null) {
18435            return focusedStack.getStackId();
18436        }
18437        return -1;
18438    }
18439
18440    public Configuration getConfiguration() {
18441        Configuration ci;
18442        synchronized(this) {
18443            ci = new Configuration(mConfiguration);
18444            ci.userSetLocale = false;
18445        }
18446        return ci;
18447    }
18448
18449    @Override
18450    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18451        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18452        synchronized (this) {
18453            mSuppressResizeConfigChanges = suppress;
18454        }
18455    }
18456
18457    @Override
18458    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18459        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18460        if (fromStackId == HOME_STACK_ID) {
18461            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18462        }
18463        synchronized (this) {
18464            final long origId = Binder.clearCallingIdentity();
18465            try {
18466                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18467            } finally {
18468                Binder.restoreCallingIdentity(origId);
18469            }
18470        }
18471    }
18472
18473    @Override
18474    public void updatePersistentConfiguration(Configuration values) {
18475        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18476                "updateConfiguration()");
18477        enforceWriteSettingsPermission("updateConfiguration()");
18478        if (values == null) {
18479            throw new NullPointerException("Configuration must not be null");
18480        }
18481
18482        int userId = UserHandle.getCallingUserId();
18483
18484        synchronized(this) {
18485            final long origId = Binder.clearCallingIdentity();
18486            updateConfigurationLocked(values, null, false, true, userId);
18487            Binder.restoreCallingIdentity(origId);
18488        }
18489    }
18490
18491    private void updateFontScaleIfNeeded() {
18492        final int currentUserId;
18493        synchronized(this) {
18494            currentUserId = mUserController.getCurrentUserIdLocked();
18495        }
18496        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18497                FONT_SCALE, 1.0f, currentUserId);
18498        if (mConfiguration.fontScale != scaleFactor) {
18499            final Configuration configuration = mWindowManager.computeNewConfiguration();
18500            configuration.fontScale = scaleFactor;
18501            updatePersistentConfiguration(configuration);
18502        }
18503    }
18504
18505    private void enforceWriteSettingsPermission(String func) {
18506        int uid = Binder.getCallingUid();
18507        if (uid == Process.ROOT_UID) {
18508            return;
18509        }
18510
18511        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18512                Settings.getPackageNameForUid(mContext, uid), false)) {
18513            return;
18514        }
18515
18516        String msg = "Permission Denial: " + func + " from pid="
18517                + Binder.getCallingPid()
18518                + ", uid=" + uid
18519                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18520        Slog.w(TAG, msg);
18521        throw new SecurityException(msg);
18522    }
18523
18524    public void updateConfiguration(Configuration values) {
18525        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18526                "updateConfiguration()");
18527
18528        synchronized(this) {
18529            if (values == null && mWindowManager != null) {
18530                // sentinel: fetch the current configuration from the window manager
18531                values = mWindowManager.computeNewConfiguration();
18532            }
18533
18534            if (mWindowManager != null) {
18535                mProcessList.applyDisplaySize(mWindowManager);
18536            }
18537
18538            final long origId = Binder.clearCallingIdentity();
18539            if (values != null) {
18540                Settings.System.clearConfiguration(values);
18541            }
18542            updateConfigurationLocked(values, null, false);
18543            Binder.restoreCallingIdentity(origId);
18544        }
18545    }
18546
18547    void updateUserConfigurationLocked() {
18548        Configuration configuration = new Configuration(mConfiguration);
18549        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18550                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18551        updateConfigurationLocked(configuration, null, false);
18552    }
18553
18554    boolean updateConfigurationLocked(Configuration values,
18555            ActivityRecord starting, boolean initLocale) {
18556        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18557        return updateConfigurationLocked(values, starting, initLocale, false,
18558                UserHandle.USER_NULL);
18559    }
18560
18561    // To cache the list of supported system locales
18562    private String[] mSupportedSystemLocales = null;
18563
18564    /**
18565     * Do either or both things: (1) change the current configuration, and (2)
18566     * make sure the given activity is running with the (now) current
18567     * configuration.  Returns true if the activity has been left running, or
18568     * false if <var>starting</var> is being destroyed to match the new
18569     * configuration.
18570     *
18571     * @param userId is only used when persistent parameter is set to true to persist configuration
18572     *               for that particular user
18573     */
18574    private boolean updateConfigurationLocked(Configuration values,
18575            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18576        int changes = 0;
18577
18578        if (mWindowManager != null) {
18579            mWindowManager.deferSurfaceLayout();
18580        }
18581        if (values != null) {
18582            Configuration newConfig = new Configuration(mConfiguration);
18583            changes = newConfig.updateFrom(values);
18584            if (changes != 0) {
18585                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18586                        "Updating configuration to: " + values);
18587
18588                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18589
18590                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18591                    final LocaleList locales = values.getLocales();
18592                    int bestLocaleIndex = 0;
18593                    if (locales.size() > 1) {
18594                        if (mSupportedSystemLocales == null) {
18595                            mSupportedSystemLocales =
18596                                    Resources.getSystem().getAssets().getLocales();
18597                        }
18598                        bestLocaleIndex = Math.max(0,
18599                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18600                    }
18601                    SystemProperties.set("persist.sys.locale",
18602                            locales.get(bestLocaleIndex).toLanguageTag());
18603                    LocaleList.setDefault(locales, bestLocaleIndex);
18604                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18605                            locales.get(bestLocaleIndex)));
18606                }
18607
18608                mConfigurationSeq++;
18609                if (mConfigurationSeq <= 0) {
18610                    mConfigurationSeq = 1;
18611                }
18612                newConfig.seq = mConfigurationSeq;
18613                mConfiguration = newConfig;
18614                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18615                mUsageStatsService.reportConfigurationChange(newConfig,
18616                        mUserController.getCurrentUserIdLocked());
18617                //mUsageStatsService.noteStartConfig(newConfig);
18618
18619                final Configuration configCopy = new Configuration(mConfiguration);
18620
18621                // TODO: If our config changes, should we auto dismiss any currently
18622                // showing dialogs?
18623                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18624
18625                AttributeCache ac = AttributeCache.instance();
18626                if (ac != null) {
18627                    ac.updateConfiguration(configCopy);
18628                }
18629
18630                // Make sure all resources in our process are updated
18631                // right now, so that anyone who is going to retrieve
18632                // resource values after we return will be sure to get
18633                // the new ones.  This is especially important during
18634                // boot, where the first config change needs to guarantee
18635                // all resources have that config before following boot
18636                // code is executed.
18637                mSystemThread.applyConfigurationToResources(configCopy);
18638
18639                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18640                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18641                    msg.obj = new Configuration(configCopy);
18642                    msg.arg1 = userId;
18643                    mHandler.sendMessage(msg);
18644                }
18645
18646                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18647                if (isDensityChange) {
18648                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18649                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18650                }
18651
18652                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18653                    ProcessRecord app = mLruProcesses.get(i);
18654                    try {
18655                        if (app.thread != null) {
18656                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18657                                    + app.processName + " new config " + mConfiguration);
18658                            app.thread.scheduleConfigurationChanged(configCopy);
18659                        }
18660                    } catch (Exception e) {
18661                    }
18662                }
18663                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18664                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18665                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18666                        | Intent.FLAG_RECEIVER_FOREGROUND);
18667                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18668                        null, AppOpsManager.OP_NONE, null, false, false,
18669                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18670                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18671                    // Tell the shortcut manager that the system locale changed.  It needs to know
18672                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18673                    // we "push" from here, rather than having the service listen to the broadcast.
18674                    final ShortcutServiceInternal shortcutService =
18675                            LocalServices.getService(ShortcutServiceInternal.class);
18676                    if (shortcutService != null) {
18677                        shortcutService.onSystemLocaleChangedNoLock();
18678                    }
18679
18680                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18681                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18682                    if (!mProcessesReady) {
18683                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18684                    }
18685                    broadcastIntentLocked(null, null, intent,
18686                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18687                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18688                }
18689            }
18690            // Update the configuration with WM first and check if any of the stacks need to be
18691            // resized due to the configuration change. If so, resize the stacks now and do any
18692            // relaunches if necessary. This way we don't need to relaunch again below in
18693            // ensureActivityConfigurationLocked().
18694            if (mWindowManager != null) {
18695                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18696                if (resizedStacks != null) {
18697                    for (int stackId : resizedStacks) {
18698                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18699                        mStackSupervisor.resizeStackLocked(
18700                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18701                    }
18702                }
18703            }
18704        }
18705
18706        boolean kept = true;
18707        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18708        // mainStack is null during startup.
18709        if (mainStack != null) {
18710            if (changes != 0 && starting == null) {
18711                // If the configuration changed, and the caller is not already
18712                // in the process of starting an activity, then find the top
18713                // activity to check if its configuration needs to change.
18714                starting = mainStack.topRunningActivityLocked();
18715            }
18716
18717            if (starting != null) {
18718                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18719                // And we need to make sure at this point that all other activities
18720                // are made visible with the correct configuration.
18721                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18722                        !PRESERVE_WINDOWS);
18723            }
18724        }
18725        if (mWindowManager != null) {
18726            mWindowManager.continueSurfaceLayout();
18727        }
18728        return kept;
18729    }
18730
18731    /**
18732     * Decide based on the configuration whether we should shouw the ANR,
18733     * crash, etc dialogs.  The idea is that if there is no affordnace to
18734     * press the on-screen buttons, we shouldn't show the dialog.
18735     *
18736     * A thought: SystemUI might also want to get told about this, the Power
18737     * dialog / global actions also might want different behaviors.
18738     */
18739    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18740        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18741                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18742                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18743        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18744                                    == Configuration.UI_MODE_TYPE_CAR);
18745        return inputMethodExists && uiIsNotCarType && !inVrMode;
18746    }
18747
18748    @Override
18749    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18750        synchronized (this) {
18751            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18752            if (srec != null) {
18753                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18754            }
18755        }
18756        return false;
18757    }
18758
18759    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18760            Intent resultData) {
18761
18762        synchronized (this) {
18763            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18764            if (r != null) {
18765                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18766            }
18767            return false;
18768        }
18769    }
18770
18771    public int getLaunchedFromUid(IBinder activityToken) {
18772        ActivityRecord srec;
18773        synchronized (this) {
18774            srec = ActivityRecord.forTokenLocked(activityToken);
18775        }
18776        if (srec == null) {
18777            return -1;
18778        }
18779        return srec.launchedFromUid;
18780    }
18781
18782    public String getLaunchedFromPackage(IBinder activityToken) {
18783        ActivityRecord srec;
18784        synchronized (this) {
18785            srec = ActivityRecord.forTokenLocked(activityToken);
18786        }
18787        if (srec == null) {
18788            return null;
18789        }
18790        return srec.launchedFromPackage;
18791    }
18792
18793    // =========================================================
18794    // LIFETIME MANAGEMENT
18795    // =========================================================
18796
18797    // Returns which broadcast queue the app is the current [or imminent] receiver
18798    // on, or 'null' if the app is not an active broadcast recipient.
18799    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18800        BroadcastRecord r = app.curReceiver;
18801        if (r != null) {
18802            return r.queue;
18803        }
18804
18805        // It's not the current receiver, but it might be starting up to become one
18806        synchronized (this) {
18807            for (BroadcastQueue queue : mBroadcastQueues) {
18808                r = queue.mPendingBroadcast;
18809                if (r != null && r.curApp == app) {
18810                    // found it; report which queue it's in
18811                    return queue;
18812                }
18813            }
18814        }
18815
18816        return null;
18817    }
18818
18819    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18820            int targetUid, ComponentName targetComponent, String targetProcess) {
18821        if (!mTrackingAssociations) {
18822            return null;
18823        }
18824        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18825                = mAssociations.get(targetUid);
18826        if (components == null) {
18827            components = new ArrayMap<>();
18828            mAssociations.put(targetUid, components);
18829        }
18830        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18831        if (sourceUids == null) {
18832            sourceUids = new SparseArray<>();
18833            components.put(targetComponent, sourceUids);
18834        }
18835        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18836        if (sourceProcesses == null) {
18837            sourceProcesses = new ArrayMap<>();
18838            sourceUids.put(sourceUid, sourceProcesses);
18839        }
18840        Association ass = sourceProcesses.get(sourceProcess);
18841        if (ass == null) {
18842            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18843                    targetProcess);
18844            sourceProcesses.put(sourceProcess, ass);
18845        }
18846        ass.mCount++;
18847        ass.mNesting++;
18848        if (ass.mNesting == 1) {
18849            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18850            ass.mLastState = sourceState;
18851        }
18852        return ass;
18853    }
18854
18855    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18856            ComponentName targetComponent) {
18857        if (!mTrackingAssociations) {
18858            return;
18859        }
18860        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18861                = mAssociations.get(targetUid);
18862        if (components == null) {
18863            return;
18864        }
18865        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18866        if (sourceUids == null) {
18867            return;
18868        }
18869        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18870        if (sourceProcesses == null) {
18871            return;
18872        }
18873        Association ass = sourceProcesses.get(sourceProcess);
18874        if (ass == null || ass.mNesting <= 0) {
18875            return;
18876        }
18877        ass.mNesting--;
18878        if (ass.mNesting == 0) {
18879            long uptime = SystemClock.uptimeMillis();
18880            ass.mTime += uptime - ass.mStartTime;
18881            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18882                    += uptime - ass.mLastStateUptime;
18883            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18884        }
18885    }
18886
18887    private void noteUidProcessState(final int uid, final int state) {
18888        mBatteryStatsService.noteUidProcessState(uid, state);
18889        if (mTrackingAssociations) {
18890            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18891                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18892                        = mAssociations.valueAt(i1);
18893                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18894                    SparseArray<ArrayMap<String, Association>> sourceUids
18895                            = targetComponents.valueAt(i2);
18896                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18897                    if (sourceProcesses != null) {
18898                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18899                            Association ass = sourceProcesses.valueAt(i4);
18900                            if (ass.mNesting >= 1) {
18901                                // currently associated
18902                                long uptime = SystemClock.uptimeMillis();
18903                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18904                                        += uptime - ass.mLastStateUptime;
18905                                ass.mLastState = state;
18906                                ass.mLastStateUptime = uptime;
18907                            }
18908                        }
18909                    }
18910                }
18911            }
18912        }
18913    }
18914
18915    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18916            boolean doingAll, long now) {
18917        if (mAdjSeq == app.adjSeq) {
18918            // This adjustment has already been computed.
18919            return app.curRawAdj;
18920        }
18921
18922        if (app.thread == null) {
18923            app.adjSeq = mAdjSeq;
18924            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18925            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18926            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18927        }
18928
18929        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18930        app.adjSource = null;
18931        app.adjTarget = null;
18932        app.empty = false;
18933        app.cached = false;
18934
18935        final int activitiesSize = app.activities.size();
18936
18937        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18938            // The max adjustment doesn't allow this app to be anything
18939            // below foreground, so it is not worth doing work for it.
18940            app.adjType = "fixed";
18941            app.adjSeq = mAdjSeq;
18942            app.curRawAdj = app.maxAdj;
18943            app.foregroundActivities = false;
18944            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18945            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18946            // System processes can do UI, and when they do we want to have
18947            // them trim their memory after the user leaves the UI.  To
18948            // facilitate this, here we need to determine whether or not it
18949            // is currently showing UI.
18950            app.systemNoUi = true;
18951            if (app == TOP_APP) {
18952                app.systemNoUi = false;
18953                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18954                app.adjType = "pers-top-activity";
18955            } else if (activitiesSize > 0) {
18956                for (int j = 0; j < activitiesSize; j++) {
18957                    final ActivityRecord r = app.activities.get(j);
18958                    if (r.visible) {
18959                        app.systemNoUi = false;
18960                    }
18961                }
18962            }
18963            if (!app.systemNoUi) {
18964                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18965            }
18966            return (app.curAdj=app.maxAdj);
18967        }
18968
18969        app.systemNoUi = false;
18970
18971        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18972
18973        // Determine the importance of the process, starting with most
18974        // important to least, and assign an appropriate OOM adjustment.
18975        int adj;
18976        int schedGroup;
18977        int procState;
18978        boolean foregroundActivities = false;
18979        BroadcastQueue queue;
18980        if (app == TOP_APP) {
18981            // The last app on the list is the foreground app.
18982            adj = ProcessList.FOREGROUND_APP_ADJ;
18983            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18984            app.adjType = "top-activity";
18985            foregroundActivities = true;
18986            procState = PROCESS_STATE_CUR_TOP;
18987        } else if (app.instrumentationClass != null) {
18988            // Don't want to kill running instrumentation.
18989            adj = ProcessList.FOREGROUND_APP_ADJ;
18990            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18991            app.adjType = "instrumentation";
18992            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18993        } else if ((queue = isReceivingBroadcast(app)) != null) {
18994            // An app that is currently receiving a broadcast also
18995            // counts as being in the foreground for OOM killer purposes.
18996            // It's placed in a sched group based on the nature of the
18997            // broadcast as reflected by which queue it's active in.
18998            adj = ProcessList.FOREGROUND_APP_ADJ;
18999            schedGroup = (queue == mFgBroadcastQueue)
19000                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19001            app.adjType = "broadcast";
19002            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19003        } else if (app.executingServices.size() > 0) {
19004            // An app that is currently executing a service callback also
19005            // counts as being in the foreground.
19006            adj = ProcessList.FOREGROUND_APP_ADJ;
19007            schedGroup = app.execServicesFg ?
19008                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19009            app.adjType = "exec-service";
19010            procState = ActivityManager.PROCESS_STATE_SERVICE;
19011            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19012        } else {
19013            // As far as we know the process is empty.  We may change our mind later.
19014            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19015            // At this point we don't actually know the adjustment.  Use the cached adj
19016            // value that the caller wants us to.
19017            adj = cachedAdj;
19018            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19019            app.cached = true;
19020            app.empty = true;
19021            app.adjType = "cch-empty";
19022        }
19023
19024        // Examine all activities if not already foreground.
19025        if (!foregroundActivities && activitiesSize > 0) {
19026            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19027            for (int j = 0; j < activitiesSize; j++) {
19028                final ActivityRecord r = app.activities.get(j);
19029                if (r.app != app) {
19030                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19031                            + " instead of expected " + app);
19032                    if (r.app == null || (r.app.uid == app.uid)) {
19033                        // Only fix things up when they look sane
19034                        r.app = app;
19035                    } else {
19036                        continue;
19037                    }
19038                }
19039                if (r.visible) {
19040                    // App has a visible activity; only upgrade adjustment.
19041                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19042                        adj = ProcessList.VISIBLE_APP_ADJ;
19043                        app.adjType = "visible";
19044                    }
19045                    if (procState > PROCESS_STATE_CUR_TOP) {
19046                        procState = PROCESS_STATE_CUR_TOP;
19047                    }
19048                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19049                    app.cached = false;
19050                    app.empty = false;
19051                    foregroundActivities = true;
19052                    if (r.task != null && minLayer > 0) {
19053                        final int layer = r.task.mLayerRank;
19054                        if (layer >= 0 && minLayer > layer) {
19055                            minLayer = layer;
19056                        }
19057                    }
19058                    break;
19059                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19060                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19061                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19062                        app.adjType = "pausing";
19063                    }
19064                    if (procState > PROCESS_STATE_CUR_TOP) {
19065                        procState = PROCESS_STATE_CUR_TOP;
19066                    }
19067                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19068                    app.cached = false;
19069                    app.empty = false;
19070                    foregroundActivities = true;
19071                } else if (r.state == ActivityState.STOPPING) {
19072                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19073                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19074                        app.adjType = "stopping";
19075                    }
19076                    // For the process state, we will at this point consider the
19077                    // process to be cached.  It will be cached either as an activity
19078                    // or empty depending on whether the activity is finishing.  We do
19079                    // this so that we can treat the process as cached for purposes of
19080                    // memory trimming (determing current memory level, trim command to
19081                    // send to process) since there can be an arbitrary number of stopping
19082                    // processes and they should soon all go into the cached state.
19083                    if (!r.finishing) {
19084                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19085                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19086                        }
19087                    }
19088                    app.cached = false;
19089                    app.empty = false;
19090                    foregroundActivities = true;
19091                } else {
19092                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19093                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19094                        app.adjType = "cch-act";
19095                    }
19096                }
19097            }
19098            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19099                adj += minLayer;
19100            }
19101        }
19102
19103        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19104                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19105            if (app.foregroundServices) {
19106                // The user is aware of this app, so make it visible.
19107                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19108                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19109                app.cached = false;
19110                app.adjType = "fg-service";
19111                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19112            } else if (app.forcingToForeground != null) {
19113                // The user is aware of this app, so make it visible.
19114                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19115                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19116                app.cached = false;
19117                app.adjType = "force-fg";
19118                app.adjSource = app.forcingToForeground;
19119                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19120            }
19121        }
19122
19123        if (app == mHeavyWeightProcess) {
19124            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19125                // We don't want to kill the current heavy-weight process.
19126                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19127                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19128                app.cached = false;
19129                app.adjType = "heavy";
19130            }
19131            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19132                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19133            }
19134        }
19135
19136        if (app == mHomeProcess) {
19137            if (adj > ProcessList.HOME_APP_ADJ) {
19138                // This process is hosting what we currently consider to be the
19139                // home app, so we don't want to let it go into the background.
19140                adj = ProcessList.HOME_APP_ADJ;
19141                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19142                app.cached = false;
19143                app.adjType = "home";
19144            }
19145            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19146                procState = ActivityManager.PROCESS_STATE_HOME;
19147            }
19148        }
19149
19150        if (app == mPreviousProcess && app.activities.size() > 0) {
19151            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19152                // This was the previous process that showed UI to the user.
19153                // We want to try to keep it around more aggressively, to give
19154                // a good experience around switching between two apps.
19155                adj = ProcessList.PREVIOUS_APP_ADJ;
19156                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19157                app.cached = false;
19158                app.adjType = "previous";
19159            }
19160            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19161                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19162            }
19163        }
19164
19165        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19166                + " reason=" + app.adjType);
19167
19168        // By default, we use the computed adjustment.  It may be changed if
19169        // there are applications dependent on our services or providers, but
19170        // this gives us a baseline and makes sure we don't get into an
19171        // infinite recursion.
19172        app.adjSeq = mAdjSeq;
19173        app.curRawAdj = adj;
19174        app.hasStartedServices = false;
19175
19176        if (mBackupTarget != null && app == mBackupTarget.app) {
19177            // If possible we want to avoid killing apps while they're being backed up
19178            if (adj > ProcessList.BACKUP_APP_ADJ) {
19179                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19180                adj = ProcessList.BACKUP_APP_ADJ;
19181                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19182                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19183                }
19184                app.adjType = "backup";
19185                app.cached = false;
19186            }
19187            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19188                procState = ActivityManager.PROCESS_STATE_BACKUP;
19189            }
19190        }
19191
19192        boolean mayBeTop = false;
19193
19194        for (int is = app.services.size()-1;
19195                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19196                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19197                        || procState > ActivityManager.PROCESS_STATE_TOP);
19198                is--) {
19199            ServiceRecord s = app.services.valueAt(is);
19200            if (s.startRequested) {
19201                app.hasStartedServices = true;
19202                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19203                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19204                }
19205                if (app.hasShownUi && app != mHomeProcess) {
19206                    // If this process has shown some UI, let it immediately
19207                    // go to the LRU list because it may be pretty heavy with
19208                    // UI stuff.  We'll tag it with a label just to help
19209                    // debug and understand what is going on.
19210                    if (adj > ProcessList.SERVICE_ADJ) {
19211                        app.adjType = "cch-started-ui-services";
19212                    }
19213                } else {
19214                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19215                        // This service has seen some activity within
19216                        // recent memory, so we will keep its process ahead
19217                        // of the background processes.
19218                        if (adj > ProcessList.SERVICE_ADJ) {
19219                            adj = ProcessList.SERVICE_ADJ;
19220                            app.adjType = "started-services";
19221                            app.cached = false;
19222                        }
19223                    }
19224                    // If we have let the service slide into the background
19225                    // state, still have some text describing what it is doing
19226                    // even though the service no longer has an impact.
19227                    if (adj > ProcessList.SERVICE_ADJ) {
19228                        app.adjType = "cch-started-services";
19229                    }
19230                }
19231            }
19232
19233            app.whitelistManager = false;
19234
19235            for (int conni = s.connections.size()-1;
19236                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19237                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19238                            || procState > ActivityManager.PROCESS_STATE_TOP);
19239                    conni--) {
19240                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19241                for (int i = 0;
19242                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19243                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19244                                || procState > ActivityManager.PROCESS_STATE_TOP);
19245                        i++) {
19246                    // XXX should compute this based on the max of
19247                    // all connected clients.
19248                    ConnectionRecord cr = clist.get(i);
19249                    if (cr.binding.client == app) {
19250                        // Binding to ourself is not interesting.
19251                        continue;
19252                    }
19253                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19254                        app.whitelistManager = true;
19255                    }
19256
19257                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19258                        ProcessRecord client = cr.binding.client;
19259                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19260                                TOP_APP, doingAll, now);
19261                        int clientProcState = client.curProcState;
19262                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19263                            // If the other app is cached for any reason, for purposes here
19264                            // we are going to consider it empty.  The specific cached state
19265                            // doesn't propagate except under certain conditions.
19266                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19267                        }
19268                        String adjType = null;
19269                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19270                            // Not doing bind OOM management, so treat
19271                            // this guy more like a started service.
19272                            if (app.hasShownUi && app != mHomeProcess) {
19273                                // If this process has shown some UI, let it immediately
19274                                // go to the LRU list because it may be pretty heavy with
19275                                // UI stuff.  We'll tag it with a label just to help
19276                                // debug and understand what is going on.
19277                                if (adj > clientAdj) {
19278                                    adjType = "cch-bound-ui-services";
19279                                }
19280                                app.cached = false;
19281                                clientAdj = adj;
19282                                clientProcState = procState;
19283                            } else {
19284                                if (now >= (s.lastActivity
19285                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19286                                    // This service has not seen activity within
19287                                    // recent memory, so allow it to drop to the
19288                                    // LRU list if there is no other reason to keep
19289                                    // it around.  We'll also tag it with a label just
19290                                    // to help debug and undertand what is going on.
19291                                    if (adj > clientAdj) {
19292                                        adjType = "cch-bound-services";
19293                                    }
19294                                    clientAdj = adj;
19295                                }
19296                            }
19297                        }
19298                        if (adj > clientAdj) {
19299                            // If this process has recently shown UI, and
19300                            // the process that is binding to it is less
19301                            // important than being visible, then we don't
19302                            // care about the binding as much as we care
19303                            // about letting this process get into the LRU
19304                            // list to be killed and restarted if needed for
19305                            // memory.
19306                            if (app.hasShownUi && app != mHomeProcess
19307                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19308                                adjType = "cch-bound-ui-services";
19309                            } else {
19310                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19311                                        |Context.BIND_IMPORTANT)) != 0) {
19312                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19313                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19314                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19315                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19316                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19317                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19318                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19319                                    adj = clientAdj;
19320                                } else {
19321                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19322                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19323                                    }
19324                                }
19325                                if (!client.cached) {
19326                                    app.cached = false;
19327                                }
19328                                adjType = "service";
19329                            }
19330                        }
19331                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19332                            // This will treat important bound services identically to
19333                            // the top app, which may behave differently than generic
19334                            // foreground work.
19335                            if (client.curSchedGroup > schedGroup) {
19336                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19337                                    schedGroup = client.curSchedGroup;
19338                                } else {
19339                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19340                                }
19341                            }
19342                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19343                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19344                                    // Special handling of clients who are in the top state.
19345                                    // We *may* want to consider this process to be in the
19346                                    // top state as well, but only if there is not another
19347                                    // reason for it to be running.  Being on the top is a
19348                                    // special state, meaning you are specifically running
19349                                    // for the current top app.  If the process is already
19350                                    // running in the background for some other reason, it
19351                                    // is more important to continue considering it to be
19352                                    // in the background state.
19353                                    mayBeTop = true;
19354                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19355                                } else {
19356                                    // Special handling for above-top states (persistent
19357                                    // processes).  These should not bring the current process
19358                                    // into the top state, since they are not on top.  Instead
19359                                    // give them the best state after that.
19360                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19361                                        clientProcState =
19362                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19363                                    } else if (mWakefulness
19364                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19365                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19366                                                    != 0) {
19367                                        clientProcState =
19368                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19369                                    } else {
19370                                        clientProcState =
19371                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19372                                    }
19373                                }
19374                            }
19375                        } else {
19376                            if (clientProcState <
19377                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19378                                clientProcState =
19379                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19380                            }
19381                        }
19382                        if (procState > clientProcState) {
19383                            procState = clientProcState;
19384                        }
19385                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19386                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19387                            app.pendingUiClean = true;
19388                        }
19389                        if (adjType != null) {
19390                            app.adjType = adjType;
19391                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19392                                    .REASON_SERVICE_IN_USE;
19393                            app.adjSource = cr.binding.client;
19394                            app.adjSourceProcState = clientProcState;
19395                            app.adjTarget = s.name;
19396                        }
19397                    }
19398                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19399                        app.treatLikeActivity = true;
19400                    }
19401                    final ActivityRecord a = cr.activity;
19402                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19403                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19404                            (a.visible || a.state == ActivityState.RESUMED ||
19405                             a.state == ActivityState.PAUSING)) {
19406                            adj = ProcessList.FOREGROUND_APP_ADJ;
19407                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19408                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19409                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19410                                } else {
19411                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19412                                }
19413                            }
19414                            app.cached = false;
19415                            app.adjType = "service";
19416                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19417                                    .REASON_SERVICE_IN_USE;
19418                            app.adjSource = a;
19419                            app.adjSourceProcState = procState;
19420                            app.adjTarget = s.name;
19421                        }
19422                    }
19423                }
19424            }
19425        }
19426
19427        for (int provi = app.pubProviders.size()-1;
19428                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19429                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19430                        || procState > ActivityManager.PROCESS_STATE_TOP);
19431                provi--) {
19432            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19433            for (int i = cpr.connections.size()-1;
19434                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19435                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19436                            || procState > ActivityManager.PROCESS_STATE_TOP);
19437                    i--) {
19438                ContentProviderConnection conn = cpr.connections.get(i);
19439                ProcessRecord client = conn.client;
19440                if (client == app) {
19441                    // Being our own client is not interesting.
19442                    continue;
19443                }
19444                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19445                int clientProcState = client.curProcState;
19446                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19447                    // If the other app is cached for any reason, for purposes here
19448                    // we are going to consider it empty.
19449                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19450                }
19451                if (adj > clientAdj) {
19452                    if (app.hasShownUi && app != mHomeProcess
19453                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19454                        app.adjType = "cch-ui-provider";
19455                    } else {
19456                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19457                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19458                        app.adjType = "provider";
19459                    }
19460                    app.cached &= client.cached;
19461                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19462                            .REASON_PROVIDER_IN_USE;
19463                    app.adjSource = client;
19464                    app.adjSourceProcState = clientProcState;
19465                    app.adjTarget = cpr.name;
19466                }
19467                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19468                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19469                        // Special handling of clients who are in the top state.
19470                        // We *may* want to consider this process to be in the
19471                        // top state as well, but only if there is not another
19472                        // reason for it to be running.  Being on the top is a
19473                        // special state, meaning you are specifically running
19474                        // for the current top app.  If the process is already
19475                        // running in the background for some other reason, it
19476                        // is more important to continue considering it to be
19477                        // in the background state.
19478                        mayBeTop = true;
19479                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19480                    } else {
19481                        // Special handling for above-top states (persistent
19482                        // processes).  These should not bring the current process
19483                        // into the top state, since they are not on top.  Instead
19484                        // give them the best state after that.
19485                        clientProcState =
19486                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19487                    }
19488                }
19489                if (procState > clientProcState) {
19490                    procState = clientProcState;
19491                }
19492                if (client.curSchedGroup > schedGroup) {
19493                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19494                }
19495            }
19496            // If the provider has external (non-framework) process
19497            // dependencies, ensure that its adjustment is at least
19498            // FOREGROUND_APP_ADJ.
19499            if (cpr.hasExternalProcessHandles()) {
19500                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19501                    adj = ProcessList.FOREGROUND_APP_ADJ;
19502                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19503                    app.cached = false;
19504                    app.adjType = "provider";
19505                    app.adjTarget = cpr.name;
19506                }
19507                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19508                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19509                }
19510            }
19511        }
19512
19513        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19514            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19515                adj = ProcessList.PREVIOUS_APP_ADJ;
19516                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19517                app.cached = false;
19518                app.adjType = "provider";
19519            }
19520            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19521                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19522            }
19523        }
19524
19525        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19526            // A client of one of our services or providers is in the top state.  We
19527            // *may* want to be in the top state, but not if we are already running in
19528            // the background for some other reason.  For the decision here, we are going
19529            // to pick out a few specific states that we want to remain in when a client
19530            // is top (states that tend to be longer-term) and otherwise allow it to go
19531            // to the top state.
19532            switch (procState) {
19533                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19534                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19535                case ActivityManager.PROCESS_STATE_SERVICE:
19536                    // These all are longer-term states, so pull them up to the top
19537                    // of the background states, but not all the way to the top state.
19538                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19539                    break;
19540                default:
19541                    // Otherwise, top is a better choice, so take it.
19542                    procState = ActivityManager.PROCESS_STATE_TOP;
19543                    break;
19544            }
19545        }
19546
19547        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19548            if (app.hasClientActivities) {
19549                // This is a cached process, but with client activities.  Mark it so.
19550                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19551                app.adjType = "cch-client-act";
19552            } else if (app.treatLikeActivity) {
19553                // This is a cached process, but somebody wants us to treat it like it has
19554                // an activity, okay!
19555                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19556                app.adjType = "cch-as-act";
19557            }
19558        }
19559
19560        if (adj == ProcessList.SERVICE_ADJ) {
19561            if (doingAll) {
19562                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19563                mNewNumServiceProcs++;
19564                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19565                if (!app.serviceb) {
19566                    // This service isn't far enough down on the LRU list to
19567                    // normally be a B service, but if we are low on RAM and it
19568                    // is large we want to force it down since we would prefer to
19569                    // keep launcher over it.
19570                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19571                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19572                        app.serviceHighRam = true;
19573                        app.serviceb = true;
19574                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19575                    } else {
19576                        mNewNumAServiceProcs++;
19577                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19578                    }
19579                } else {
19580                    app.serviceHighRam = false;
19581                }
19582            }
19583            if (app.serviceb) {
19584                adj = ProcessList.SERVICE_B_ADJ;
19585            }
19586        }
19587
19588        app.curRawAdj = adj;
19589
19590        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19591        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19592        if (adj > app.maxAdj) {
19593            adj = app.maxAdj;
19594            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19595                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19596            }
19597        }
19598
19599        // Do final modification to adj.  Everything we do between here and applying
19600        // the final setAdj must be done in this function, because we will also use
19601        // it when computing the final cached adj later.  Note that we don't need to
19602        // worry about this for max adj above, since max adj will always be used to
19603        // keep it out of the cached vaues.
19604        app.curAdj = app.modifyRawOomAdj(adj);
19605        app.curSchedGroup = schedGroup;
19606        app.curProcState = procState;
19607        app.foregroundActivities = foregroundActivities;
19608
19609        return app.curRawAdj;
19610    }
19611
19612    /**
19613     * Record new PSS sample for a process.
19614     */
19615    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19616            long now) {
19617        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19618                swapPss * 1024);
19619        proc.lastPssTime = now;
19620        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19621        if (DEBUG_PSS) Slog.d(TAG_PSS,
19622                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19623                + " state=" + ProcessList.makeProcStateString(procState));
19624        if (proc.initialIdlePss == 0) {
19625            proc.initialIdlePss = pss;
19626        }
19627        proc.lastPss = pss;
19628        proc.lastSwapPss = swapPss;
19629        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19630            proc.lastCachedPss = pss;
19631            proc.lastCachedSwapPss = swapPss;
19632        }
19633
19634        final SparseArray<Pair<Long, String>> watchUids
19635                = mMemWatchProcesses.getMap().get(proc.processName);
19636        Long check = null;
19637        if (watchUids != null) {
19638            Pair<Long, String> val = watchUids.get(proc.uid);
19639            if (val == null) {
19640                val = watchUids.get(0);
19641            }
19642            if (val != null) {
19643                check = val.first;
19644            }
19645        }
19646        if (check != null) {
19647            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19648                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19649                if (!isDebuggable) {
19650                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19651                        isDebuggable = true;
19652                    }
19653                }
19654                if (isDebuggable) {
19655                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19656                    final ProcessRecord myProc = proc;
19657                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19658                    mMemWatchDumpProcName = proc.processName;
19659                    mMemWatchDumpFile = heapdumpFile.toString();
19660                    mMemWatchDumpPid = proc.pid;
19661                    mMemWatchDumpUid = proc.uid;
19662                    BackgroundThread.getHandler().post(new Runnable() {
19663                        @Override
19664                        public void run() {
19665                            revokeUriPermission(ActivityThread.currentActivityThread()
19666                                            .getApplicationThread(),
19667                                    DumpHeapActivity.JAVA_URI,
19668                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19669                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19670                                    UserHandle.myUserId());
19671                            ParcelFileDescriptor fd = null;
19672                            try {
19673                                heapdumpFile.delete();
19674                                fd = ParcelFileDescriptor.open(heapdumpFile,
19675                                        ParcelFileDescriptor.MODE_CREATE |
19676                                                ParcelFileDescriptor.MODE_TRUNCATE |
19677                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19678                                                ParcelFileDescriptor.MODE_APPEND);
19679                                IApplicationThread thread = myProc.thread;
19680                                if (thread != null) {
19681                                    try {
19682                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19683                                                "Requesting dump heap from "
19684                                                + myProc + " to " + heapdumpFile);
19685                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19686                                    } catch (RemoteException e) {
19687                                    }
19688                                }
19689                            } catch (FileNotFoundException e) {
19690                                e.printStackTrace();
19691                            } finally {
19692                                if (fd != null) {
19693                                    try {
19694                                        fd.close();
19695                                    } catch (IOException e) {
19696                                    }
19697                                }
19698                            }
19699                        }
19700                    });
19701                } else {
19702                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19703                            + ", but debugging not enabled");
19704                }
19705            }
19706        }
19707    }
19708
19709    /**
19710     * Schedule PSS collection of a process.
19711     */
19712    void requestPssLocked(ProcessRecord proc, int procState) {
19713        if (mPendingPssProcesses.contains(proc)) {
19714            return;
19715        }
19716        if (mPendingPssProcesses.size() == 0) {
19717            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19718        }
19719        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19720        proc.pssProcState = procState;
19721        mPendingPssProcesses.add(proc);
19722    }
19723
19724    /**
19725     * Schedule PSS collection of all processes.
19726     */
19727    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19728        if (!always) {
19729            if (now < (mLastFullPssTime +
19730                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19731                return;
19732            }
19733        }
19734        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19735        mLastFullPssTime = now;
19736        mFullPssPending = true;
19737        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19738        mPendingPssProcesses.clear();
19739        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19740            ProcessRecord app = mLruProcesses.get(i);
19741            if (app.thread == null
19742                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19743                continue;
19744            }
19745            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19746                app.pssProcState = app.setProcState;
19747                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19748                        mTestPssMode, isSleeping(), now);
19749                mPendingPssProcesses.add(app);
19750            }
19751        }
19752        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19753    }
19754
19755    public void setTestPssMode(boolean enabled) {
19756        synchronized (this) {
19757            mTestPssMode = enabled;
19758            if (enabled) {
19759                // Whenever we enable the mode, we want to take a snapshot all of current
19760                // process mem use.
19761                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19762            }
19763        }
19764    }
19765
19766    /**
19767     * Ask a given process to GC right now.
19768     */
19769    final void performAppGcLocked(ProcessRecord app) {
19770        try {
19771            app.lastRequestedGc = SystemClock.uptimeMillis();
19772            if (app.thread != null) {
19773                if (app.reportLowMemory) {
19774                    app.reportLowMemory = false;
19775                    app.thread.scheduleLowMemory();
19776                } else {
19777                    app.thread.processInBackground();
19778                }
19779            }
19780        } catch (Exception e) {
19781            // whatever.
19782        }
19783    }
19784
19785    /**
19786     * Returns true if things are idle enough to perform GCs.
19787     */
19788    private final boolean canGcNowLocked() {
19789        boolean processingBroadcasts = false;
19790        for (BroadcastQueue q : mBroadcastQueues) {
19791            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19792                processingBroadcasts = true;
19793            }
19794        }
19795        return !processingBroadcasts
19796                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19797    }
19798
19799    /**
19800     * Perform GCs on all processes that are waiting for it, but only
19801     * if things are idle.
19802     */
19803    final void performAppGcsLocked() {
19804        final int N = mProcessesToGc.size();
19805        if (N <= 0) {
19806            return;
19807        }
19808        if (canGcNowLocked()) {
19809            while (mProcessesToGc.size() > 0) {
19810                ProcessRecord proc = mProcessesToGc.remove(0);
19811                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19812                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19813                            <= SystemClock.uptimeMillis()) {
19814                        // To avoid spamming the system, we will GC processes one
19815                        // at a time, waiting a few seconds between each.
19816                        performAppGcLocked(proc);
19817                        scheduleAppGcsLocked();
19818                        return;
19819                    } else {
19820                        // It hasn't been long enough since we last GCed this
19821                        // process...  put it in the list to wait for its time.
19822                        addProcessToGcListLocked(proc);
19823                        break;
19824                    }
19825                }
19826            }
19827
19828            scheduleAppGcsLocked();
19829        }
19830    }
19831
19832    /**
19833     * If all looks good, perform GCs on all processes waiting for them.
19834     */
19835    final void performAppGcsIfAppropriateLocked() {
19836        if (canGcNowLocked()) {
19837            performAppGcsLocked();
19838            return;
19839        }
19840        // Still not idle, wait some more.
19841        scheduleAppGcsLocked();
19842    }
19843
19844    /**
19845     * Schedule the execution of all pending app GCs.
19846     */
19847    final void scheduleAppGcsLocked() {
19848        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19849
19850        if (mProcessesToGc.size() > 0) {
19851            // Schedule a GC for the time to the next process.
19852            ProcessRecord proc = mProcessesToGc.get(0);
19853            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19854
19855            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19856            long now = SystemClock.uptimeMillis();
19857            if (when < (now+GC_TIMEOUT)) {
19858                when = now + GC_TIMEOUT;
19859            }
19860            mHandler.sendMessageAtTime(msg, when);
19861        }
19862    }
19863
19864    /**
19865     * Add a process to the array of processes waiting to be GCed.  Keeps the
19866     * list in sorted order by the last GC time.  The process can't already be
19867     * on the list.
19868     */
19869    final void addProcessToGcListLocked(ProcessRecord proc) {
19870        boolean added = false;
19871        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19872            if (mProcessesToGc.get(i).lastRequestedGc <
19873                    proc.lastRequestedGc) {
19874                added = true;
19875                mProcessesToGc.add(i+1, proc);
19876                break;
19877            }
19878        }
19879        if (!added) {
19880            mProcessesToGc.add(0, proc);
19881        }
19882    }
19883
19884    /**
19885     * Set up to ask a process to GC itself.  This will either do it
19886     * immediately, or put it on the list of processes to gc the next
19887     * time things are idle.
19888     */
19889    final void scheduleAppGcLocked(ProcessRecord app) {
19890        long now = SystemClock.uptimeMillis();
19891        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19892            return;
19893        }
19894        if (!mProcessesToGc.contains(app)) {
19895            addProcessToGcListLocked(app);
19896            scheduleAppGcsLocked();
19897        }
19898    }
19899
19900    final void checkExcessivePowerUsageLocked(boolean doKills) {
19901        updateCpuStatsNow();
19902
19903        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19904        boolean doWakeKills = doKills;
19905        boolean doCpuKills = doKills;
19906        if (mLastPowerCheckRealtime == 0) {
19907            doWakeKills = false;
19908        }
19909        if (mLastPowerCheckUptime == 0) {
19910            doCpuKills = false;
19911        }
19912        if (stats.isScreenOn()) {
19913            doWakeKills = false;
19914        }
19915        final long curRealtime = SystemClock.elapsedRealtime();
19916        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19917        final long curUptime = SystemClock.uptimeMillis();
19918        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19919        mLastPowerCheckRealtime = curRealtime;
19920        mLastPowerCheckUptime = curUptime;
19921        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19922            doWakeKills = false;
19923        }
19924        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19925            doCpuKills = false;
19926        }
19927        int i = mLruProcesses.size();
19928        while (i > 0) {
19929            i--;
19930            ProcessRecord app = mLruProcesses.get(i);
19931            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19932                long wtime;
19933                synchronized (stats) {
19934                    wtime = stats.getProcessWakeTime(app.info.uid,
19935                            app.pid, curRealtime);
19936                }
19937                long wtimeUsed = wtime - app.lastWakeTime;
19938                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19939                if (DEBUG_POWER) {
19940                    StringBuilder sb = new StringBuilder(128);
19941                    sb.append("Wake for ");
19942                    app.toShortString(sb);
19943                    sb.append(": over ");
19944                    TimeUtils.formatDuration(realtimeSince, sb);
19945                    sb.append(" used ");
19946                    TimeUtils.formatDuration(wtimeUsed, sb);
19947                    sb.append(" (");
19948                    sb.append((wtimeUsed*100)/realtimeSince);
19949                    sb.append("%)");
19950                    Slog.i(TAG_POWER, sb.toString());
19951                    sb.setLength(0);
19952                    sb.append("CPU for ");
19953                    app.toShortString(sb);
19954                    sb.append(": over ");
19955                    TimeUtils.formatDuration(uptimeSince, sb);
19956                    sb.append(" used ");
19957                    TimeUtils.formatDuration(cputimeUsed, sb);
19958                    sb.append(" (");
19959                    sb.append((cputimeUsed*100)/uptimeSince);
19960                    sb.append("%)");
19961                    Slog.i(TAG_POWER, sb.toString());
19962                }
19963                // If a process has held a wake lock for more
19964                // than 50% of the time during this period,
19965                // that sounds bad.  Kill!
19966                if (doWakeKills && realtimeSince > 0
19967                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19968                    synchronized (stats) {
19969                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19970                                realtimeSince, wtimeUsed);
19971                    }
19972                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19973                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19974                } else if (doCpuKills && uptimeSince > 0
19975                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19976                    synchronized (stats) {
19977                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19978                                uptimeSince, cputimeUsed);
19979                    }
19980                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19981                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19982                } else {
19983                    app.lastWakeTime = wtime;
19984                    app.lastCpuTime = app.curCpuTime;
19985                }
19986            }
19987        }
19988    }
19989
19990    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19991            long nowElapsed) {
19992        boolean success = true;
19993
19994        if (app.curRawAdj != app.setRawAdj) {
19995            app.setRawAdj = app.curRawAdj;
19996        }
19997
19998        int changes = 0;
19999
20000        if (app.curAdj != app.setAdj) {
20001            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20002            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20003                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20004                    + app.adjType);
20005            app.setAdj = app.curAdj;
20006        }
20007
20008        if (app.setSchedGroup != app.curSchedGroup) {
20009            app.setSchedGroup = app.curSchedGroup;
20010            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20011                    "Setting sched group of " + app.processName
20012                    + " to " + app.curSchedGroup);
20013            if (app.waitingToKill != null && app.curReceiver == null
20014                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20015                app.kill(app.waitingToKill, true);
20016                success = false;
20017            } else {
20018                int processGroup;
20019                switch (app.curSchedGroup) {
20020                    case ProcessList.SCHED_GROUP_BACKGROUND:
20021                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20022                        break;
20023                    case ProcessList.SCHED_GROUP_TOP_APP:
20024                        processGroup = Process.THREAD_GROUP_TOP_APP;
20025                        break;
20026                    default:
20027                        processGroup = Process.THREAD_GROUP_DEFAULT;
20028                        break;
20029                }
20030                if (true) {
20031                    long oldId = Binder.clearCallingIdentity();
20032                    try {
20033                        Process.setProcessGroup(app.pid, processGroup);
20034                    } catch (Exception e) {
20035                        Slog.w(TAG, "Failed setting process group of " + app.pid
20036                                + " to " + app.curSchedGroup);
20037                        e.printStackTrace();
20038                    } finally {
20039                        Binder.restoreCallingIdentity(oldId);
20040                    }
20041                } else {
20042                    if (app.thread != null) {
20043                        try {
20044                            app.thread.setSchedulingGroup(processGroup);
20045                        } catch (RemoteException e) {
20046                        }
20047                    }
20048                }
20049            }
20050        }
20051        if (app.repForegroundActivities != app.foregroundActivities) {
20052            app.repForegroundActivities = app.foregroundActivities;
20053            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20054        }
20055        if (app.repProcState != app.curProcState) {
20056            app.repProcState = app.curProcState;
20057            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20058            if (app.thread != null) {
20059                try {
20060                    if (false) {
20061                        //RuntimeException h = new RuntimeException("here");
20062                        Slog.i(TAG, "Sending new process state " + app.repProcState
20063                                + " to " + app /*, h*/);
20064                    }
20065                    app.thread.setProcessState(app.repProcState);
20066                } catch (RemoteException e) {
20067                }
20068            }
20069        }
20070        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20071                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20072            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20073                // Experimental code to more aggressively collect pss while
20074                // running test...  the problem is that this tends to collect
20075                // the data right when a process is transitioning between process
20076                // states, which well tend to give noisy data.
20077                long start = SystemClock.uptimeMillis();
20078                long pss = Debug.getPss(app.pid, mTmpLong, null);
20079                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20080                mPendingPssProcesses.remove(app);
20081                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20082                        + " to " + app.curProcState + ": "
20083                        + (SystemClock.uptimeMillis()-start) + "ms");
20084            }
20085            app.lastStateTime = now;
20086            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20087                    mTestPssMode, isSleeping(), now);
20088            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20089                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20090                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20091                    + (app.nextPssTime-now) + ": " + app);
20092        } else {
20093            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20094                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20095                    mTestPssMode)))) {
20096                requestPssLocked(app, app.setProcState);
20097                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20098                        mTestPssMode, isSleeping(), now);
20099            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20100                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20101        }
20102        if (app.setProcState != app.curProcState) {
20103            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20104                    "Proc state change of " + app.processName
20105                            + " to " + app.curProcState);
20106            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20107            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20108            if (setImportant && !curImportant) {
20109                // This app is no longer something we consider important enough to allow to
20110                // use arbitrary amounts of battery power.  Note
20111                // its current wake lock time to later know to kill it if
20112                // it is not behaving well.
20113                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20114                synchronized (stats) {
20115                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20116                            app.pid, nowElapsed);
20117                }
20118                app.lastCpuTime = app.curCpuTime;
20119
20120            }
20121            // Inform UsageStats of important process state change
20122            // Must be called before updating setProcState
20123            maybeUpdateUsageStatsLocked(app, nowElapsed);
20124
20125            app.setProcState = app.curProcState;
20126            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20127                app.notCachedSinceIdle = false;
20128            }
20129            if (!doingAll) {
20130                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20131            } else {
20132                app.procStateChanged = true;
20133            }
20134        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20135                > USAGE_STATS_INTERACTION_INTERVAL) {
20136            // For apps that sit around for a long time in the interactive state, we need
20137            // to report this at least once a day so they don't go idle.
20138            maybeUpdateUsageStatsLocked(app, nowElapsed);
20139        }
20140
20141        if (changes != 0) {
20142            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20143                    "Changes in " + app + ": " + changes);
20144            int i = mPendingProcessChanges.size()-1;
20145            ProcessChangeItem item = null;
20146            while (i >= 0) {
20147                item = mPendingProcessChanges.get(i);
20148                if (item.pid == app.pid) {
20149                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20150                            "Re-using existing item: " + item);
20151                    break;
20152                }
20153                i--;
20154            }
20155            if (i < 0) {
20156                // No existing item in pending changes; need a new one.
20157                final int NA = mAvailProcessChanges.size();
20158                if (NA > 0) {
20159                    item = mAvailProcessChanges.remove(NA-1);
20160                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20161                            "Retrieving available item: " + item);
20162                } else {
20163                    item = new ProcessChangeItem();
20164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20165                            "Allocating new item: " + item);
20166                }
20167                item.changes = 0;
20168                item.pid = app.pid;
20169                item.uid = app.info.uid;
20170                if (mPendingProcessChanges.size() == 0) {
20171                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20172                            "*** Enqueueing dispatch processes changed!");
20173                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20174                }
20175                mPendingProcessChanges.add(item);
20176            }
20177            item.changes |= changes;
20178            item.processState = app.repProcState;
20179            item.foregroundActivities = app.repForegroundActivities;
20180            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20181                    "Item " + Integer.toHexString(System.identityHashCode(item))
20182                    + " " + app.toShortString() + ": changes=" + item.changes
20183                    + " procState=" + item.processState
20184                    + " foreground=" + item.foregroundActivities
20185                    + " type=" + app.adjType + " source=" + app.adjSource
20186                    + " target=" + app.adjTarget);
20187        }
20188
20189        return success;
20190    }
20191
20192    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20193        final UidRecord.ChangeItem pendingChange;
20194        if (uidRec == null || uidRec.pendingChange == null) {
20195            if (mPendingUidChanges.size() == 0) {
20196                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20197                        "*** Enqueueing dispatch uid changed!");
20198                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20199            }
20200            final int NA = mAvailUidChanges.size();
20201            if (NA > 0) {
20202                pendingChange = mAvailUidChanges.remove(NA-1);
20203                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20204                        "Retrieving available item: " + pendingChange);
20205            } else {
20206                pendingChange = new UidRecord.ChangeItem();
20207                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20208                        "Allocating new item: " + pendingChange);
20209            }
20210            if (uidRec != null) {
20211                uidRec.pendingChange = pendingChange;
20212                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20213                    // If this uid is going away, and we haven't yet reported it is gone,
20214                    // then do so now.
20215                    change = UidRecord.CHANGE_GONE_IDLE;
20216                }
20217            } else if (uid < 0) {
20218                throw new IllegalArgumentException("No UidRecord or uid");
20219            }
20220            pendingChange.uidRecord = uidRec;
20221            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20222            mPendingUidChanges.add(pendingChange);
20223        } else {
20224            pendingChange = uidRec.pendingChange;
20225            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20226                change = UidRecord.CHANGE_GONE_IDLE;
20227            }
20228        }
20229        pendingChange.change = change;
20230        pendingChange.processState = uidRec != null
20231                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20232    }
20233
20234    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20235            String authority) {
20236        if (app == null) return;
20237        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20238            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20239            if (userState == null) return;
20240            final long now = SystemClock.elapsedRealtime();
20241            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20242            if (lastReported == null || lastReported < now - 60 * 1000L) {
20243                mUsageStatsService.reportContentProviderUsage(
20244                        authority, providerPkgName, app.userId);
20245                userState.mProviderLastReportedFg.put(authority, now);
20246            }
20247        }
20248    }
20249
20250    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20251        if (DEBUG_USAGE_STATS) {
20252            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20253                    + "] state changes: old = " + app.setProcState + ", new = "
20254                    + app.curProcState);
20255        }
20256        if (mUsageStatsService == null) {
20257            return;
20258        }
20259        boolean isInteraction;
20260        // To avoid some abuse patterns, we are going to be careful about what we consider
20261        // to be an app interaction.  Being the top activity doesn't count while the display
20262        // is sleeping, nor do short foreground services.
20263        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20264            isInteraction = true;
20265            app.fgInteractionTime = 0;
20266        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20267            if (app.fgInteractionTime == 0) {
20268                app.fgInteractionTime = nowElapsed;
20269                isInteraction = false;
20270            } else {
20271                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20272            }
20273        } else {
20274            isInteraction = app.curProcState
20275                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20276            app.fgInteractionTime = 0;
20277        }
20278        if (isInteraction && (!app.reportedInteraction
20279                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20280            app.interactionEventTime = nowElapsed;
20281            String[] packages = app.getPackageList();
20282            if (packages != null) {
20283                for (int i = 0; i < packages.length; i++) {
20284                    mUsageStatsService.reportEvent(packages[i], app.userId,
20285                            UsageEvents.Event.SYSTEM_INTERACTION);
20286                }
20287            }
20288        }
20289        app.reportedInteraction = isInteraction;
20290        if (!isInteraction) {
20291            app.interactionEventTime = 0;
20292        }
20293    }
20294
20295    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20296        if (proc.thread != null) {
20297            if (proc.baseProcessTracker != null) {
20298                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20299            }
20300        }
20301    }
20302
20303    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20304            ProcessRecord TOP_APP, boolean doingAll, long now) {
20305        if (app.thread == null) {
20306            return false;
20307        }
20308
20309        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20310
20311        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20312    }
20313
20314    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20315            boolean oomAdj) {
20316        if (isForeground != proc.foregroundServices) {
20317            proc.foregroundServices = isForeground;
20318            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20319                    proc.info.uid);
20320            if (isForeground) {
20321                if (curProcs == null) {
20322                    curProcs = new ArrayList<ProcessRecord>();
20323                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20324                }
20325                if (!curProcs.contains(proc)) {
20326                    curProcs.add(proc);
20327                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20328                            proc.info.packageName, proc.info.uid);
20329                }
20330            } else {
20331                if (curProcs != null) {
20332                    if (curProcs.remove(proc)) {
20333                        mBatteryStatsService.noteEvent(
20334                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20335                                proc.info.packageName, proc.info.uid);
20336                        if (curProcs.size() <= 0) {
20337                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20338                        }
20339                    }
20340                }
20341            }
20342            if (oomAdj) {
20343                updateOomAdjLocked();
20344            }
20345        }
20346    }
20347
20348    private final ActivityRecord resumedAppLocked() {
20349        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20350        String pkg;
20351        int uid;
20352        if (act != null) {
20353            pkg = act.packageName;
20354            uid = act.info.applicationInfo.uid;
20355        } else {
20356            pkg = null;
20357            uid = -1;
20358        }
20359        // Has the UID or resumed package name changed?
20360        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20361                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20362            if (mCurResumedPackage != null) {
20363                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20364                        mCurResumedPackage, mCurResumedUid);
20365            }
20366            mCurResumedPackage = pkg;
20367            mCurResumedUid = uid;
20368            if (mCurResumedPackage != null) {
20369                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20370                        mCurResumedPackage, mCurResumedUid);
20371            }
20372        }
20373        return act;
20374    }
20375
20376    final boolean updateOomAdjLocked(ProcessRecord app) {
20377        final ActivityRecord TOP_ACT = resumedAppLocked();
20378        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20379        final boolean wasCached = app.cached;
20380
20381        mAdjSeq++;
20382
20383        // This is the desired cached adjusment we want to tell it to use.
20384        // If our app is currently cached, we know it, and that is it.  Otherwise,
20385        // we don't know it yet, and it needs to now be cached we will then
20386        // need to do a complete oom adj.
20387        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20388                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20389        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20390                SystemClock.uptimeMillis());
20391        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20392            // Changed to/from cached state, so apps after it in the LRU
20393            // list may also be changed.
20394            updateOomAdjLocked();
20395        }
20396        return success;
20397    }
20398
20399    final void updateOomAdjLocked() {
20400        final ActivityRecord TOP_ACT = resumedAppLocked();
20401        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20402        final long now = SystemClock.uptimeMillis();
20403        final long nowElapsed = SystemClock.elapsedRealtime();
20404        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20405        final int N = mLruProcesses.size();
20406
20407        if (false) {
20408            RuntimeException e = new RuntimeException();
20409            e.fillInStackTrace();
20410            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20411        }
20412
20413        // Reset state in all uid records.
20414        for (int i=mActiveUids.size()-1; i>=0; i--) {
20415            final UidRecord uidRec = mActiveUids.valueAt(i);
20416            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20417                    "Starting update of " + uidRec);
20418            uidRec.reset();
20419        }
20420
20421        mStackSupervisor.rankTaskLayersIfNeeded();
20422
20423        mAdjSeq++;
20424        mNewNumServiceProcs = 0;
20425        mNewNumAServiceProcs = 0;
20426
20427        final int emptyProcessLimit;
20428        final int cachedProcessLimit;
20429        if (mProcessLimit <= 0) {
20430            emptyProcessLimit = cachedProcessLimit = 0;
20431        } else if (mProcessLimit == 1) {
20432            emptyProcessLimit = 1;
20433            cachedProcessLimit = 0;
20434        } else {
20435            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20436            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20437        }
20438
20439        // Let's determine how many processes we have running vs.
20440        // how many slots we have for background processes; we may want
20441        // to put multiple processes in a slot of there are enough of
20442        // them.
20443        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20444                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20445        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20446        if (numEmptyProcs > cachedProcessLimit) {
20447            // If there are more empty processes than our limit on cached
20448            // processes, then use the cached process limit for the factor.
20449            // This ensures that the really old empty processes get pushed
20450            // down to the bottom, so if we are running low on memory we will
20451            // have a better chance at keeping around more cached processes
20452            // instead of a gazillion empty processes.
20453            numEmptyProcs = cachedProcessLimit;
20454        }
20455        int emptyFactor = numEmptyProcs/numSlots;
20456        if (emptyFactor < 1) emptyFactor = 1;
20457        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20458        if (cachedFactor < 1) cachedFactor = 1;
20459        int stepCached = 0;
20460        int stepEmpty = 0;
20461        int numCached = 0;
20462        int numEmpty = 0;
20463        int numTrimming = 0;
20464
20465        mNumNonCachedProcs = 0;
20466        mNumCachedHiddenProcs = 0;
20467
20468        // First update the OOM adjustment for each of the
20469        // application processes based on their current state.
20470        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20471        int nextCachedAdj = curCachedAdj+1;
20472        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20473        int nextEmptyAdj = curEmptyAdj+2;
20474        for (int i=N-1; i>=0; i--) {
20475            ProcessRecord app = mLruProcesses.get(i);
20476            if (!app.killedByAm && app.thread != null) {
20477                app.procStateChanged = false;
20478                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20479
20480                // If we haven't yet assigned the final cached adj
20481                // to the process, do that now.
20482                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20483                    switch (app.curProcState) {
20484                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20485                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20486                            // This process is a cached process holding activities...
20487                            // assign it the next cached value for that type, and then
20488                            // step that cached level.
20489                            app.curRawAdj = curCachedAdj;
20490                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20491                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20492                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20493                                    + ")");
20494                            if (curCachedAdj != nextCachedAdj) {
20495                                stepCached++;
20496                                if (stepCached >= cachedFactor) {
20497                                    stepCached = 0;
20498                                    curCachedAdj = nextCachedAdj;
20499                                    nextCachedAdj += 2;
20500                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20501                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20502                                    }
20503                                }
20504                            }
20505                            break;
20506                        default:
20507                            // For everything else, assign next empty cached process
20508                            // level and bump that up.  Note that this means that
20509                            // long-running services that have dropped down to the
20510                            // cached level will be treated as empty (since their process
20511                            // state is still as a service), which is what we want.
20512                            app.curRawAdj = curEmptyAdj;
20513                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20514                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20515                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20516                                    + ")");
20517                            if (curEmptyAdj != nextEmptyAdj) {
20518                                stepEmpty++;
20519                                if (stepEmpty >= emptyFactor) {
20520                                    stepEmpty = 0;
20521                                    curEmptyAdj = nextEmptyAdj;
20522                                    nextEmptyAdj += 2;
20523                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20524                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20525                                    }
20526                                }
20527                            }
20528                            break;
20529                    }
20530                }
20531
20532                applyOomAdjLocked(app, true, now, nowElapsed);
20533
20534                // Count the number of process types.
20535                switch (app.curProcState) {
20536                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20537                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20538                        mNumCachedHiddenProcs++;
20539                        numCached++;
20540                        if (numCached > cachedProcessLimit) {
20541                            app.kill("cached #" + numCached, true);
20542                        }
20543                        break;
20544                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20545                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20546                                && app.lastActivityTime < oldTime) {
20547                            app.kill("empty for "
20548                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20549                                    / 1000) + "s", true);
20550                        } else {
20551                            numEmpty++;
20552                            if (numEmpty > emptyProcessLimit) {
20553                                app.kill("empty #" + numEmpty, true);
20554                            }
20555                        }
20556                        break;
20557                    default:
20558                        mNumNonCachedProcs++;
20559                        break;
20560                }
20561
20562                if (app.isolated && app.services.size() <= 0) {
20563                    // If this is an isolated process, and there are no
20564                    // services running in it, then the process is no longer
20565                    // needed.  We agressively kill these because we can by
20566                    // definition not re-use the same process again, and it is
20567                    // good to avoid having whatever code was running in them
20568                    // left sitting around after no longer needed.
20569                    app.kill("isolated not needed", true);
20570                } else {
20571                    // Keeping this process, update its uid.
20572                    final UidRecord uidRec = app.uidRecord;
20573                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20574                        uidRec.curProcState = app.curProcState;
20575                    }
20576                }
20577
20578                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20579                        && !app.killedByAm) {
20580                    numTrimming++;
20581                }
20582            }
20583        }
20584
20585        mNumServiceProcs = mNewNumServiceProcs;
20586
20587        // Now determine the memory trimming level of background processes.
20588        // Unfortunately we need to start at the back of the list to do this
20589        // properly.  We only do this if the number of background apps we
20590        // are managing to keep around is less than half the maximum we desire;
20591        // if we are keeping a good number around, we'll let them use whatever
20592        // memory they want.
20593        final int numCachedAndEmpty = numCached + numEmpty;
20594        int memFactor;
20595        if (numCached <= ProcessList.TRIM_CACHED_APPS
20596                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20597            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20598                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20599            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20600                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20601            } else {
20602                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20603            }
20604        } else {
20605            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20606        }
20607        // We always allow the memory level to go up (better).  We only allow it to go
20608        // down if we are in a state where that is allowed, *and* the total number of processes
20609        // has gone down since last time.
20610        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20611                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20612                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20613        if (memFactor > mLastMemoryLevel) {
20614            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20615                memFactor = mLastMemoryLevel;
20616                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20617            }
20618        }
20619        if (memFactor != mLastMemoryLevel) {
20620            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20621        }
20622        mLastMemoryLevel = memFactor;
20623        mLastNumProcesses = mLruProcesses.size();
20624        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20625        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20626        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20627            if (mLowRamStartTime == 0) {
20628                mLowRamStartTime = now;
20629            }
20630            int step = 0;
20631            int fgTrimLevel;
20632            switch (memFactor) {
20633                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20634                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20635                    break;
20636                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20637                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20638                    break;
20639                default:
20640                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20641                    break;
20642            }
20643            int factor = numTrimming/3;
20644            int minFactor = 2;
20645            if (mHomeProcess != null) minFactor++;
20646            if (mPreviousProcess != null) minFactor++;
20647            if (factor < minFactor) factor = minFactor;
20648            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20649            for (int i=N-1; i>=0; i--) {
20650                ProcessRecord app = mLruProcesses.get(i);
20651                if (allChanged || app.procStateChanged) {
20652                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20653                    app.procStateChanged = false;
20654                }
20655                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20656                        && !app.killedByAm) {
20657                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20658                        try {
20659                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20660                                    "Trimming memory of " + app.processName + " to " + curLevel);
20661                            app.thread.scheduleTrimMemory(curLevel);
20662                        } catch (RemoteException e) {
20663                        }
20664                        if (false) {
20665                            // For now we won't do this; our memory trimming seems
20666                            // to be good enough at this point that destroying
20667                            // activities causes more harm than good.
20668                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20669                                    && app != mHomeProcess && app != mPreviousProcess) {
20670                                // Need to do this on its own message because the stack may not
20671                                // be in a consistent state at this point.
20672                                // For these apps we will also finish their activities
20673                                // to help them free memory.
20674                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20675                            }
20676                        }
20677                    }
20678                    app.trimMemoryLevel = curLevel;
20679                    step++;
20680                    if (step >= factor) {
20681                        step = 0;
20682                        switch (curLevel) {
20683                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20684                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20685                                break;
20686                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20687                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20688                                break;
20689                        }
20690                    }
20691                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20692                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20693                            && app.thread != null) {
20694                        try {
20695                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20696                                    "Trimming memory of heavy-weight " + app.processName
20697                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20698                            app.thread.scheduleTrimMemory(
20699                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20700                        } catch (RemoteException e) {
20701                        }
20702                    }
20703                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20704                } else {
20705                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20706                            || app.systemNoUi) && app.pendingUiClean) {
20707                        // If this application is now in the background and it
20708                        // had done UI, then give it the special trim level to
20709                        // have it free UI resources.
20710                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20711                        if (app.trimMemoryLevel < level && app.thread != null) {
20712                            try {
20713                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20714                                        "Trimming memory of bg-ui " + app.processName
20715                                        + " to " + level);
20716                                app.thread.scheduleTrimMemory(level);
20717                            } catch (RemoteException e) {
20718                            }
20719                        }
20720                        app.pendingUiClean = false;
20721                    }
20722                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20723                        try {
20724                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20725                                    "Trimming memory of fg " + app.processName
20726                                    + " to " + fgTrimLevel);
20727                            app.thread.scheduleTrimMemory(fgTrimLevel);
20728                        } catch (RemoteException e) {
20729                        }
20730                    }
20731                    app.trimMemoryLevel = fgTrimLevel;
20732                }
20733            }
20734        } else {
20735            if (mLowRamStartTime != 0) {
20736                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20737                mLowRamStartTime = 0;
20738            }
20739            for (int i=N-1; i>=0; i--) {
20740                ProcessRecord app = mLruProcesses.get(i);
20741                if (allChanged || app.procStateChanged) {
20742                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20743                    app.procStateChanged = false;
20744                }
20745                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20746                        || app.systemNoUi) && app.pendingUiClean) {
20747                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20748                            && app.thread != null) {
20749                        try {
20750                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20751                                    "Trimming memory of ui hidden " + app.processName
20752                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20753                            app.thread.scheduleTrimMemory(
20754                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20755                        } catch (RemoteException e) {
20756                        }
20757                    }
20758                    app.pendingUiClean = false;
20759                }
20760                app.trimMemoryLevel = 0;
20761            }
20762        }
20763
20764        if (mAlwaysFinishActivities) {
20765            // Need to do this on its own message because the stack may not
20766            // be in a consistent state at this point.
20767            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20768        }
20769
20770        if (allChanged) {
20771            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20772        }
20773
20774        // Update from any uid changes.
20775        for (int i=mActiveUids.size()-1; i>=0; i--) {
20776            final UidRecord uidRec = mActiveUids.valueAt(i);
20777            int uidChange = UidRecord.CHANGE_PROCSTATE;
20778            if (uidRec.setProcState != uidRec.curProcState) {
20779                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20780                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20781                        + " to " + uidRec.curProcState);
20782                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20783                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20784                        uidRec.lastBackgroundTime = nowElapsed;
20785                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20786                            // Note: the background settle time is in elapsed realtime, while
20787                            // the handler time base is uptime.  All this means is that we may
20788                            // stop background uids later than we had intended, but that only
20789                            // happens because the device was sleeping so we are okay anyway.
20790                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20791                        }
20792                    }
20793                } else {
20794                    if (uidRec.idle) {
20795                        uidChange = UidRecord.CHANGE_ACTIVE;
20796                        uidRec.idle = false;
20797                    }
20798                    uidRec.lastBackgroundTime = 0;
20799                }
20800                uidRec.setProcState = uidRec.curProcState;
20801                enqueueUidChangeLocked(uidRec, -1, uidChange);
20802                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20803            }
20804        }
20805
20806        if (mProcessStats.shouldWriteNowLocked(now)) {
20807            mHandler.post(new Runnable() {
20808                @Override public void run() {
20809                    synchronized (ActivityManagerService.this) {
20810                        mProcessStats.writeStateAsyncLocked();
20811                    }
20812                }
20813            });
20814        }
20815
20816        if (DEBUG_OOM_ADJ) {
20817            final long duration = SystemClock.uptimeMillis() - now;
20818            if (false) {
20819                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20820                        new RuntimeException("here").fillInStackTrace());
20821            } else {
20822                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20823            }
20824        }
20825    }
20826
20827    final void idleUids() {
20828        synchronized (this) {
20829            final long nowElapsed = SystemClock.elapsedRealtime();
20830            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20831            long nextTime = 0;
20832            for (int i=mActiveUids.size()-1; i>=0; i--) {
20833                final UidRecord uidRec = mActiveUids.valueAt(i);
20834                final long bgTime = uidRec.lastBackgroundTime;
20835                if (bgTime > 0 && !uidRec.idle) {
20836                    if (bgTime <= maxBgTime) {
20837                        uidRec.idle = true;
20838                        doStopUidLocked(uidRec.uid, uidRec);
20839                    } else {
20840                        if (nextTime == 0 || nextTime > bgTime) {
20841                            nextTime = bgTime;
20842                        }
20843                    }
20844                }
20845            }
20846            if (nextTime > 0) {
20847                mHandler.removeMessages(IDLE_UIDS_MSG);
20848                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20849                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20850            }
20851        }
20852    }
20853
20854    final void runInBackgroundDisabled(int uid) {
20855        synchronized (this) {
20856            UidRecord uidRec = mActiveUids.get(uid);
20857            if (uidRec != null) {
20858                // This uid is actually running...  should it be considered background now?
20859                if (uidRec.idle) {
20860                    doStopUidLocked(uidRec.uid, uidRec);
20861                }
20862            } else {
20863                // This uid isn't actually running...  still send a report about it being "stopped".
20864                doStopUidLocked(uid, null);
20865            }
20866        }
20867    }
20868
20869    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20870        mServices.stopInBackgroundLocked(uid);
20871        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20872    }
20873
20874    final void trimApplications() {
20875        synchronized (this) {
20876            int i;
20877
20878            // First remove any unused application processes whose package
20879            // has been removed.
20880            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20881                final ProcessRecord app = mRemovedProcesses.get(i);
20882                if (app.activities.size() == 0
20883                        && app.curReceiver == null && app.services.size() == 0) {
20884                    Slog.i(
20885                        TAG, "Exiting empty application process "
20886                        + app.toShortString() + " ("
20887                        + (app.thread != null ? app.thread.asBinder() : null)
20888                        + ")\n");
20889                    if (app.pid > 0 && app.pid != MY_PID) {
20890                        app.kill("empty", false);
20891                    } else {
20892                        try {
20893                            app.thread.scheduleExit();
20894                        } catch (Exception e) {
20895                            // Ignore exceptions.
20896                        }
20897                    }
20898                    cleanUpApplicationRecordLocked(app, false, true, -1);
20899                    mRemovedProcesses.remove(i);
20900
20901                    if (app.persistent) {
20902                        addAppLocked(app.info, false, null /* ABI override */);
20903                    }
20904                }
20905            }
20906
20907            // Now update the oom adj for all processes.
20908            updateOomAdjLocked();
20909        }
20910    }
20911
20912    /** This method sends the specified signal to each of the persistent apps */
20913    public void signalPersistentProcesses(int sig) throws RemoteException {
20914        if (sig != Process.SIGNAL_USR1) {
20915            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20916        }
20917
20918        synchronized (this) {
20919            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20920                    != PackageManager.PERMISSION_GRANTED) {
20921                throw new SecurityException("Requires permission "
20922                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20923            }
20924
20925            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20926                ProcessRecord r = mLruProcesses.get(i);
20927                if (r.thread != null && r.persistent) {
20928                    Process.sendSignal(r.pid, sig);
20929                }
20930            }
20931        }
20932    }
20933
20934    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20935        if (proc == null || proc == mProfileProc) {
20936            proc = mProfileProc;
20937            profileType = mProfileType;
20938            clearProfilerLocked();
20939        }
20940        if (proc == null) {
20941            return;
20942        }
20943        try {
20944            proc.thread.profilerControl(false, null, profileType);
20945        } catch (RemoteException e) {
20946            throw new IllegalStateException("Process disappeared");
20947        }
20948    }
20949
20950    private void clearProfilerLocked() {
20951        if (mProfileFd != null) {
20952            try {
20953                mProfileFd.close();
20954            } catch (IOException e) {
20955            }
20956        }
20957        mProfileApp = null;
20958        mProfileProc = null;
20959        mProfileFile = null;
20960        mProfileType = 0;
20961        mAutoStopProfiler = false;
20962        mSamplingInterval = 0;
20963    }
20964
20965    public boolean profileControl(String process, int userId, boolean start,
20966            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20967
20968        try {
20969            synchronized (this) {
20970                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20971                // its own permission.
20972                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20973                        != PackageManager.PERMISSION_GRANTED) {
20974                    throw new SecurityException("Requires permission "
20975                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20976                }
20977
20978                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20979                    throw new IllegalArgumentException("null profile info or fd");
20980                }
20981
20982                ProcessRecord proc = null;
20983                if (process != null) {
20984                    proc = findProcessLocked(process, userId, "profileControl");
20985                }
20986
20987                if (start && (proc == null || proc.thread == null)) {
20988                    throw new IllegalArgumentException("Unknown process: " + process);
20989                }
20990
20991                if (start) {
20992                    stopProfilerLocked(null, 0);
20993                    setProfileApp(proc.info, proc.processName, profilerInfo);
20994                    mProfileProc = proc;
20995                    mProfileType = profileType;
20996                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20997                    try {
20998                        fd = fd.dup();
20999                    } catch (IOException e) {
21000                        fd = null;
21001                    }
21002                    profilerInfo.profileFd = fd;
21003                    proc.thread.profilerControl(start, profilerInfo, profileType);
21004                    fd = null;
21005                    mProfileFd = null;
21006                } else {
21007                    stopProfilerLocked(proc, profileType);
21008                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21009                        try {
21010                            profilerInfo.profileFd.close();
21011                        } catch (IOException e) {
21012                        }
21013                    }
21014                }
21015
21016                return true;
21017            }
21018        } catch (RemoteException e) {
21019            throw new IllegalStateException("Process disappeared");
21020        } finally {
21021            if (profilerInfo != null && profilerInfo.profileFd != null) {
21022                try {
21023                    profilerInfo.profileFd.close();
21024                } catch (IOException e) {
21025                }
21026            }
21027        }
21028    }
21029
21030    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21031        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21032                userId, true, ALLOW_FULL_ONLY, callName, null);
21033        ProcessRecord proc = null;
21034        try {
21035            int pid = Integer.parseInt(process);
21036            synchronized (mPidsSelfLocked) {
21037                proc = mPidsSelfLocked.get(pid);
21038            }
21039        } catch (NumberFormatException e) {
21040        }
21041
21042        if (proc == null) {
21043            ArrayMap<String, SparseArray<ProcessRecord>> all
21044                    = mProcessNames.getMap();
21045            SparseArray<ProcessRecord> procs = all.get(process);
21046            if (procs != null && procs.size() > 0) {
21047                proc = procs.valueAt(0);
21048                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21049                    for (int i=1; i<procs.size(); i++) {
21050                        ProcessRecord thisProc = procs.valueAt(i);
21051                        if (thisProc.userId == userId) {
21052                            proc = thisProc;
21053                            break;
21054                        }
21055                    }
21056                }
21057            }
21058        }
21059
21060        return proc;
21061    }
21062
21063    public boolean dumpHeap(String process, int userId, boolean managed,
21064            String path, ParcelFileDescriptor fd) throws RemoteException {
21065
21066        try {
21067            synchronized (this) {
21068                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21069                // its own permission (same as profileControl).
21070                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21071                        != PackageManager.PERMISSION_GRANTED) {
21072                    throw new SecurityException("Requires permission "
21073                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21074                }
21075
21076                if (fd == null) {
21077                    throw new IllegalArgumentException("null fd");
21078                }
21079
21080                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21081                if (proc == null || proc.thread == null) {
21082                    throw new IllegalArgumentException("Unknown process: " + process);
21083                }
21084
21085                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21086                if (!isDebuggable) {
21087                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21088                        throw new SecurityException("Process not debuggable: " + proc);
21089                    }
21090                }
21091
21092                proc.thread.dumpHeap(managed, path, fd);
21093                fd = null;
21094                return true;
21095            }
21096        } catch (RemoteException e) {
21097            throw new IllegalStateException("Process disappeared");
21098        } finally {
21099            if (fd != null) {
21100                try {
21101                    fd.close();
21102                } catch (IOException e) {
21103                }
21104            }
21105        }
21106    }
21107
21108    @Override
21109    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21110            String reportPackage) {
21111        if (processName != null) {
21112            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21113                    "setDumpHeapDebugLimit()");
21114        } else {
21115            synchronized (mPidsSelfLocked) {
21116                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21117                if (proc == null) {
21118                    throw new SecurityException("No process found for calling pid "
21119                            + Binder.getCallingPid());
21120                }
21121                if (!Build.IS_DEBUGGABLE
21122                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21123                    throw new SecurityException("Not running a debuggable build");
21124                }
21125                processName = proc.processName;
21126                uid = proc.uid;
21127                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21128                    throw new SecurityException("Package " + reportPackage + " is not running in "
21129                            + proc);
21130                }
21131            }
21132        }
21133        synchronized (this) {
21134            if (maxMemSize > 0) {
21135                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21136            } else {
21137                if (uid != 0) {
21138                    mMemWatchProcesses.remove(processName, uid);
21139                } else {
21140                    mMemWatchProcesses.getMap().remove(processName);
21141                }
21142            }
21143        }
21144    }
21145
21146    @Override
21147    public void dumpHeapFinished(String path) {
21148        synchronized (this) {
21149            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21150                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21151                        + " does not match last pid " + mMemWatchDumpPid);
21152                return;
21153            }
21154            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21155                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21156                        + " does not match last path " + mMemWatchDumpFile);
21157                return;
21158            }
21159            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21160            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21161        }
21162    }
21163
21164    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21165    public void monitor() {
21166        synchronized (this) { }
21167    }
21168
21169    void onCoreSettingsChange(Bundle settings) {
21170        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21171            ProcessRecord processRecord = mLruProcesses.get(i);
21172            try {
21173                if (processRecord.thread != null) {
21174                    processRecord.thread.setCoreSettings(settings);
21175                }
21176            } catch (RemoteException re) {
21177                /* ignore */
21178            }
21179        }
21180    }
21181
21182    // Multi-user methods
21183
21184    /**
21185     * Start user, if its not already running, but don't bring it to foreground.
21186     */
21187    @Override
21188    public boolean startUserInBackground(final int userId) {
21189        return mUserController.startUser(userId, /* foreground */ false);
21190    }
21191
21192    @Override
21193    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21194        return mUserController.unlockUser(userId, token, secret, listener);
21195    }
21196
21197    @Override
21198    public boolean switchUser(final int targetUserId) {
21199        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21200        UserInfo currentUserInfo;
21201        UserInfo targetUserInfo;
21202        synchronized (this) {
21203            int currentUserId = mUserController.getCurrentUserIdLocked();
21204            currentUserInfo = mUserController.getUserInfo(currentUserId);
21205            targetUserInfo = mUserController.getUserInfo(targetUserId);
21206            if (targetUserInfo == null) {
21207                Slog.w(TAG, "No user info for user #" + targetUserId);
21208                return false;
21209            }
21210            if (!targetUserInfo.supportsSwitchTo()) {
21211                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21212                return false;
21213            }
21214            if (targetUserInfo.isManagedProfile()) {
21215                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21216                return false;
21217            }
21218            mUserController.setTargetUserIdLocked(targetUserId);
21219        }
21220        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21221        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21222        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21223        return true;
21224    }
21225
21226    void scheduleStartProfilesLocked() {
21227        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21228            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21229                    DateUtils.SECOND_IN_MILLIS);
21230        }
21231    }
21232
21233    @Override
21234    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21235        return mUserController.stopUser(userId, force, callback);
21236    }
21237
21238    @Override
21239    public UserInfo getCurrentUser() {
21240        return mUserController.getCurrentUser();
21241    }
21242
21243    @Override
21244    public boolean isUserRunning(int userId, int flags) {
21245        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21246                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21247            String msg = "Permission Denial: isUserRunning() from pid="
21248                    + Binder.getCallingPid()
21249                    + ", uid=" + Binder.getCallingUid()
21250                    + " requires " + INTERACT_ACROSS_USERS;
21251            Slog.w(TAG, msg);
21252            throw new SecurityException(msg);
21253        }
21254        synchronized (this) {
21255            return mUserController.isUserRunningLocked(userId, flags);
21256        }
21257    }
21258
21259    @Override
21260    public int[] getRunningUserIds() {
21261        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21262                != PackageManager.PERMISSION_GRANTED) {
21263            String msg = "Permission Denial: isUserRunning() from pid="
21264                    + Binder.getCallingPid()
21265                    + ", uid=" + Binder.getCallingUid()
21266                    + " requires " + INTERACT_ACROSS_USERS;
21267            Slog.w(TAG, msg);
21268            throw new SecurityException(msg);
21269        }
21270        synchronized (this) {
21271            return mUserController.getStartedUserArrayLocked();
21272        }
21273    }
21274
21275    @Override
21276    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21277        mUserController.registerUserSwitchObserver(observer);
21278    }
21279
21280    @Override
21281    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21282        mUserController.unregisterUserSwitchObserver(observer);
21283    }
21284
21285    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21286        if (info == null) return null;
21287        ApplicationInfo newInfo = new ApplicationInfo(info);
21288        newInfo.initForUser(userId);
21289        return newInfo;
21290    }
21291
21292    public boolean isUserStopped(int userId) {
21293        synchronized (this) {
21294            return mUserController.getStartedUserStateLocked(userId) == null;
21295        }
21296    }
21297
21298    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21299        if (aInfo == null
21300                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21301            return aInfo;
21302        }
21303
21304        ActivityInfo info = new ActivityInfo(aInfo);
21305        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21306        return info;
21307    }
21308
21309    private boolean processSanityChecksLocked(ProcessRecord process) {
21310        if (process == null || process.thread == null) {
21311            return false;
21312        }
21313
21314        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21315        if (!isDebuggable) {
21316            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21317                return false;
21318            }
21319        }
21320
21321        return true;
21322    }
21323
21324    public boolean startBinderTracking() throws RemoteException {
21325        synchronized (this) {
21326            mBinderTransactionTrackingEnabled = true;
21327            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21328            // permission (same as profileControl).
21329            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21330                    != PackageManager.PERMISSION_GRANTED) {
21331                throw new SecurityException("Requires permission "
21332                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21333            }
21334
21335            for (int i = 0; i < mLruProcesses.size(); i++) {
21336                ProcessRecord process = mLruProcesses.get(i);
21337                if (!processSanityChecksLocked(process)) {
21338                    continue;
21339                }
21340                try {
21341                    process.thread.startBinderTracking();
21342                } catch (RemoteException e) {
21343                    Log.v(TAG, "Process disappared");
21344                }
21345            }
21346            return true;
21347        }
21348    }
21349
21350    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21351        try {
21352            synchronized (this) {
21353                mBinderTransactionTrackingEnabled = false;
21354                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21355                // permission (same as profileControl).
21356                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21357                        != PackageManager.PERMISSION_GRANTED) {
21358                    throw new SecurityException("Requires permission "
21359                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21360                }
21361
21362                if (fd == null) {
21363                    throw new IllegalArgumentException("null fd");
21364                }
21365
21366                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21367                pw.println("Binder transaction traces for all processes.\n");
21368                for (ProcessRecord process : mLruProcesses) {
21369                    if (!processSanityChecksLocked(process)) {
21370                        continue;
21371                    }
21372
21373                    pw.println("Traces for process: " + process.processName);
21374                    pw.flush();
21375                    try {
21376                        TransferPipe tp = new TransferPipe();
21377                        try {
21378                            process.thread.stopBinderTrackingAndDump(
21379                                    tp.getWriteFd().getFileDescriptor());
21380                            tp.go(fd.getFileDescriptor());
21381                        } finally {
21382                            tp.kill();
21383                        }
21384                    } catch (IOException e) {
21385                        pw.println("Failure while dumping IPC traces from " + process +
21386                                ".  Exception: " + e);
21387                        pw.flush();
21388                    } catch (RemoteException e) {
21389                        pw.println("Got a RemoteException while dumping IPC traces from " +
21390                                process + ".  Exception: " + e);
21391                        pw.flush();
21392                    }
21393                }
21394                fd = null;
21395                return true;
21396            }
21397        } finally {
21398            if (fd != null) {
21399                try {
21400                    fd.close();
21401                } catch (IOException e) {
21402                }
21403            }
21404        }
21405    }
21406
21407    private final class LocalService extends ActivityManagerInternal {
21408        @Override
21409        public void onWakefulnessChanged(int wakefulness) {
21410            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21411        }
21412
21413        @Override
21414        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21415                String processName, String abiOverride, int uid, Runnable crashHandler) {
21416            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21417                    processName, abiOverride, uid, crashHandler);
21418        }
21419
21420        @Override
21421        public SleepToken acquireSleepToken(String tag) {
21422            Preconditions.checkNotNull(tag);
21423
21424            ComponentName requestedVrService = null;
21425            ComponentName callingVrActivity = null;
21426            int userId = -1;
21427            synchronized (ActivityManagerService.this) {
21428                if (mFocusedActivity != null) {
21429                    requestedVrService = mFocusedActivity.requestedVrComponent;
21430                    callingVrActivity = mFocusedActivity.info.getComponentName();
21431                    userId = mFocusedActivity.userId;
21432                }
21433            }
21434
21435            if (requestedVrService != null) {
21436                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21437            }
21438
21439            synchronized (ActivityManagerService.this) {
21440                SleepTokenImpl token = new SleepTokenImpl(tag);
21441                mSleepTokens.add(token);
21442                updateSleepIfNeededLocked();
21443                return token;
21444            }
21445        }
21446
21447        @Override
21448        public ComponentName getHomeActivityForUser(int userId) {
21449            synchronized (ActivityManagerService.this) {
21450                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21451                return homeActivity == null ? null : homeActivity.realActivity;
21452            }
21453        }
21454
21455        @Override
21456        public void onUserRemoved(int userId) {
21457            synchronized (ActivityManagerService.this) {
21458                ActivityManagerService.this.onUserStoppedLocked(userId);
21459            }
21460        }
21461
21462        @Override
21463        public void onLocalVoiceInteractionStarted(IBinder activity,
21464                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21465            synchronized (ActivityManagerService.this) {
21466                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21467                        voiceSession, voiceInteractor);
21468            }
21469        }
21470
21471        @Override
21472        public void notifyStartingWindowDrawn() {
21473            synchronized (ActivityManagerService.this) {
21474                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21475            }
21476        }
21477
21478        @Override
21479        public void notifyAppTransitionStarting(int reason) {
21480            synchronized (ActivityManagerService.this) {
21481                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21482            }
21483        }
21484
21485        @Override
21486        public void notifyAppTransitionFinished() {
21487            synchronized (ActivityManagerService.this) {
21488                mStackSupervisor.notifyAppTransitionDone();
21489            }
21490        }
21491
21492        @Override
21493        public void notifyAppTransitionCancelled() {
21494            synchronized (ActivityManagerService.this) {
21495                mStackSupervisor.notifyAppTransitionDone();
21496            }
21497        }
21498
21499        @Override
21500        public List<IBinder> getTopVisibleActivities() {
21501            synchronized (ActivityManagerService.this) {
21502                return mStackSupervisor.getTopVisibleActivities();
21503            }
21504        }
21505
21506        @Override
21507        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21508            synchronized (ActivityManagerService.this) {
21509                mStackSupervisor.setDockedStackMinimized(minimized);
21510            }
21511        }
21512
21513        @Override
21514        public void killForegroundAppsForUser(int userHandle) {
21515            synchronized (ActivityManagerService.this) {
21516                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21517                final int NP = mProcessNames.getMap().size();
21518                for (int ip = 0; ip < NP; ip++) {
21519                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21520                    final int NA = apps.size();
21521                    for (int ia = 0; ia < NA; ia++) {
21522                        final ProcessRecord app = apps.valueAt(ia);
21523                        if (app.persistent) {
21524                            // We don't kill persistent processes.
21525                            continue;
21526                        }
21527                        if (app.removed) {
21528                            procs.add(app);
21529                        } else if (app.userId == userHandle && app.foregroundActivities) {
21530                            app.removed = true;
21531                            procs.add(app);
21532                        }
21533                    }
21534                }
21535
21536                final int N = procs.size();
21537                for (int i = 0; i < N; i++) {
21538                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21539                }
21540            }
21541        }
21542
21543        @Override
21544        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21545            if (!(target instanceof PendingIntentRecord)) {
21546                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21547                return;
21548            }
21549            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21550        }
21551    }
21552
21553    private final class SleepTokenImpl extends SleepToken {
21554        private final String mTag;
21555        private final long mAcquireTime;
21556
21557        public SleepTokenImpl(String tag) {
21558            mTag = tag;
21559            mAcquireTime = SystemClock.uptimeMillis();
21560        }
21561
21562        @Override
21563        public void release() {
21564            synchronized (ActivityManagerService.this) {
21565                if (mSleepTokens.remove(this)) {
21566                    updateSleepIfNeededLocked();
21567                }
21568            }
21569        }
21570
21571        @Override
21572        public String toString() {
21573            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21574        }
21575    }
21576
21577    /**
21578     * An implementation of IAppTask, that allows an app to manage its own tasks via
21579     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21580     * only the process that calls getAppTasks() can call the AppTask methods.
21581     */
21582    class AppTaskImpl extends IAppTask.Stub {
21583        private int mTaskId;
21584        private int mCallingUid;
21585
21586        public AppTaskImpl(int taskId, int callingUid) {
21587            mTaskId = taskId;
21588            mCallingUid = callingUid;
21589        }
21590
21591        private void checkCaller() {
21592            if (mCallingUid != Binder.getCallingUid()) {
21593                throw new SecurityException("Caller " + mCallingUid
21594                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21595            }
21596        }
21597
21598        @Override
21599        public void finishAndRemoveTask() {
21600            checkCaller();
21601
21602            synchronized (ActivityManagerService.this) {
21603                long origId = Binder.clearCallingIdentity();
21604                try {
21605                    // We remove the task from recents to preserve backwards
21606                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21607                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21608                    }
21609                } finally {
21610                    Binder.restoreCallingIdentity(origId);
21611                }
21612            }
21613        }
21614
21615        @Override
21616        public ActivityManager.RecentTaskInfo getTaskInfo() {
21617            checkCaller();
21618
21619            synchronized (ActivityManagerService.this) {
21620                long origId = Binder.clearCallingIdentity();
21621                try {
21622                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21623                    if (tr == null) {
21624                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21625                    }
21626                    return createRecentTaskInfoFromTaskRecord(tr);
21627                } finally {
21628                    Binder.restoreCallingIdentity(origId);
21629                }
21630            }
21631        }
21632
21633        @Override
21634        public void moveToFront() {
21635            checkCaller();
21636            // Will bring task to front if it already has a root activity.
21637            final long origId = Binder.clearCallingIdentity();
21638            try {
21639                synchronized (this) {
21640                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21641                }
21642            } finally {
21643                Binder.restoreCallingIdentity(origId);
21644            }
21645        }
21646
21647        @Override
21648        public int startActivity(IBinder whoThread, String callingPackage,
21649                Intent intent, String resolvedType, Bundle bOptions) {
21650            checkCaller();
21651
21652            int callingUser = UserHandle.getCallingUserId();
21653            TaskRecord tr;
21654            IApplicationThread appThread;
21655            synchronized (ActivityManagerService.this) {
21656                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21657                if (tr == null) {
21658                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21659                }
21660                appThread = ApplicationThreadNative.asInterface(whoThread);
21661                if (appThread == null) {
21662                    throw new IllegalArgumentException("Bad app thread " + appThread);
21663                }
21664            }
21665            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21666                    resolvedType, null, null, null, null, 0, 0, null, null,
21667                    null, bOptions, false, callingUser, null, tr);
21668        }
21669
21670        @Override
21671        public void setExcludeFromRecents(boolean exclude) {
21672            checkCaller();
21673
21674            synchronized (ActivityManagerService.this) {
21675                long origId = Binder.clearCallingIdentity();
21676                try {
21677                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21678                    if (tr == null) {
21679                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21680                    }
21681                    Intent intent = tr.getBaseIntent();
21682                    if (exclude) {
21683                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21684                    } else {
21685                        intent.setFlags(intent.getFlags()
21686                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21687                    }
21688                } finally {
21689                    Binder.restoreCallingIdentity(origId);
21690                }
21691            }
21692        }
21693    }
21694
21695    /**
21696     * Kill processes for the user with id userId and that depend on the package named packageName
21697     */
21698    @Override
21699    public void killPackageDependents(String packageName, int userId) {
21700        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21701        if (packageName == null) {
21702            throw new NullPointerException(
21703                    "Cannot kill the dependents of a package without its name.");
21704        }
21705
21706        long callingId = Binder.clearCallingIdentity();
21707        IPackageManager pm = AppGlobals.getPackageManager();
21708        int pkgUid = -1;
21709        try {
21710            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21711        } catch (RemoteException e) {
21712        }
21713        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21714            throw new IllegalArgumentException(
21715                    "Cannot kill dependents of non-existing package " + packageName);
21716        }
21717        try {
21718            synchronized(this) {
21719                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21720                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21721                        "dep: " + packageName);
21722            }
21723        } finally {
21724            Binder.restoreCallingIdentity(callingId);
21725        }
21726    }
21727}
21728