ActivityManagerService.java revision 82c2e88890fbe0b7e112964e14b9b9ef3887d3f1
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.Manifest.permission;
67import android.annotation.NonNull;
68import android.annotation.UserIdInt;
69import android.app.Activity;
70import android.app.ActivityManager;
71import android.app.ActivityManager.RunningTaskInfo;
72import android.app.ActivityManager.StackId;
73import android.app.ActivityManager.StackInfo;
74import android.app.ActivityManager.TaskThumbnailInfo;
75import android.app.ActivityManagerInternal;
76import android.app.ActivityManagerInternal.SleepToken;
77import android.app.ActivityManagerNative;
78import android.app.ActivityOptions;
79import android.app.ActivityThread;
80import android.app.AlertDialog;
81import android.app.AppGlobals;
82import android.app.AppOpsManager;
83import android.app.ApplicationErrorReport;
84import android.app.ApplicationThreadNative;
85import android.app.BroadcastOptions;
86import android.app.Dialog;
87import android.app.IActivityContainer;
88import android.app.IActivityContainerCallback;
89import android.app.IActivityController;
90import android.app.IAppTask;
91import android.app.IApplicationThread;
92import android.app.IInstrumentationWatcher;
93import android.app.INotificationManager;
94import android.app.IProcessObserver;
95import android.app.IServiceConnection;
96import android.app.IStopUserCallback;
97import android.app.ITaskStackListener;
98import android.app.IUiAutomationConnection;
99import android.app.IUidObserver;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
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.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    // Whether we should use SCHED_FIFO for UI and RenderThreads.
573    private boolean mUseFifoUiScheduling = false;
574
575    BroadcastQueue mFgBroadcastQueue;
576    BroadcastQueue mBgBroadcastQueue;
577    // Convenient for easy iteration over the queues. Foreground is first
578    // so that dispatch of foreground broadcasts gets precedence.
579    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580
581    BroadcastStats mLastBroadcastStats;
582    BroadcastStats mCurBroadcastStats;
583
584    BroadcastQueue broadcastQueueForIntent(Intent intent) {
585        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                "Broadcast intent " + intent + " on "
588                + (isFg ? "foreground" : "background") + " queue");
589        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590    }
591
592    /**
593     * Activity we have told the window manager to have key focus.
594     */
595    ActivityRecord mFocusedActivity = null;
596
597    /**
598     * User id of the last activity mFocusedActivity was set to.
599     */
600    private int mLastFocusedUserId;
601
602    /**
603     * If non-null, we are tracking the time the user spends in the currently focused app.
604     */
605    private AppTimeTracker mCurAppTimeTracker;
606
607    /**
608     * List of intents that were used to start the most recent tasks.
609     */
610    final RecentTasks mRecentTasks;
611
612    /**
613     * For addAppTask: cached of the last activity component that was added.
614     */
615    ComponentName mLastAddedTaskComponent;
616
617    /**
618     * For addAppTask: cached of the last activity uid that was added.
619     */
620    int mLastAddedTaskUid;
621
622    /**
623     * For addAppTask: cached of the last ActivityInfo that was added.
624     */
625    ActivityInfo mLastAddedTaskActivity;
626
627    /**
628     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629     */
630    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631
632    /**
633     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634     */
635    String mDeviceOwnerName;
636
637    final UserController mUserController;
638
639    final AppErrors mAppErrors;
640
641    boolean mDoingSetFocusedActivity;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown;
645    }
646
647    private static final class PriorityState {
648        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
649        // the current thread is currently in. When it drops down to zero, we will no longer boost
650        // the thread's priority.
651        private int regionCounter = 0;
652
653        // The thread's previous priority before boosting.
654        private int prevPriority = Integer.MIN_VALUE;
655    }
656
657    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
658        @Override protected PriorityState initialValue() {
659            return new PriorityState();
660        }
661    };
662
663    static void boostPriorityForLockedSection() {
664        int tid = Process.myTid();
665        int prevPriority = Process.getThreadPriority(tid);
666        PriorityState state = sThreadPriorityState.get();
667        if (state.regionCounter == 0 && prevPriority > -2) {
668            state.prevPriority = prevPriority;
669            Process.setThreadPriority(tid, -2);
670        }
671        state.regionCounter++;
672    }
673
674    static void resetPriorityAfterLockedSection() {
675        PriorityState state = sThreadPriorityState.get();
676        state.regionCounter--;
677        if (state.regionCounter == 0 && state.prevPriority > -2) {
678            Process.setThreadPriority(Process.myTid(), state.prevPriority);
679        }
680    }
681
682    public class PendingAssistExtras extends Binder implements Runnable {
683        public final ActivityRecord activity;
684        public final Bundle extras;
685        public final Intent intent;
686        public final String hint;
687        public final IResultReceiver receiver;
688        public final int userHandle;
689        public boolean haveResult = false;
690        public Bundle result = null;
691        public AssistStructure structure = null;
692        public AssistContent content = null;
693        public Bundle receiverExtras;
694
695        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
696                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
697            activity = _activity;
698            extras = _extras;
699            intent = _intent;
700            hint = _hint;
701            receiver = _receiver;
702            receiverExtras = _receiverExtras;
703            userHandle = _userHandle;
704        }
705        @Override
706        public void run() {
707            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
708            synchronized (this) {
709                haveResult = true;
710                notifyAll();
711            }
712            pendingAssistExtrasTimedOut(this);
713        }
714    }
715
716    final ArrayList<PendingAssistExtras> mPendingAssistExtras
717            = new ArrayList<PendingAssistExtras>();
718
719    /**
720     * Process management.
721     */
722    final ProcessList mProcessList = new ProcessList();
723
724    /**
725     * All of the applications we currently have running organized by name.
726     * The keys are strings of the application package name (as
727     * returned by the package manager), and the keys are ApplicationRecord
728     * objects.
729     */
730    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
731
732    /**
733     * Tracking long-term execution of processes to look for abuse and other
734     * bad app behavior.
735     */
736    final ProcessStatsService mProcessStats;
737
738    /**
739     * The currently running isolated processes.
740     */
741    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
742
743    /**
744     * Counter for assigning isolated process uids, to avoid frequently reusing the
745     * same ones.
746     */
747    int mNextIsolatedProcessUid = 0;
748
749    /**
750     * The currently running heavy-weight process, if any.
751     */
752    ProcessRecord mHeavyWeightProcess = null;
753
754    /**
755     * All of the processes we currently have running organized by pid.
756     * The keys are the pid running the application.
757     *
758     * <p>NOTE: This object is protected by its own lock, NOT the global
759     * activity manager lock!
760     */
761    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
762
763    /**
764     * All of the processes that have been forced to be foreground.  The key
765     * is the pid of the caller who requested it (we hold a death
766     * link on it).
767     */
768    abstract class ForegroundToken implements IBinder.DeathRecipient {
769        int pid;
770        IBinder token;
771    }
772    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
773
774    /**
775     * List of records for processes that someone had tried to start before the
776     * system was ready.  We don't start them at that point, but ensure they
777     * are started by the time booting is complete.
778     */
779    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
780
781    /**
782     * List of persistent applications that are in the process
783     * of being started.
784     */
785    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
786
787    /**
788     * Processes that are being forcibly torn down.
789     */
790    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
791
792    /**
793     * List of running applications, sorted by recent usage.
794     * The first entry in the list is the least recently used.
795     */
796    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
797
798    /**
799     * Where in mLruProcesses that the processes hosting activities start.
800     */
801    int mLruProcessActivityStart = 0;
802
803    /**
804     * Where in mLruProcesses that the processes hosting services start.
805     * This is after (lower index) than mLruProcessesActivityStart.
806     */
807    int mLruProcessServiceStart = 0;
808
809    /**
810     * List of processes that should gc as soon as things are idle.
811     */
812    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
813
814    /**
815     * Processes we want to collect PSS data from.
816     */
817    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
818
819    private boolean mBinderTransactionTrackingEnabled = false;
820
821    /**
822     * Last time we requested PSS data of all processes.
823     */
824    long mLastFullPssTime = SystemClock.uptimeMillis();
825
826    /**
827     * If set, the next time we collect PSS data we should do a full collection
828     * with data from native processes and the kernel.
829     */
830    boolean mFullPssPending = false;
831
832    /**
833     * This is the process holding what we currently consider to be
834     * the "home" activity.
835     */
836    ProcessRecord mHomeProcess;
837
838    /**
839     * This is the process holding the activity the user last visited that
840     * is in a different process from the one they are currently in.
841     */
842    ProcessRecord mPreviousProcess;
843
844    /**
845     * The time at which the previous process was last visible.
846     */
847    long mPreviousProcessVisibleTime;
848
849    /**
850     * Track all uids that have actively running processes.
851     */
852    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
853
854    /**
855     * This is for verifying the UID report flow.
856     */
857    static final boolean VALIDATE_UID_STATES = true;
858    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
859
860    /**
861     * Packages that the user has asked to have run in screen size
862     * compatibility mode instead of filling the screen.
863     */
864    final CompatModePackages mCompatModePackages;
865
866    /**
867     * Set of IntentSenderRecord objects that are currently active.
868     */
869    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
870            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
871
872    /**
873     * Fingerprints (hashCode()) of stack traces that we've
874     * already logged DropBox entries for.  Guarded by itself.  If
875     * something (rogue user app) forces this over
876     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
877     */
878    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
879    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
880
881    /**
882     * Strict Mode background batched logging state.
883     *
884     * The string buffer is guarded by itself, and its lock is also
885     * used to determine if another batched write is already
886     * in-flight.
887     */
888    private final StringBuilder mStrictModeBuffer = new StringBuilder();
889
890    /**
891     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
892     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
893     */
894    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
895
896    /**
897     * Resolver for broadcast intents to registered receivers.
898     * Holds BroadcastFilter (subclass of IntentFilter).
899     */
900    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
901            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
902        @Override
903        protected boolean allowFilterResult(
904                BroadcastFilter filter, List<BroadcastFilter> dest) {
905            IBinder target = filter.receiverList.receiver.asBinder();
906            for (int i = dest.size() - 1; i >= 0; i--) {
907                if (dest.get(i).receiverList.receiver.asBinder() == target) {
908                    return false;
909                }
910            }
911            return true;
912        }
913
914        @Override
915        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
916            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
917                    || userId == filter.owningUserId) {
918                return super.newResult(filter, match, userId);
919            }
920            return null;
921        }
922
923        @Override
924        protected BroadcastFilter[] newArray(int size) {
925            return new BroadcastFilter[size];
926        }
927
928        @Override
929        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
930            return packageName.equals(filter.packageName);
931        }
932    };
933
934    /**
935     * State of all active sticky broadcasts per user.  Keys are the action of the
936     * sticky Intent, values are an ArrayList of all broadcasted intents with
937     * that action (which should usually be one).  The SparseArray is keyed
938     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
939     * for stickies that are sent to all users.
940     */
941    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
942            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
943
944    final ActiveServices mServices;
945
946    final static class Association {
947        final int mSourceUid;
948        final String mSourceProcess;
949        final int mTargetUid;
950        final ComponentName mTargetComponent;
951        final String mTargetProcess;
952
953        int mCount;
954        long mTime;
955
956        int mNesting;
957        long mStartTime;
958
959        // states of the source process when the bind occurred.
960        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
961        long mLastStateUptime;
962        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
963                - ActivityManager.MIN_PROCESS_STATE+1];
964
965        Association(int sourceUid, String sourceProcess, int targetUid,
966                ComponentName targetComponent, String targetProcess) {
967            mSourceUid = sourceUid;
968            mSourceProcess = sourceProcess;
969            mTargetUid = targetUid;
970            mTargetComponent = targetComponent;
971            mTargetProcess = targetProcess;
972        }
973    }
974
975    /**
976     * When service association tracking is enabled, this is all of the associations we
977     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
978     * -> association data.
979     */
980    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
981            mAssociations = new SparseArray<>();
982    boolean mTrackingAssociations;
983
984    /**
985     * Backup/restore process management
986     */
987    String mBackupAppName = null;
988    BackupRecord mBackupTarget = null;
989
990    final ProviderMap mProviderMap;
991
992    /**
993     * List of content providers who have clients waiting for them.  The
994     * application is currently being launched and the provider will be
995     * removed from this list once it is published.
996     */
997    final ArrayList<ContentProviderRecord> mLaunchingProviders
998            = new ArrayList<ContentProviderRecord>();
999
1000    /**
1001     * File storing persisted {@link #mGrantedUriPermissions}.
1002     */
1003    private final AtomicFile mGrantFile;
1004
1005    /** XML constants used in {@link #mGrantFile} */
1006    private static final String TAG_URI_GRANTS = "uri-grants";
1007    private static final String TAG_URI_GRANT = "uri-grant";
1008    private static final String ATTR_USER_HANDLE = "userHandle";
1009    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1010    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1011    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1012    private static final String ATTR_TARGET_PKG = "targetPkg";
1013    private static final String ATTR_URI = "uri";
1014    private static final String ATTR_MODE_FLAGS = "modeFlags";
1015    private static final String ATTR_CREATED_TIME = "createdTime";
1016    private static final String ATTR_PREFIX = "prefix";
1017
1018    /**
1019     * Global set of specific {@link Uri} permissions that have been granted.
1020     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1021     * to {@link UriPermission#uri} to {@link UriPermission}.
1022     */
1023    @GuardedBy("this")
1024    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1025            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1026
1027    public static class GrantUri {
1028        public final int sourceUserId;
1029        public final Uri uri;
1030        public boolean prefix;
1031
1032        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1033            this.sourceUserId = sourceUserId;
1034            this.uri = uri;
1035            this.prefix = prefix;
1036        }
1037
1038        @Override
1039        public int hashCode() {
1040            int hashCode = 1;
1041            hashCode = 31 * hashCode + sourceUserId;
1042            hashCode = 31 * hashCode + uri.hashCode();
1043            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1044            return hashCode;
1045        }
1046
1047        @Override
1048        public boolean equals(Object o) {
1049            if (o instanceof GrantUri) {
1050                GrantUri other = (GrantUri) o;
1051                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1052                        && prefix == other.prefix;
1053            }
1054            return false;
1055        }
1056
1057        @Override
1058        public String toString() {
1059            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1060            if (prefix) result += " [prefix]";
1061            return result;
1062        }
1063
1064        public String toSafeString() {
1065            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1066            if (prefix) result += " [prefix]";
1067            return result;
1068        }
1069
1070        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1071            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1072                    ContentProvider.getUriWithoutUserId(uri), false);
1073        }
1074    }
1075
1076    CoreSettingsObserver mCoreSettingsObserver;
1077
1078    FontScaleSettingObserver mFontScaleSettingObserver;
1079
1080    private final class FontScaleSettingObserver extends ContentObserver {
1081        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1082
1083        public FontScaleSettingObserver() {
1084            super(mHandler);
1085            ContentResolver resolver = mContext.getContentResolver();
1086            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1087        }
1088
1089        @Override
1090        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1091            if (mFontScaleUri.equals(uri)) {
1092                updateFontScaleIfNeeded(userId);
1093            }
1094        }
1095    }
1096
1097    /**
1098     * Thread-local storage used to carry caller permissions over through
1099     * indirect content-provider access.
1100     */
1101    private class Identity {
1102        public final IBinder token;
1103        public final int pid;
1104        public final int uid;
1105
1106        Identity(IBinder _token, int _pid, int _uid) {
1107            token = _token;
1108            pid = _pid;
1109            uid = _uid;
1110        }
1111    }
1112
1113    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1114
1115    /**
1116     * All information we have collected about the runtime performance of
1117     * any user id that can impact battery performance.
1118     */
1119    final BatteryStatsService mBatteryStatsService;
1120
1121    /**
1122     * Information about component usage
1123     */
1124    UsageStatsManagerInternal mUsageStatsService;
1125
1126    /**
1127     * Access to DeviceIdleController service.
1128     */
1129    DeviceIdleController.LocalService mLocalDeviceIdleController;
1130
1131    /**
1132     * Information about and control over application operations
1133     */
1134    final AppOpsService mAppOpsService;
1135
1136    /**
1137     * Current configuration information.  HistoryRecord objects are given
1138     * a reference to this object to indicate which configuration they are
1139     * currently running in, so this object must be kept immutable.
1140     */
1141    Configuration mConfiguration = new Configuration();
1142
1143    /**
1144     * Current sequencing integer of the configuration, for skipping old
1145     * configurations.
1146     */
1147    int mConfigurationSeq = 0;
1148
1149    boolean mSuppressResizeConfigChanges = false;
1150
1151    /**
1152     * Hardware-reported OpenGLES version.
1153     */
1154    final int GL_ES_VERSION;
1155
1156    /**
1157     * List of initialization arguments to pass to all processes when binding applications to them.
1158     * For example, references to the commonly used services.
1159     */
1160    HashMap<String, IBinder> mAppBindArgs;
1161
1162    /**
1163     * Temporary to avoid allocations.  Protected by main lock.
1164     */
1165    final StringBuilder mStringBuilder = new StringBuilder(256);
1166
1167    /**
1168     * Used to control how we initialize the service.
1169     */
1170    ComponentName mTopComponent;
1171    String mTopAction = Intent.ACTION_MAIN;
1172    String mTopData;
1173
1174    volatile boolean mProcessesReady = false;
1175    volatile boolean mSystemReady = false;
1176    volatile boolean mOnBattery = false;
1177    volatile int mFactoryTest;
1178
1179    @GuardedBy("this") boolean mBooting = false;
1180    @GuardedBy("this") boolean mCallFinishBooting = false;
1181    @GuardedBy("this") boolean mBootAnimationComplete = false;
1182    @GuardedBy("this") boolean mLaunchWarningShown = false;
1183    @GuardedBy("this") boolean mCheckedForSetup = false;
1184
1185    Context mContext;
1186
1187    /**
1188     * The time at which we will allow normal application switches again,
1189     * after a call to {@link #stopAppSwitches()}.
1190     */
1191    long mAppSwitchesAllowedTime;
1192
1193    /**
1194     * This is set to true after the first switch after mAppSwitchesAllowedTime
1195     * is set; any switches after that will clear the time.
1196     */
1197    boolean mDidAppSwitch;
1198
1199    /**
1200     * Last time (in realtime) at which we checked for power usage.
1201     */
1202    long mLastPowerCheckRealtime;
1203
1204    /**
1205     * Last time (in uptime) at which we checked for power usage.
1206     */
1207    long mLastPowerCheckUptime;
1208
1209    /**
1210     * Set while we are wanting to sleep, to prevent any
1211     * activities from being started/resumed.
1212     */
1213    private boolean mSleeping = false;
1214
1215    /**
1216     * The process state used for processes that are running the top activities.
1217     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1218     */
1219    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1220
1221    /**
1222     * Set while we are running a voice interaction.  This overrides
1223     * sleeping while it is active.
1224     */
1225    private IVoiceInteractionSession mRunningVoice;
1226
1227    /**
1228     * For some direct access we need to power manager.
1229     */
1230    PowerManagerInternal mLocalPowerManager;
1231
1232    /**
1233     * We want to hold a wake lock while running a voice interaction session, since
1234     * this may happen with the screen off and we need to keep the CPU running to
1235     * be able to continue to interact with the user.
1236     */
1237    PowerManager.WakeLock mVoiceWakeLock;
1238
1239    /**
1240     * State of external calls telling us if the device is awake or asleep.
1241     */
1242    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1243
1244    /**
1245     * A list of tokens that cause the top activity to be put to sleep.
1246     * They are used by components that may hide and block interaction with underlying
1247     * activities.
1248     */
1249    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1250
1251    static final int LOCK_SCREEN_HIDDEN = 0;
1252    static final int LOCK_SCREEN_LEAVING = 1;
1253    static final int LOCK_SCREEN_SHOWN = 2;
1254    /**
1255     * State of external call telling us if the lock screen is shown.
1256     */
1257    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1258
1259    /**
1260     * Set if we are shutting down the system, similar to sleeping.
1261     */
1262    boolean mShuttingDown = false;
1263
1264    /**
1265     * Current sequence id for oom_adj computation traversal.
1266     */
1267    int mAdjSeq = 0;
1268
1269    /**
1270     * Current sequence id for process LRU updating.
1271     */
1272    int mLruSeq = 0;
1273
1274    /**
1275     * Keep track of the non-cached/empty process we last found, to help
1276     * determine how to distribute cached/empty processes next time.
1277     */
1278    int mNumNonCachedProcs = 0;
1279
1280    /**
1281     * Keep track of the number of cached hidden procs, to balance oom adj
1282     * distribution between those and empty procs.
1283     */
1284    int mNumCachedHiddenProcs = 0;
1285
1286    /**
1287     * Keep track of the number of service processes we last found, to
1288     * determine on the next iteration which should be B services.
1289     */
1290    int mNumServiceProcs = 0;
1291    int mNewNumAServiceProcs = 0;
1292    int mNewNumServiceProcs = 0;
1293
1294    /**
1295     * Allow the current computed overall memory level of the system to go down?
1296     * This is set to false when we are killing processes for reasons other than
1297     * memory management, so that the now smaller process list will not be taken as
1298     * an indication that memory is tighter.
1299     */
1300    boolean mAllowLowerMemLevel = false;
1301
1302    /**
1303     * The last computed memory level, for holding when we are in a state that
1304     * processes are going away for other reasons.
1305     */
1306    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1307
1308    /**
1309     * The last total number of process we have, to determine if changes actually look
1310     * like a shrinking number of process due to lower RAM.
1311     */
1312    int mLastNumProcesses;
1313
1314    /**
1315     * The uptime of the last time we performed idle maintenance.
1316     */
1317    long mLastIdleTime = SystemClock.uptimeMillis();
1318
1319    /**
1320     * Total time spent with RAM that has been added in the past since the last idle time.
1321     */
1322    long mLowRamTimeSinceLastIdle = 0;
1323
1324    /**
1325     * If RAM is currently low, when that horrible situation started.
1326     */
1327    long mLowRamStartTime = 0;
1328
1329    /**
1330     * For reporting to battery stats the current top application.
1331     */
1332    private String mCurResumedPackage = null;
1333    private int mCurResumedUid = -1;
1334
1335    /**
1336     * For reporting to battery stats the apps currently running foreground
1337     * service.  The ProcessMap is package/uid tuples; each of these contain
1338     * an array of the currently foreground processes.
1339     */
1340    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1341            = new ProcessMap<ArrayList<ProcessRecord>>();
1342
1343    /**
1344     * This is set if we had to do a delayed dexopt of an app before launching
1345     * it, to increase the ANR timeouts in that case.
1346     */
1347    boolean mDidDexOpt;
1348
1349    /**
1350     * Set if the systemServer made a call to enterSafeMode.
1351     */
1352    boolean mSafeMode;
1353
1354    /**
1355     * If true, we are running under a test environment so will sample PSS from processes
1356     * much more rapidly to try to collect better data when the tests are rapidly
1357     * running through apps.
1358     */
1359    boolean mTestPssMode = false;
1360
1361    String mDebugApp = null;
1362    boolean mWaitForDebugger = false;
1363    boolean mDebugTransient = false;
1364    String mOrigDebugApp = null;
1365    boolean mOrigWaitForDebugger = false;
1366    boolean mAlwaysFinishActivities = false;
1367    boolean mLenientBackgroundCheck = false;
1368    boolean mForceResizableActivities;
1369    boolean mSupportsMultiWindow;
1370    boolean mSupportsFreeformWindowManagement;
1371    boolean mSupportsPictureInPicture;
1372    boolean mSupportsLeanbackOnly;
1373    Rect mDefaultPinnedStackBounds;
1374    IActivityController mController = null;
1375    boolean mControllerIsAMonkey = false;
1376    String mProfileApp = null;
1377    ProcessRecord mProfileProc = null;
1378    String mProfileFile;
1379    ParcelFileDescriptor mProfileFd;
1380    int mSamplingInterval = 0;
1381    boolean mAutoStopProfiler = false;
1382    int mProfileType = 0;
1383    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1384    String mMemWatchDumpProcName;
1385    String mMemWatchDumpFile;
1386    int mMemWatchDumpPid;
1387    int mMemWatchDumpUid;
1388    String mTrackAllocationApp = null;
1389    String mNativeDebuggingApp = null;
1390
1391    final long[] mTmpLong = new long[2];
1392
1393    static final class ProcessChangeItem {
1394        static final int CHANGE_ACTIVITIES = 1<<0;
1395        static final int CHANGE_PROCESS_STATE = 1<<1;
1396        int changes;
1397        int uid;
1398        int pid;
1399        int processState;
1400        boolean foregroundActivities;
1401    }
1402
1403    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1404    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1405
1406    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1407    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1408
1409    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1410    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1411
1412    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1413    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1414
1415    /**
1416     * Runtime CPU use collection thread.  This object's lock is used to
1417     * perform synchronization with the thread (notifying it to run).
1418     */
1419    final Thread mProcessCpuThread;
1420
1421    /**
1422     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1423     * Must acquire this object's lock when accessing it.
1424     * NOTE: this lock will be held while doing long operations (trawling
1425     * through all processes in /proc), so it should never be acquired by
1426     * any critical paths such as when holding the main activity manager lock.
1427     */
1428    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1429            MONITOR_THREAD_CPU_USAGE);
1430    final AtomicLong mLastCpuTime = new AtomicLong(0);
1431    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1432
1433    long mLastWriteTime = 0;
1434
1435    /**
1436     * Used to retain an update lock when the foreground activity is in
1437     * immersive mode.
1438     */
1439    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1440
1441    /**
1442     * Set to true after the system has finished booting.
1443     */
1444    boolean mBooted = false;
1445
1446    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1447    int mProcessLimitOverride = -1;
1448
1449    WindowManagerService mWindowManager;
1450    final ActivityThread mSystemThread;
1451
1452    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1453        final ProcessRecord mApp;
1454        final int mPid;
1455        final IApplicationThread mAppThread;
1456
1457        AppDeathRecipient(ProcessRecord app, int pid,
1458                IApplicationThread thread) {
1459            if (DEBUG_ALL) Slog.v(
1460                TAG, "New death recipient " + this
1461                + " for thread " + thread.asBinder());
1462            mApp = app;
1463            mPid = pid;
1464            mAppThread = thread;
1465        }
1466
1467        @Override
1468        public void binderDied() {
1469            if (DEBUG_ALL) Slog.v(
1470                TAG, "Death received in " + this
1471                + " for thread " + mAppThread.asBinder());
1472            synchronized(ActivityManagerService.this) {
1473                appDiedLocked(mApp, mPid, mAppThread, true);
1474            }
1475        }
1476    }
1477
1478    static final int SHOW_ERROR_UI_MSG = 1;
1479    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1480    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1481    static final int UPDATE_CONFIGURATION_MSG = 4;
1482    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1483    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1484    static final int SERVICE_TIMEOUT_MSG = 12;
1485    static final int UPDATE_TIME_ZONE = 13;
1486    static final int SHOW_UID_ERROR_UI_MSG = 14;
1487    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1488    static final int PROC_START_TIMEOUT_MSG = 20;
1489    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1490    static final int KILL_APPLICATION_MSG = 22;
1491    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1492    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1493    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1494    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1495    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1496    static final int CLEAR_DNS_CACHE_MSG = 28;
1497    static final int UPDATE_HTTP_PROXY_MSG = 29;
1498    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1499    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1500    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1501    static final int REPORT_MEM_USAGE_MSG = 33;
1502    static final int REPORT_USER_SWITCH_MSG = 34;
1503    static final int CONTINUE_USER_SWITCH_MSG = 35;
1504    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1505    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1506    static final int PERSIST_URI_GRANTS_MSG = 38;
1507    static final int REQUEST_ALL_PSS_MSG = 39;
1508    static final int START_PROFILES_MSG = 40;
1509    static final int UPDATE_TIME = 41;
1510    static final int SYSTEM_USER_START_MSG = 42;
1511    static final int SYSTEM_USER_CURRENT_MSG = 43;
1512    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1513    static final int FINISH_BOOTING_MSG = 45;
1514    static final int START_USER_SWITCH_UI_MSG = 46;
1515    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1516    static final int DISMISS_DIALOG_UI_MSG = 48;
1517    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1518    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1519    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1520    static final int DELETE_DUMPHEAP_MSG = 52;
1521    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1522    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1523    static final int REPORT_TIME_TRACKER_MSG = 55;
1524    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1525    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1526    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1527    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1528    static final int IDLE_UIDS_MSG = 60;
1529    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1530    static final int LOG_STACK_STATE = 62;
1531    static final int VR_MODE_CHANGE_MSG = 63;
1532    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1533    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1534    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1535    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1536    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1537    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1538    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1539
1540    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1541    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1542    static final int FIRST_COMPAT_MODE_MSG = 300;
1543    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1544
1545    static ServiceThread sKillThread = null;
1546    static KillHandler sKillHandler = null;
1547
1548    CompatModeDialog mCompatModeDialog;
1549    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1550    long mLastMemUsageReportTime = 0;
1551
1552    /**
1553     * Flag whether the current user is a "monkey", i.e. whether
1554     * the UI is driven by a UI automation tool.
1555     */
1556    private boolean mUserIsMonkey;
1557
1558    /** Flag whether the device has a Recents UI */
1559    boolean mHasRecents;
1560
1561    /** The dimensions of the thumbnails in the Recents UI. */
1562    int mThumbnailWidth;
1563    int mThumbnailHeight;
1564    float mFullscreenThumbnailScale;
1565
1566    final ServiceThread mHandlerThread;
1567    final MainHandler mHandler;
1568    final UiHandler mUiHandler;
1569
1570    PackageManagerInternal mPackageManagerInt;
1571
1572    // VoiceInteraction session ID that changes for each new request except when
1573    // being called for multiwindow assist in a single session.
1574    private int mViSessionId = 1000;
1575
1576    final class KillHandler extends Handler {
1577        static final int KILL_PROCESS_GROUP_MSG = 4000;
1578
1579        public KillHandler(Looper looper) {
1580            super(looper, null, true);
1581        }
1582
1583        @Override
1584        public void handleMessage(Message msg) {
1585            switch (msg.what) {
1586                case KILL_PROCESS_GROUP_MSG:
1587                {
1588                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1589                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1590                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1591                }
1592                break;
1593
1594                default:
1595                    super.handleMessage(msg);
1596            }
1597        }
1598    }
1599
1600    final class UiHandler extends Handler {
1601        public UiHandler() {
1602            super(com.android.server.UiThread.get().getLooper(), null, true);
1603        }
1604
1605        @Override
1606        public void handleMessage(Message msg) {
1607            switch (msg.what) {
1608            case SHOW_ERROR_UI_MSG: {
1609                mAppErrors.handleShowAppErrorUi(msg);
1610                ensureBootCompleted();
1611            } break;
1612            case SHOW_NOT_RESPONDING_UI_MSG: {
1613                mAppErrors.handleShowAnrUi(msg);
1614                ensureBootCompleted();
1615            } break;
1616            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1617                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1618                synchronized (ActivityManagerService.this) {
1619                    ProcessRecord proc = (ProcessRecord) data.get("app");
1620                    if (proc == null) {
1621                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1622                        break;
1623                    }
1624                    if (proc.crashDialog != null) {
1625                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1626                        return;
1627                    }
1628                    AppErrorResult res = (AppErrorResult) data.get("result");
1629                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1630                        Dialog d = new StrictModeViolationDialog(mContext,
1631                                ActivityManagerService.this, res, proc);
1632                        d.show();
1633                        proc.crashDialog = d;
1634                    } else {
1635                        // The device is asleep, so just pretend that the user
1636                        // saw a crash dialog and hit "force quit".
1637                        res.set(0);
1638                    }
1639                }
1640                ensureBootCompleted();
1641            } break;
1642            case SHOW_FACTORY_ERROR_UI_MSG: {
1643                Dialog d = new FactoryErrorDialog(
1644                    mContext, msg.getData().getCharSequence("msg"));
1645                d.show();
1646                ensureBootCompleted();
1647            } break;
1648            case WAIT_FOR_DEBUGGER_UI_MSG: {
1649                synchronized (ActivityManagerService.this) {
1650                    ProcessRecord app = (ProcessRecord)msg.obj;
1651                    if (msg.arg1 != 0) {
1652                        if (!app.waitedForDebugger) {
1653                            Dialog d = new AppWaitingForDebuggerDialog(
1654                                    ActivityManagerService.this,
1655                                    mContext, app);
1656                            app.waitDialog = d;
1657                            app.waitedForDebugger = true;
1658                            d.show();
1659                        }
1660                    } else {
1661                        if (app.waitDialog != null) {
1662                            app.waitDialog.dismiss();
1663                            app.waitDialog = null;
1664                        }
1665                    }
1666                }
1667            } break;
1668            case SHOW_UID_ERROR_UI_MSG: {
1669                if (mShowDialogs) {
1670                    AlertDialog d = new BaseErrorDialog(mContext);
1671                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1672                    d.setCancelable(false);
1673                    d.setTitle(mContext.getText(R.string.android_system_label));
1674                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1675                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1676                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1677                    d.show();
1678                }
1679            } break;
1680            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1681                if (mShowDialogs) {
1682                    AlertDialog d = new BaseErrorDialog(mContext);
1683                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1684                    d.setCancelable(false);
1685                    d.setTitle(mContext.getText(R.string.android_system_label));
1686                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1687                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1688                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1689                    d.show();
1690                }
1691            } break;
1692            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    ActivityRecord ar = (ActivityRecord) msg.obj;
1695                    if (mCompatModeDialog != null) {
1696                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1697                                ar.info.applicationInfo.packageName)) {
1698                            return;
1699                        }
1700                        mCompatModeDialog.dismiss();
1701                        mCompatModeDialog = null;
1702                    }
1703                    if (ar != null && false) {
1704                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1705                                ar.packageName)) {
1706                            int mode = mCompatModePackages.computeCompatModeLocked(
1707                                    ar.info.applicationInfo);
1708                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1709                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1710                                mCompatModeDialog = new CompatModeDialog(
1711                                        ActivityManagerService.this, mContext,
1712                                        ar.info.applicationInfo);
1713                                mCompatModeDialog.show();
1714                            }
1715                        }
1716                    }
1717                }
1718                break;
1719            }
1720            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1721                synchronized (ActivityManagerService.this) {
1722                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1723                    if (mUnsupportedDisplaySizeDialog != null) {
1724                        mUnsupportedDisplaySizeDialog.dismiss();
1725                        mUnsupportedDisplaySizeDialog = null;
1726                    }
1727                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1728                            ar.packageName)) {
1729                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1730                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1731                        mUnsupportedDisplaySizeDialog.show();
1732                    }
1733                }
1734                break;
1735            }
1736            case START_USER_SWITCH_UI_MSG: {
1737                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1738                break;
1739            }
1740            case DISMISS_DIALOG_UI_MSG: {
1741                final Dialog d = (Dialog) msg.obj;
1742                d.dismiss();
1743                break;
1744            }
1745            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1746                dispatchProcessesChanged();
1747                break;
1748            }
1749            case DISPATCH_PROCESS_DIED_UI_MSG: {
1750                final int pid = msg.arg1;
1751                final int uid = msg.arg2;
1752                dispatchProcessDied(pid, uid);
1753                break;
1754            }
1755            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1756                dispatchUidsChanged();
1757            } break;
1758            }
1759        }
1760    }
1761
1762    final class MainHandler extends Handler {
1763        public MainHandler(Looper looper) {
1764            super(looper, null, true);
1765        }
1766
1767        @Override
1768        public void handleMessage(Message msg) {
1769            switch (msg.what) {
1770            case UPDATE_CONFIGURATION_MSG: {
1771                final ContentResolver resolver = mContext.getContentResolver();
1772                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1773                        msg.arg1);
1774            } break;
1775            case GC_BACKGROUND_PROCESSES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    performAppGcsIfAppropriateLocked();
1778                }
1779            } break;
1780            case SERVICE_TIMEOUT_MSG: {
1781                if (mDidDexOpt) {
1782                    mDidDexOpt = false;
1783                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1784                    nmsg.obj = msg.obj;
1785                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1786                    return;
1787                }
1788                mServices.serviceTimeout((ProcessRecord)msg.obj);
1789            } break;
1790            case UPDATE_TIME_ZONE: {
1791                synchronized (ActivityManagerService.this) {
1792                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1793                        ProcessRecord r = mLruProcesses.get(i);
1794                        if (r.thread != null) {
1795                            try {
1796                                r.thread.updateTimeZone();
1797                            } catch (RemoteException ex) {
1798                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case CLEAR_DNS_CACHE_MSG: {
1805                synchronized (ActivityManagerService.this) {
1806                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                        ProcessRecord r = mLruProcesses.get(i);
1808                        if (r.thread != null) {
1809                            try {
1810                                r.thread.clearDnsCache();
1811                            } catch (RemoteException ex) {
1812                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1813                            }
1814                        }
1815                    }
1816                }
1817            } break;
1818            case UPDATE_HTTP_PROXY_MSG: {
1819                ProxyInfo proxy = (ProxyInfo)msg.obj;
1820                String host = "";
1821                String port = "";
1822                String exclList = "";
1823                Uri pacFileUrl = Uri.EMPTY;
1824                if (proxy != null) {
1825                    host = proxy.getHost();
1826                    port = Integer.toString(proxy.getPort());
1827                    exclList = proxy.getExclusionListAsString();
1828                    pacFileUrl = proxy.getPacFileUrl();
1829                }
1830                synchronized (ActivityManagerService.this) {
1831                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                        ProcessRecord r = mLruProcesses.get(i);
1833                        if (r.thread != null) {
1834                            try {
1835                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1836                            } catch (RemoteException ex) {
1837                                Slog.w(TAG, "Failed to update http proxy for: " +
1838                                        r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843            } break;
1844            case PROC_START_TIMEOUT_MSG: {
1845                if (mDidDexOpt) {
1846                    mDidDexOpt = false;
1847                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1848                    nmsg.obj = msg.obj;
1849                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1850                    return;
1851                }
1852                ProcessRecord app = (ProcessRecord)msg.obj;
1853                synchronized (ActivityManagerService.this) {
1854                    processStartTimedOutLocked(app);
1855                }
1856            } break;
1857            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1858                ProcessRecord app = (ProcessRecord)msg.obj;
1859                synchronized (ActivityManagerService.this) {
1860                    processContentProviderPublishTimedOutLocked(app);
1861                }
1862            } break;
1863            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1864                synchronized (ActivityManagerService.this) {
1865                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1866                }
1867            } break;
1868            case KILL_APPLICATION_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    final int appId = msg.arg1;
1871                    final int userId = msg.arg2;
1872                    Bundle bundle = (Bundle)msg.obj;
1873                    String pkg = bundle.getString("pkg");
1874                    String reason = bundle.getString("reason");
1875                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1876                            false, userId, reason);
1877                }
1878            } break;
1879            case FINALIZE_PENDING_INTENT_MSG: {
1880                ((PendingIntentRecord)msg.obj).completeFinalize();
1881            } break;
1882            case POST_HEAVY_NOTIFICATION_MSG: {
1883                INotificationManager inm = NotificationManager.getService();
1884                if (inm == null) {
1885                    return;
1886                }
1887
1888                ActivityRecord root = (ActivityRecord)msg.obj;
1889                ProcessRecord process = root.app;
1890                if (process == null) {
1891                    return;
1892                }
1893
1894                try {
1895                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1896                    String text = mContext.getString(R.string.heavy_weight_notification,
1897                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1898                    Notification notification = new Notification.Builder(context)
1899                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1900                            .setWhen(0)
1901                            .setOngoing(true)
1902                            .setTicker(text)
1903                            .setColor(mContext.getColor(
1904                                    com.android.internal.R.color.system_notification_accent_color))
1905                            .setContentTitle(text)
1906                            .setContentText(
1907                                    mContext.getText(R.string.heavy_weight_notification_detail))
1908                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1909                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1910                                    new UserHandle(root.userId)))
1911                            .build();
1912                    try {
1913                        int[] outId = new int[1];
1914                        inm.enqueueNotificationWithTag("android", "android", null,
1915                                R.string.heavy_weight_notification,
1916                                notification, outId, root.userId);
1917                    } catch (RuntimeException e) {
1918                        Slog.w(ActivityManagerService.TAG,
1919                                "Error showing notification for heavy-weight app", e);
1920                    } catch (RemoteException e) {
1921                    }
1922                } catch (NameNotFoundException e) {
1923                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1924                }
1925            } break;
1926            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1927                INotificationManager inm = NotificationManager.getService();
1928                if (inm == null) {
1929                    return;
1930                }
1931                try {
1932                    inm.cancelNotificationWithTag("android", null,
1933                            R.string.heavy_weight_notification,  msg.arg1);
1934                } catch (RuntimeException e) {
1935                    Slog.w(ActivityManagerService.TAG,
1936                            "Error canceling notification for service", e);
1937                } catch (RemoteException e) {
1938                }
1939            } break;
1940            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1941                synchronized (ActivityManagerService.this) {
1942                    checkExcessivePowerUsageLocked(true);
1943                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1944                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1945                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1946                }
1947            } break;
1948            case REPORT_MEM_USAGE_MSG: {
1949                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1950                Thread thread = new Thread() {
1951                    @Override public void run() {
1952                        reportMemUsage(memInfos);
1953                    }
1954                };
1955                thread.start();
1956                break;
1957            }
1958            case REPORT_USER_SWITCH_MSG: {
1959                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1960                break;
1961            }
1962            case CONTINUE_USER_SWITCH_MSG: {
1963                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964                break;
1965            }
1966            case USER_SWITCH_TIMEOUT_MSG: {
1967                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1968                break;
1969            }
1970            case IMMERSIVE_MODE_LOCK_MSG: {
1971                final boolean nextState = (msg.arg1 != 0);
1972                if (mUpdateLock.isHeld() != nextState) {
1973                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1974                            "Applying new update lock state '" + nextState
1975                            + "' for " + (ActivityRecord)msg.obj);
1976                    if (nextState) {
1977                        mUpdateLock.acquire();
1978                    } else {
1979                        mUpdateLock.release();
1980                    }
1981                }
1982                break;
1983            }
1984            case PERSIST_URI_GRANTS_MSG: {
1985                writeGrantedUriPermissions();
1986                break;
1987            }
1988            case REQUEST_ALL_PSS_MSG: {
1989                synchronized (ActivityManagerService.this) {
1990                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1991                }
1992                break;
1993            }
1994            case START_PROFILES_MSG: {
1995                synchronized (ActivityManagerService.this) {
1996                    mUserController.startProfilesLocked();
1997                }
1998                break;
1999            }
2000            case UPDATE_TIME: {
2001                synchronized (ActivityManagerService.this) {
2002                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2003                        ProcessRecord r = mLruProcesses.get(i);
2004                        if (r.thread != null) {
2005                            try {
2006                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2007                            } catch (RemoteException ex) {
2008                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2009                            }
2010                        }
2011                    }
2012                }
2013                break;
2014            }
2015            case SYSTEM_USER_START_MSG: {
2016                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2017                        Integer.toString(msg.arg1), msg.arg1);
2018                mSystemServiceManager.startUser(msg.arg1);
2019                break;
2020            }
2021            case SYSTEM_USER_UNLOCK_MSG: {
2022                final int userId = msg.arg1;
2023                mSystemServiceManager.unlockUser(userId);
2024                synchronized (ActivityManagerService.this) {
2025                    mRecentTasks.loadUserRecentsLocked(userId);
2026                }
2027                if (userId == UserHandle.USER_SYSTEM) {
2028                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2029                }
2030                installEncryptionUnawareProviders(userId);
2031                mUserController.finishUserUnlocked((UserState) msg.obj);
2032                break;
2033            }
2034            case SYSTEM_USER_CURRENT_MSG: {
2035                mBatteryStatsService.noteEvent(
2036                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2037                        Integer.toString(msg.arg2), msg.arg2);
2038                mBatteryStatsService.noteEvent(
2039                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2040                        Integer.toString(msg.arg1), msg.arg1);
2041                mSystemServiceManager.switchUser(msg.arg1);
2042                break;
2043            }
2044            case ENTER_ANIMATION_COMPLETE_MSG: {
2045                synchronized (ActivityManagerService.this) {
2046                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2047                    if (r != null && r.app != null && r.app.thread != null) {
2048                        try {
2049                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2050                        } catch (RemoteException e) {
2051                        }
2052                    }
2053                }
2054                break;
2055            }
2056            case FINISH_BOOTING_MSG: {
2057                if (msg.arg1 != 0) {
2058                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2059                    finishBooting();
2060                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2061                }
2062                if (msg.arg2 != 0) {
2063                    enableScreenAfterBoot();
2064                }
2065                break;
2066            }
2067            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2068                try {
2069                    Locale l = (Locale) msg.obj;
2070                    IBinder service = ServiceManager.getService("mount");
2071                    IMountService mountService = IMountService.Stub.asInterface(service);
2072                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2073                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2074                } catch (RemoteException e) {
2075                    Log.e(TAG, "Error storing locale for decryption UI", e);
2076                }
2077                break;
2078            }
2079            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2080                synchronized (ActivityManagerService.this) {
2081                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                        try {
2083                            // Make a one-way callback to the listener
2084                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2085                        } catch (RemoteException e){
2086                            // Handled by the RemoteCallbackList
2087                        }
2088                    }
2089                    mTaskStackListeners.finishBroadcast();
2090                }
2091                break;
2092            }
2093            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2094                synchronized (ActivityManagerService.this) {
2095                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                        try {
2097                            // Make a one-way callback to the listener
2098                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2108                synchronized (ActivityManagerService.this) {
2109                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                        try {
2111                            // Make a one-way callback to the listener
2112                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2113                        } catch (RemoteException e){
2114                            // Handled by the RemoteCallbackList
2115                        }
2116                    }
2117                    mTaskStackListeners.finishBroadcast();
2118                }
2119                break;
2120            }
2121            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2122                synchronized (ActivityManagerService.this) {
2123                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                        try {
2125                            // Make a one-way callback to the listener
2126                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135            case NOTIFY_FORCED_RESIZABLE_MSG: {
2136                synchronized (ActivityManagerService.this) {
2137                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                        try {
2139                            // Make a one-way callback to the listener
2140                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2141                                    (String) msg.obj, msg.arg1);
2142                        } catch (RemoteException e){
2143                            // Handled by the RemoteCallbackList
2144                        }
2145                    }
2146                    mTaskStackListeners.finishBroadcast();
2147                }
2148                break;
2149            }
2150                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2151                    synchronized (ActivityManagerService.this) {
2152                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2153                            try {
2154                                // Make a one-way callback to the listener
2155                                mTaskStackListeners.getBroadcastItem(i)
2156                                        .onActivityDismissingDockedStack();
2157                            } catch (RemoteException e){
2158                                // Handled by the RemoteCallbackList
2159                            }
2160                        }
2161                        mTaskStackListeners.finishBroadcast();
2162                    }
2163                    break;
2164                }
2165            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2166                final int uid = msg.arg1;
2167                final byte[] firstPacket = (byte[]) msg.obj;
2168
2169                synchronized (mPidsSelfLocked) {
2170                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2171                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2172                        if (p.uid == uid) {
2173                            try {
2174                                p.thread.notifyCleartextNetwork(firstPacket);
2175                            } catch (RemoteException ignored) {
2176                            }
2177                        }
2178                    }
2179                }
2180                break;
2181            }
2182            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2183                final String procName;
2184                final int uid;
2185                final long memLimit;
2186                final String reportPackage;
2187                synchronized (ActivityManagerService.this) {
2188                    procName = mMemWatchDumpProcName;
2189                    uid = mMemWatchDumpUid;
2190                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2191                    if (val == null) {
2192                        val = mMemWatchProcesses.get(procName, 0);
2193                    }
2194                    if (val != null) {
2195                        memLimit = val.first;
2196                        reportPackage = val.second;
2197                    } else {
2198                        memLimit = 0;
2199                        reportPackage = null;
2200                    }
2201                }
2202                if (procName == null) {
2203                    return;
2204                }
2205
2206                if (DEBUG_PSS) Slog.d(TAG_PSS,
2207                        "Showing dump heap notification from " + procName + "/" + uid);
2208
2209                INotificationManager inm = NotificationManager.getService();
2210                if (inm == null) {
2211                    return;
2212                }
2213
2214                String text = mContext.getString(R.string.dump_heap_notification, procName);
2215
2216
2217                Intent deleteIntent = new Intent();
2218                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2219                Intent intent = new Intent();
2220                intent.setClassName("android", DumpHeapActivity.class.getName());
2221                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2222                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2223                if (reportPackage != null) {
2224                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2225                }
2226                int userId = UserHandle.getUserId(uid);
2227                Notification notification = new Notification.Builder(mContext)
2228                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2229                        .setWhen(0)
2230                        .setOngoing(true)
2231                        .setAutoCancel(true)
2232                        .setTicker(text)
2233                        .setColor(mContext.getColor(
2234                                com.android.internal.R.color.system_notification_accent_color))
2235                        .setContentTitle(text)
2236                        .setContentText(
2237                                mContext.getText(R.string.dump_heap_notification_detail))
2238                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2239                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2240                                new UserHandle(userId)))
2241                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2242                                deleteIntent, 0, UserHandle.SYSTEM))
2243                        .build();
2244
2245                try {
2246                    int[] outId = new int[1];
2247                    inm.enqueueNotificationWithTag("android", "android", null,
2248                            R.string.dump_heap_notification,
2249                            notification, outId, userId);
2250                } catch (RuntimeException e) {
2251                    Slog.w(ActivityManagerService.TAG,
2252                            "Error showing notification for dump heap", e);
2253                } catch (RemoteException e) {
2254                }
2255            } break;
2256            case DELETE_DUMPHEAP_MSG: {
2257                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2258                        DumpHeapActivity.JAVA_URI,
2259                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2260                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2261                        UserHandle.myUserId());
2262                synchronized (ActivityManagerService.this) {
2263                    mMemWatchDumpFile = null;
2264                    mMemWatchDumpProcName = null;
2265                    mMemWatchDumpPid = -1;
2266                    mMemWatchDumpUid = -1;
2267                }
2268            } break;
2269            case FOREGROUND_PROFILE_CHANGED_MSG: {
2270                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2271            } break;
2272            case REPORT_TIME_TRACKER_MSG: {
2273                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2274                tracker.deliverResult(mContext);
2275            } break;
2276            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2277                mUserController.dispatchUserSwitchComplete(msg.arg1);
2278            } break;
2279            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2280                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2281                try {
2282                    connection.shutdown();
2283                } catch (RemoteException e) {
2284                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2285                }
2286                // Only a UiAutomation can set this flag and now that
2287                // it is finished we make sure it is reset to its default.
2288                mUserIsMonkey = false;
2289            } break;
2290            case APP_BOOST_DEACTIVATE_MSG: {
2291                synchronized(ActivityManagerService.this) {
2292                    if (mIsBoosted) {
2293                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2294                            nativeMigrateFromBoost();
2295                            mIsBoosted = false;
2296                            mBoostStartTime = 0;
2297                        } else {
2298                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2299                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2300                        }
2301                    }
2302                }
2303            } break;
2304            case IDLE_UIDS_MSG: {
2305                idleUids();
2306            } break;
2307            case LOG_STACK_STATE: {
2308                synchronized (ActivityManagerService.this) {
2309                    mStackSupervisor.logStackState();
2310                }
2311            } break;
2312            case VR_MODE_CHANGE_MSG: {
2313                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2314                final ActivityRecord r = (ActivityRecord) msg.obj;
2315                boolean vrMode;
2316                ComponentName requestedPackage;
2317                ComponentName callingPackage;
2318                int userId;
2319                synchronized (ActivityManagerService.this) {
2320                    vrMode = r.requestedVrComponent != null;
2321                    requestedPackage = r.requestedVrComponent;
2322                    userId = r.userId;
2323                    callingPackage = r.info.getComponentName();
2324                    if (mInVrMode != vrMode) {
2325                        mInVrMode = vrMode;
2326                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2327                        if (r.app != null) {
2328                            ProcessRecord proc = r.app;
2329                            if (proc.vrThreadTid > 0) {
2330                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2331                                    if (mInVrMode == true) {
2332                                        Process.setThreadScheduler(proc.vrThreadTid,
2333                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2334                                    } else {
2335                                        Process.setThreadScheduler(proc.vrThreadTid,
2336                                            Process.SCHED_OTHER, 0);
2337                                    }
2338                                }
2339                            }
2340                        }
2341                    }
2342                }
2343                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2344            } break;
2345            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2346                final ActivityRecord r = (ActivityRecord) msg.obj;
2347                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2348                if (needsVrMode) {
2349                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2350                            r.info.getComponentName(), false);
2351                }
2352            } break;
2353            }
2354        }
2355    };
2356
2357    static final int COLLECT_PSS_BG_MSG = 1;
2358
2359    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2360        @Override
2361        public void handleMessage(Message msg) {
2362            switch (msg.what) {
2363            case COLLECT_PSS_BG_MSG: {
2364                long start = SystemClock.uptimeMillis();
2365                MemInfoReader memInfo = null;
2366                synchronized (ActivityManagerService.this) {
2367                    if (mFullPssPending) {
2368                        mFullPssPending = false;
2369                        memInfo = new MemInfoReader();
2370                    }
2371                }
2372                if (memInfo != null) {
2373                    updateCpuStatsNow();
2374                    long nativeTotalPss = 0;
2375                    synchronized (mProcessCpuTracker) {
2376                        final int N = mProcessCpuTracker.countStats();
2377                        for (int j=0; j<N; j++) {
2378                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2379                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2380                                // This is definitely an application process; skip it.
2381                                continue;
2382                            }
2383                            synchronized (mPidsSelfLocked) {
2384                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2385                                    // This is one of our own processes; skip it.
2386                                    continue;
2387                                }
2388                            }
2389                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2390                        }
2391                    }
2392                    memInfo.readMemInfo();
2393                    synchronized (ActivityManagerService.this) {
2394                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2395                                + (SystemClock.uptimeMillis()-start) + "ms");
2396                        final long cachedKb = memInfo.getCachedSizeKb();
2397                        final long freeKb = memInfo.getFreeSizeKb();
2398                        final long zramKb = memInfo.getZramTotalSizeKb();
2399                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2400                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2401                                kernelKb*1024, nativeTotalPss*1024);
2402                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2403                                nativeTotalPss);
2404                    }
2405                }
2406
2407                int num = 0;
2408                long[] tmp = new long[2];
2409                do {
2410                    ProcessRecord proc;
2411                    int procState;
2412                    int pid;
2413                    long lastPssTime;
2414                    synchronized (ActivityManagerService.this) {
2415                        if (mPendingPssProcesses.size() <= 0) {
2416                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2417                                    "Collected PSS of " + num + " processes in "
2418                                    + (SystemClock.uptimeMillis() - start) + "ms");
2419                            mPendingPssProcesses.clear();
2420                            return;
2421                        }
2422                        proc = mPendingPssProcesses.remove(0);
2423                        procState = proc.pssProcState;
2424                        lastPssTime = proc.lastPssTime;
2425                        if (proc.thread != null && procState == proc.setProcState
2426                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2427                                        < SystemClock.uptimeMillis()) {
2428                            pid = proc.pid;
2429                        } else {
2430                            proc = null;
2431                            pid = 0;
2432                        }
2433                    }
2434                    if (proc != null) {
2435                        long pss = Debug.getPss(pid, tmp, null);
2436                        synchronized (ActivityManagerService.this) {
2437                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2438                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2439                                num++;
2440                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2441                                        SystemClock.uptimeMillis());
2442                            }
2443                        }
2444                    }
2445                } while (true);
2446            }
2447            }
2448        }
2449    };
2450
2451    public void setSystemProcess() {
2452        try {
2453            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2454            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2455            ServiceManager.addService("meminfo", new MemBinder(this));
2456            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2457            ServiceManager.addService("dbinfo", new DbBinder(this));
2458            if (MONITOR_CPU_USAGE) {
2459                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2460            }
2461            ServiceManager.addService("permission", new PermissionController(this));
2462            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2463
2464            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2465                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2466            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2467
2468            synchronized (this) {
2469                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2470                app.persistent = true;
2471                app.pid = MY_PID;
2472                app.maxAdj = ProcessList.SYSTEM_ADJ;
2473                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2474                synchronized (mPidsSelfLocked) {
2475                    mPidsSelfLocked.put(app.pid, app);
2476                }
2477                updateLruProcessLocked(app, false, null);
2478                updateOomAdjLocked();
2479            }
2480        } catch (PackageManager.NameNotFoundException e) {
2481            throw new RuntimeException(
2482                    "Unable to find android system package", e);
2483        }
2484    }
2485
2486    public void setWindowManager(WindowManagerService wm) {
2487        mWindowManager = wm;
2488        mStackSupervisor.setWindowManager(wm);
2489        mActivityStarter.setWindowManager(wm);
2490    }
2491
2492    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2493        mUsageStatsService = usageStatsManager;
2494    }
2495
2496    public void startObservingNativeCrashes() {
2497        final NativeCrashListener ncl = new NativeCrashListener(this);
2498        ncl.start();
2499    }
2500
2501    public IAppOpsService getAppOpsService() {
2502        return mAppOpsService;
2503    }
2504
2505    static class MemBinder extends Binder {
2506        ActivityManagerService mActivityManagerService;
2507        MemBinder(ActivityManagerService activityManagerService) {
2508            mActivityManagerService = activityManagerService;
2509        }
2510
2511        @Override
2512        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2513            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2514                    != PackageManager.PERMISSION_GRANTED) {
2515                pw.println("Permission Denial: can't dump meminfo from from pid="
2516                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2517                        + " without permission " + android.Manifest.permission.DUMP);
2518                return;
2519            }
2520
2521            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2522        }
2523    }
2524
2525    static class GraphicsBinder extends Binder {
2526        ActivityManagerService mActivityManagerService;
2527        GraphicsBinder(ActivityManagerService activityManagerService) {
2528            mActivityManagerService = activityManagerService;
2529        }
2530
2531        @Override
2532        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2533            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2534                    != PackageManager.PERMISSION_GRANTED) {
2535                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2536                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2537                        + " without permission " + android.Manifest.permission.DUMP);
2538                return;
2539            }
2540
2541            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2542        }
2543    }
2544
2545    static class DbBinder extends Binder {
2546        ActivityManagerService mActivityManagerService;
2547        DbBinder(ActivityManagerService activityManagerService) {
2548            mActivityManagerService = activityManagerService;
2549        }
2550
2551        @Override
2552        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2553            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2554                    != PackageManager.PERMISSION_GRANTED) {
2555                pw.println("Permission Denial: can't dump dbinfo from from pid="
2556                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2557                        + " without permission " + android.Manifest.permission.DUMP);
2558                return;
2559            }
2560
2561            mActivityManagerService.dumpDbInfo(fd, pw, args);
2562        }
2563    }
2564
2565    static class CpuBinder extends Binder {
2566        ActivityManagerService mActivityManagerService;
2567        CpuBinder(ActivityManagerService activityManagerService) {
2568            mActivityManagerService = activityManagerService;
2569        }
2570
2571        @Override
2572        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2573            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2574                    != PackageManager.PERMISSION_GRANTED) {
2575                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2576                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2577                        + " without permission " + android.Manifest.permission.DUMP);
2578                return;
2579            }
2580
2581            synchronized (mActivityManagerService.mProcessCpuTracker) {
2582                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2583                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2584                        SystemClock.uptimeMillis()));
2585            }
2586        }
2587    }
2588
2589    public static final class Lifecycle extends SystemService {
2590        private final ActivityManagerService mService;
2591
2592        public Lifecycle(Context context) {
2593            super(context);
2594            mService = new ActivityManagerService(context);
2595        }
2596
2597        @Override
2598        public void onStart() {
2599            mService.start();
2600        }
2601
2602        public ActivityManagerService getService() {
2603            return mService;
2604        }
2605    }
2606
2607    // Note: This method is invoked on the main thread but may need to attach various
2608    // handlers to other threads.  So take care to be explicit about the looper.
2609    public ActivityManagerService(Context systemContext) {
2610        mContext = systemContext;
2611        mFactoryTest = FactoryTest.getMode();
2612        mSystemThread = ActivityThread.currentActivityThread();
2613
2614        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2615
2616        mHandlerThread = new ServiceThread(TAG,
2617                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2618        mHandlerThread.start();
2619        mHandler = new MainHandler(mHandlerThread.getLooper());
2620        mUiHandler = new UiHandler();
2621
2622        /* static; one-time init here */
2623        if (sKillHandler == null) {
2624            sKillThread = new ServiceThread(TAG + ":kill",
2625                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2626            sKillThread.start();
2627            sKillHandler = new KillHandler(sKillThread.getLooper());
2628        }
2629
2630        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2631                "foreground", BROADCAST_FG_TIMEOUT, false);
2632        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2633                "background", BROADCAST_BG_TIMEOUT, true);
2634        mBroadcastQueues[0] = mFgBroadcastQueue;
2635        mBroadcastQueues[1] = mBgBroadcastQueue;
2636
2637        mServices = new ActiveServices(this);
2638        mProviderMap = new ProviderMap(this);
2639        mAppErrors = new AppErrors(mContext, this);
2640
2641        // TODO: Move creation of battery stats service outside of activity manager service.
2642        File dataDir = Environment.getDataDirectory();
2643        File systemDir = new File(dataDir, "system");
2644        systemDir.mkdirs();
2645        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2646        mBatteryStatsService.getActiveStatistics().readLocked();
2647        mBatteryStatsService.scheduleWriteToDisk();
2648        mOnBattery = DEBUG_POWER ? true
2649                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2650        mBatteryStatsService.getActiveStatistics().setCallback(this);
2651
2652        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2653
2654        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2655        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2656                new IAppOpsCallback.Stub() {
2657                    @Override public void opChanged(int op, int uid, String packageName) {
2658                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2659                            if (mAppOpsService.checkOperation(op, uid, packageName)
2660                                    != AppOpsManager.MODE_ALLOWED) {
2661                                runInBackgroundDisabled(uid);
2662                            }
2663                        }
2664                    }
2665                });
2666
2667        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2668
2669        mUserController = new UserController(this);
2670
2671        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2672            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2673
2674        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2675            mUseFifoUiScheduling = true;
2676        }
2677
2678        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2679
2680        mConfiguration.setToDefaults();
2681        mConfiguration.setLocales(LocaleList.getDefault());
2682
2683        mConfigurationSeq = mConfiguration.seq = 1;
2684        mProcessCpuTracker.init();
2685
2686        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2687        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2688        mStackSupervisor = new ActivityStackSupervisor(this);
2689        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2690        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2691
2692        mProcessCpuThread = new Thread("CpuTracker") {
2693            @Override
2694            public void run() {
2695                while (true) {
2696                    try {
2697                        try {
2698                            synchronized(this) {
2699                                final long now = SystemClock.uptimeMillis();
2700                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2701                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2702                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2703                                //        + ", write delay=" + nextWriteDelay);
2704                                if (nextWriteDelay < nextCpuDelay) {
2705                                    nextCpuDelay = nextWriteDelay;
2706                                }
2707                                if (nextCpuDelay > 0) {
2708                                    mProcessCpuMutexFree.set(true);
2709                                    this.wait(nextCpuDelay);
2710                                }
2711                            }
2712                        } catch (InterruptedException e) {
2713                        }
2714                        updateCpuStatsNow();
2715                    } catch (Exception e) {
2716                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2717                    }
2718                }
2719            }
2720        };
2721
2722        Watchdog.getInstance().addMonitor(this);
2723        Watchdog.getInstance().addThread(mHandler);
2724    }
2725
2726    public void setSystemServiceManager(SystemServiceManager mgr) {
2727        mSystemServiceManager = mgr;
2728    }
2729
2730    public void setInstaller(Installer installer) {
2731        mInstaller = installer;
2732    }
2733
2734    private void start() {
2735        Process.removeAllProcessGroups();
2736        mProcessCpuThread.start();
2737
2738        mBatteryStatsService.publish(mContext);
2739        mAppOpsService.publish(mContext);
2740        Slog.d("AppOps", "AppOpsService published");
2741        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2742    }
2743
2744    void onUserStoppedLocked(int userId) {
2745        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2746    }
2747
2748    public void initPowerManagement() {
2749        mStackSupervisor.initPowerManagement();
2750        mBatteryStatsService.initPowerManagement();
2751        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2752        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2753        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2754        mVoiceWakeLock.setReferenceCounted(false);
2755    }
2756
2757    @Override
2758    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2759            throws RemoteException {
2760        if (code == SYSPROPS_TRANSACTION) {
2761            // We need to tell all apps about the system property change.
2762            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2763            synchronized(this) {
2764                final int NP = mProcessNames.getMap().size();
2765                for (int ip=0; ip<NP; ip++) {
2766                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2767                    final int NA = apps.size();
2768                    for (int ia=0; ia<NA; ia++) {
2769                        ProcessRecord app = apps.valueAt(ia);
2770                        if (app.thread != null) {
2771                            procs.add(app.thread.asBinder());
2772                        }
2773                    }
2774                }
2775            }
2776
2777            int N = procs.size();
2778            for (int i=0; i<N; i++) {
2779                Parcel data2 = Parcel.obtain();
2780                try {
2781                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2782                } catch (RemoteException e) {
2783                }
2784                data2.recycle();
2785            }
2786        }
2787        try {
2788            return super.onTransact(code, data, reply, flags);
2789        } catch (RuntimeException e) {
2790            // The activity manager only throws security exceptions, so let's
2791            // log all others.
2792            if (!(e instanceof SecurityException)) {
2793                Slog.wtf(TAG, "Activity Manager Crash", e);
2794            }
2795            throw e;
2796        }
2797    }
2798
2799    void updateCpuStats() {
2800        final long now = SystemClock.uptimeMillis();
2801        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2802            return;
2803        }
2804        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2805            synchronized (mProcessCpuThread) {
2806                mProcessCpuThread.notify();
2807            }
2808        }
2809    }
2810
2811    void updateCpuStatsNow() {
2812        synchronized (mProcessCpuTracker) {
2813            mProcessCpuMutexFree.set(false);
2814            final long now = SystemClock.uptimeMillis();
2815            boolean haveNewCpuStats = false;
2816
2817            if (MONITOR_CPU_USAGE &&
2818                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2819                mLastCpuTime.set(now);
2820                mProcessCpuTracker.update();
2821                if (mProcessCpuTracker.hasGoodLastStats()) {
2822                    haveNewCpuStats = true;
2823                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2824                    //Slog.i(TAG, "Total CPU usage: "
2825                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2826
2827                    // Slog the cpu usage if the property is set.
2828                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2829                        int user = mProcessCpuTracker.getLastUserTime();
2830                        int system = mProcessCpuTracker.getLastSystemTime();
2831                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2832                        int irq = mProcessCpuTracker.getLastIrqTime();
2833                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2834                        int idle = mProcessCpuTracker.getLastIdleTime();
2835
2836                        int total = user + system + iowait + irq + softIrq + idle;
2837                        if (total == 0) total = 1;
2838
2839                        EventLog.writeEvent(EventLogTags.CPU,
2840                                ((user+system+iowait+irq+softIrq) * 100) / total,
2841                                (user * 100) / total,
2842                                (system * 100) / total,
2843                                (iowait * 100) / total,
2844                                (irq * 100) / total,
2845                                (softIrq * 100) / total);
2846                    }
2847                }
2848            }
2849
2850            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2851            synchronized(bstats) {
2852                synchronized(mPidsSelfLocked) {
2853                    if (haveNewCpuStats) {
2854                        if (bstats.startAddingCpuLocked()) {
2855                            int totalUTime = 0;
2856                            int totalSTime = 0;
2857                            final int N = mProcessCpuTracker.countStats();
2858                            for (int i=0; i<N; i++) {
2859                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2860                                if (!st.working) {
2861                                    continue;
2862                                }
2863                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2864                                totalUTime += st.rel_utime;
2865                                totalSTime += st.rel_stime;
2866                                if (pr != null) {
2867                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2868                                    if (ps == null || !ps.isActive()) {
2869                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2870                                                pr.info.uid, pr.processName);
2871                                    }
2872                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2873                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2874                                } else {
2875                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2876                                    if (ps == null || !ps.isActive()) {
2877                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2878                                                bstats.mapUid(st.uid), st.name);
2879                                    }
2880                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2881                                }
2882                            }
2883                            final int userTime = mProcessCpuTracker.getLastUserTime();
2884                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2885                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2886                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2887                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2888                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2889                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2890                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2891                        }
2892                    }
2893                }
2894
2895                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2896                    mLastWriteTime = now;
2897                    mBatteryStatsService.scheduleWriteToDisk();
2898                }
2899            }
2900        }
2901    }
2902
2903    @Override
2904    public void batteryNeedsCpuUpdate() {
2905        updateCpuStatsNow();
2906    }
2907
2908    @Override
2909    public void batteryPowerChanged(boolean onBattery) {
2910        // When plugging in, update the CPU stats first before changing
2911        // the plug state.
2912        updateCpuStatsNow();
2913        synchronized (this) {
2914            synchronized(mPidsSelfLocked) {
2915                mOnBattery = DEBUG_POWER ? true : onBattery;
2916            }
2917        }
2918    }
2919
2920    @Override
2921    public void batterySendBroadcast(Intent intent) {
2922        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2923                AppOpsManager.OP_NONE, null, false, false,
2924                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2925    }
2926
2927    /**
2928     * Initialize the application bind args. These are passed to each
2929     * process when the bindApplication() IPC is sent to the process. They're
2930     * lazily setup to make sure the services are running when they're asked for.
2931     */
2932    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2933        if (mAppBindArgs == null) {
2934            mAppBindArgs = new HashMap<>();
2935
2936            // Isolated processes won't get this optimization, so that we don't
2937            // violate the rules about which services they have access to.
2938            if (!isolated) {
2939                // Setup the application init args
2940                mAppBindArgs.put("package", ServiceManager.getService("package"));
2941                mAppBindArgs.put("window", ServiceManager.getService("window"));
2942                mAppBindArgs.put(Context.ALARM_SERVICE,
2943                        ServiceManager.getService(Context.ALARM_SERVICE));
2944            }
2945        }
2946        return mAppBindArgs;
2947    }
2948
2949    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2950        if (r == null || mFocusedActivity == r) {
2951            return false;
2952        }
2953
2954        if (!r.isFocusable()) {
2955            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2956            return false;
2957        }
2958
2959        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2960
2961        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2962        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2963                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2964        mDoingSetFocusedActivity = true;
2965
2966        final ActivityRecord last = mFocusedActivity;
2967        mFocusedActivity = r;
2968        if (r.task.isApplicationTask()) {
2969            if (mCurAppTimeTracker != r.appTimeTracker) {
2970                // We are switching app tracking.  Complete the current one.
2971                if (mCurAppTimeTracker != null) {
2972                    mCurAppTimeTracker.stop();
2973                    mHandler.obtainMessage(
2974                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2975                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2976                    mCurAppTimeTracker = null;
2977                }
2978                if (r.appTimeTracker != null) {
2979                    mCurAppTimeTracker = r.appTimeTracker;
2980                    startTimeTrackingFocusedActivityLocked();
2981                }
2982            } else {
2983                startTimeTrackingFocusedActivityLocked();
2984            }
2985        } else {
2986            r.appTimeTracker = null;
2987        }
2988        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2989        // TODO: Probably not, because we don't want to resume voice on switching
2990        // back to this activity
2991        if (r.task.voiceInteractor != null) {
2992            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2993        } else {
2994            finishRunningVoiceLocked();
2995            IVoiceInteractionSession session;
2996            if (last != null && ((session = last.task.voiceSession) != null
2997                    || (session = last.voiceSession) != null)) {
2998                // We had been in a voice interaction session, but now focused has
2999                // move to something different.  Just finish the session, we can't
3000                // return to it and retain the proper state and synchronization with
3001                // the voice interaction service.
3002                finishVoiceTask(session);
3003            }
3004        }
3005        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3006            mWindowManager.setFocusedApp(r.appToken, true);
3007        }
3008        applyUpdateLockStateLocked(r);
3009        applyUpdateVrModeLocked(r);
3010        if (mFocusedActivity.userId != mLastFocusedUserId) {
3011            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3012            mHandler.obtainMessage(
3013                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3014            mLastFocusedUserId = mFocusedActivity.userId;
3015        }
3016
3017        // Log a warning if the focused app is changed during the process. This could
3018        // indicate a problem of the focus setting logic!
3019        if (mFocusedActivity != r) Slog.w(TAG,
3020                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3021        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3022
3023        EventLogTags.writeAmFocusedActivity(
3024                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3025                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3026                reason);
3027        return true;
3028    }
3029
3030    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3031        if (mFocusedActivity != goingAway) {
3032            return;
3033        }
3034
3035        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3036        if (focusedStack != null) {
3037            final ActivityRecord top = focusedStack.topActivity();
3038            if (top != null && top.userId != mLastFocusedUserId) {
3039                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3040                mHandler.sendMessage(
3041                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3042                mLastFocusedUserId = top.userId;
3043            }
3044        }
3045
3046        // Try to move focus to another activity if possible.
3047        if (setFocusedActivityLocked(
3048                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3049            return;
3050        }
3051
3052        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3053                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3054        mFocusedActivity = null;
3055        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3056    }
3057
3058    @Override
3059    public void setFocusedStack(int stackId) {
3060        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3061        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3062        final long callingId = Binder.clearCallingIdentity();
3063        try {
3064            synchronized (this) {
3065                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3066                if (stack == null) {
3067                    return;
3068                }
3069                final ActivityRecord r = stack.topRunningActivityLocked();
3070                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3071                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3072                }
3073            }
3074        } finally {
3075            Binder.restoreCallingIdentity(callingId);
3076        }
3077    }
3078
3079    @Override
3080    public void setFocusedTask(int taskId) {
3081        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3082        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3083        final long callingId = Binder.clearCallingIdentity();
3084        try {
3085            synchronized (this) {
3086                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3087                if (task == null) {
3088                    return;
3089                }
3090                final ActivityRecord r = task.topRunningActivityLocked();
3091                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3092                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3093                }
3094            }
3095        } finally {
3096            Binder.restoreCallingIdentity(callingId);
3097        }
3098    }
3099
3100    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3101    @Override
3102    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3103        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3104        synchronized (this) {
3105            if (listener != null) {
3106                mTaskStackListeners.register(listener);
3107            }
3108        }
3109    }
3110
3111    @Override
3112    public void notifyActivityDrawn(IBinder token) {
3113        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3114        synchronized (this) {
3115            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3116            if (r != null) {
3117                r.task.stack.notifyActivityDrawnLocked(r);
3118            }
3119        }
3120    }
3121
3122    final void applyUpdateLockStateLocked(ActivityRecord r) {
3123        // Modifications to the UpdateLock state are done on our handler, outside
3124        // the activity manager's locks.  The new state is determined based on the
3125        // state *now* of the relevant activity record.  The object is passed to
3126        // the handler solely for logging detail, not to be consulted/modified.
3127        final boolean nextState = r != null && r.immersive;
3128        mHandler.sendMessage(
3129                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3130    }
3131
3132    final void applyUpdateVrModeLocked(ActivityRecord r) {
3133        mHandler.sendMessage(
3134                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3135    }
3136
3137    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3138        mHandler.sendMessage(
3139                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3140    }
3141
3142    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3143            ComponentName callingPackage, boolean immediate) {
3144        VrManagerInternal vrService =
3145                LocalServices.getService(VrManagerInternal.class);
3146        if (immediate) {
3147            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3148        } else {
3149            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3150        }
3151    }
3152
3153    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3154        Message msg = Message.obtain();
3155        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3156        msg.obj = r.task.askedCompatMode ? null : r;
3157        mUiHandler.sendMessage(msg);
3158    }
3159
3160    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3161        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3162                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3163            final Message msg = Message.obtain();
3164            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3165            msg.obj = r;
3166            mUiHandler.sendMessage(msg);
3167        }
3168    }
3169
3170    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3171            String what, Object obj, ProcessRecord srcApp) {
3172        app.lastActivityTime = now;
3173
3174        if (app.activities.size() > 0) {
3175            // Don't want to touch dependent processes that are hosting activities.
3176            return index;
3177        }
3178
3179        int lrui = mLruProcesses.lastIndexOf(app);
3180        if (lrui < 0) {
3181            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3182                    + what + " " + obj + " from " + srcApp);
3183            return index;
3184        }
3185
3186        if (lrui >= index) {
3187            // Don't want to cause this to move dependent processes *back* in the
3188            // list as if they were less frequently used.
3189            return index;
3190        }
3191
3192        if (lrui >= mLruProcessActivityStart) {
3193            // Don't want to touch dependent processes that are hosting activities.
3194            return index;
3195        }
3196
3197        mLruProcesses.remove(lrui);
3198        if (index > 0) {
3199            index--;
3200        }
3201        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3202                + " in LRU list: " + app);
3203        mLruProcesses.add(index, app);
3204        return index;
3205    }
3206
3207    static void killProcessGroup(int uid, int pid) {
3208        if (sKillHandler != null) {
3209            sKillHandler.sendMessage(
3210                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3211        } else {
3212            Slog.w(TAG, "Asked to kill process group before system bringup!");
3213            Process.killProcessGroup(uid, pid);
3214        }
3215    }
3216
3217    final void removeLruProcessLocked(ProcessRecord app) {
3218        int lrui = mLruProcesses.lastIndexOf(app);
3219        if (lrui >= 0) {
3220            if (!app.killed) {
3221                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3222                Process.killProcessQuiet(app.pid);
3223                killProcessGroup(app.uid, app.pid);
3224            }
3225            if (lrui <= mLruProcessActivityStart) {
3226                mLruProcessActivityStart--;
3227            }
3228            if (lrui <= mLruProcessServiceStart) {
3229                mLruProcessServiceStart--;
3230            }
3231            mLruProcesses.remove(lrui);
3232        }
3233    }
3234
3235    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3236            ProcessRecord client) {
3237        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3238                || app.treatLikeActivity;
3239        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3240        if (!activityChange && hasActivity) {
3241            // The process has activities, so we are only allowing activity-based adjustments
3242            // to move it.  It should be kept in the front of the list with other
3243            // processes that have activities, and we don't want those to change their
3244            // order except due to activity operations.
3245            return;
3246        }
3247
3248        mLruSeq++;
3249        final long now = SystemClock.uptimeMillis();
3250        app.lastActivityTime = now;
3251
3252        // First a quick reject: if the app is already at the position we will
3253        // put it, then there is nothing to do.
3254        if (hasActivity) {
3255            final int N = mLruProcesses.size();
3256            if (N > 0 && mLruProcesses.get(N-1) == app) {
3257                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3258                return;
3259            }
3260        } else {
3261            if (mLruProcessServiceStart > 0
3262                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3263                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3264                return;
3265            }
3266        }
3267
3268        int lrui = mLruProcesses.lastIndexOf(app);
3269
3270        if (app.persistent && lrui >= 0) {
3271            // We don't care about the position of persistent processes, as long as
3272            // they are in the list.
3273            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3274            return;
3275        }
3276
3277        /* In progress: compute new position first, so we can avoid doing work
3278           if the process is not actually going to move.  Not yet working.
3279        int addIndex;
3280        int nextIndex;
3281        boolean inActivity = false, inService = false;
3282        if (hasActivity) {
3283            // Process has activities, put it at the very tipsy-top.
3284            addIndex = mLruProcesses.size();
3285            nextIndex = mLruProcessServiceStart;
3286            inActivity = true;
3287        } else if (hasService) {
3288            // Process has services, put it at the top of the service list.
3289            addIndex = mLruProcessActivityStart;
3290            nextIndex = mLruProcessServiceStart;
3291            inActivity = true;
3292            inService = true;
3293        } else  {
3294            // Process not otherwise of interest, it goes to the top of the non-service area.
3295            addIndex = mLruProcessServiceStart;
3296            if (client != null) {
3297                int clientIndex = mLruProcesses.lastIndexOf(client);
3298                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3299                        + app);
3300                if (clientIndex >= 0 && addIndex > clientIndex) {
3301                    addIndex = clientIndex;
3302                }
3303            }
3304            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3305        }
3306
3307        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3308                + mLruProcessActivityStart + "): " + app);
3309        */
3310
3311        if (lrui >= 0) {
3312            if (lrui < mLruProcessActivityStart) {
3313                mLruProcessActivityStart--;
3314            }
3315            if (lrui < mLruProcessServiceStart) {
3316                mLruProcessServiceStart--;
3317            }
3318            /*
3319            if (addIndex > lrui) {
3320                addIndex--;
3321            }
3322            if (nextIndex > lrui) {
3323                nextIndex--;
3324            }
3325            */
3326            mLruProcesses.remove(lrui);
3327        }
3328
3329        /*
3330        mLruProcesses.add(addIndex, app);
3331        if (inActivity) {
3332            mLruProcessActivityStart++;
3333        }
3334        if (inService) {
3335            mLruProcessActivityStart++;
3336        }
3337        */
3338
3339        int nextIndex;
3340        if (hasActivity) {
3341            final int N = mLruProcesses.size();
3342            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3343                // Process doesn't have activities, but has clients with
3344                // activities...  move it up, but one below the top (the top
3345                // should always have a real activity).
3346                if (DEBUG_LRU) Slog.d(TAG_LRU,
3347                        "Adding to second-top of LRU activity list: " + app);
3348                mLruProcesses.add(N - 1, app);
3349                // To keep it from spamming the LRU list (by making a bunch of clients),
3350                // we will push down any other entries owned by the app.
3351                final int uid = app.info.uid;
3352                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3353                    ProcessRecord subProc = mLruProcesses.get(i);
3354                    if (subProc.info.uid == uid) {
3355                        // We want to push this one down the list.  If the process after
3356                        // it is for the same uid, however, don't do so, because we don't
3357                        // want them internally to be re-ordered.
3358                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3359                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3360                                    "Pushing uid " + uid + " swapping at " + i + ": "
3361                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3362                            ProcessRecord tmp = mLruProcesses.get(i);
3363                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3364                            mLruProcesses.set(i - 1, tmp);
3365                            i--;
3366                        }
3367                    } else {
3368                        // A gap, we can stop here.
3369                        break;
3370                    }
3371                }
3372            } else {
3373                // Process has activities, put it at the very tipsy-top.
3374                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3375                mLruProcesses.add(app);
3376            }
3377            nextIndex = mLruProcessServiceStart;
3378        } else if (hasService) {
3379            // Process has services, put it at the top of the service list.
3380            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3381            mLruProcesses.add(mLruProcessActivityStart, app);
3382            nextIndex = mLruProcessServiceStart;
3383            mLruProcessActivityStart++;
3384        } else  {
3385            // Process not otherwise of interest, it goes to the top of the non-service area.
3386            int index = mLruProcessServiceStart;
3387            if (client != null) {
3388                // If there is a client, don't allow the process to be moved up higher
3389                // in the list than that client.
3390                int clientIndex = mLruProcesses.lastIndexOf(client);
3391                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3392                        + " when updating " + app);
3393                if (clientIndex <= lrui) {
3394                    // Don't allow the client index restriction to push it down farther in the
3395                    // list than it already is.
3396                    clientIndex = lrui;
3397                }
3398                if (clientIndex >= 0 && index > clientIndex) {
3399                    index = clientIndex;
3400                }
3401            }
3402            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3403            mLruProcesses.add(index, app);
3404            nextIndex = index-1;
3405            mLruProcessActivityStart++;
3406            mLruProcessServiceStart++;
3407        }
3408
3409        // If the app is currently using a content provider or service,
3410        // bump those processes as well.
3411        for (int j=app.connections.size()-1; j>=0; j--) {
3412            ConnectionRecord cr = app.connections.valueAt(j);
3413            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3414                    && cr.binding.service.app != null
3415                    && cr.binding.service.app.lruSeq != mLruSeq
3416                    && !cr.binding.service.app.persistent) {
3417                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3418                        "service connection", cr, app);
3419            }
3420        }
3421        for (int j=app.conProviders.size()-1; j>=0; j--) {
3422            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3423            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3424                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3425                        "provider reference", cpr, app);
3426            }
3427        }
3428    }
3429
3430    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3431        if (uid == Process.SYSTEM_UID) {
3432            // The system gets to run in any process.  If there are multiple
3433            // processes with the same uid, just pick the first (this
3434            // should never happen).
3435            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3436            if (procs == null) return null;
3437            final int procCount = procs.size();
3438            for (int i = 0; i < procCount; i++) {
3439                final int procUid = procs.keyAt(i);
3440                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3441                    // Don't use an app process or different user process for system component.
3442                    continue;
3443                }
3444                return procs.valueAt(i);
3445            }
3446        }
3447        ProcessRecord proc = mProcessNames.get(processName, uid);
3448        if (false && proc != null && !keepIfLarge
3449                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3450                && proc.lastCachedPss >= 4000) {
3451            // Turn this condition on to cause killing to happen regularly, for testing.
3452            if (proc.baseProcessTracker != null) {
3453                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3454            }
3455            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3456        } else if (proc != null && !keepIfLarge
3457                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3458                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3459            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3460            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3461                if (proc.baseProcessTracker != null) {
3462                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3463                }
3464                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3465            }
3466        }
3467        return proc;
3468    }
3469
3470    void notifyPackageUse(String packageName, int reason) {
3471        IPackageManager pm = AppGlobals.getPackageManager();
3472        try {
3473            pm.notifyPackageUse(packageName, reason);
3474        } catch (RemoteException e) {
3475        }
3476    }
3477
3478    boolean isNextTransitionForward() {
3479        int transit = mWindowManager.getPendingAppTransition();
3480        return transit == TRANSIT_ACTIVITY_OPEN
3481                || transit == TRANSIT_TASK_OPEN
3482                || transit == TRANSIT_TASK_TO_FRONT;
3483    }
3484
3485    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3486            String processName, String abiOverride, int uid, Runnable crashHandler) {
3487        synchronized(this) {
3488            ApplicationInfo info = new ApplicationInfo();
3489            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3490            // For isolated processes, the former contains the parent's uid and the latter the
3491            // actual uid of the isolated process.
3492            // In the special case introduced by this method (which is, starting an isolated
3493            // process directly from the SystemServer without an actual parent app process) the
3494            // closest thing to a parent's uid is SYSTEM_UID.
3495            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3496            // the |isolated| logic in the ProcessRecord constructor.
3497            info.uid = Process.SYSTEM_UID;
3498            info.processName = processName;
3499            info.className = entryPoint;
3500            info.packageName = "android";
3501            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3502                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3503                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3504                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3505                    crashHandler);
3506            return proc != null ? proc.pid : 0;
3507        }
3508    }
3509
3510    final ProcessRecord startProcessLocked(String processName,
3511            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3512            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3513            boolean isolated, boolean keepIfLarge) {
3514        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3515                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3516                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3517                null /* crashHandler */);
3518    }
3519
3520    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3521            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3522            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3523            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3524        long startTime = SystemClock.elapsedRealtime();
3525        ProcessRecord app;
3526        if (!isolated) {
3527            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3528            checkTime(startTime, "startProcess: after getProcessRecord");
3529
3530            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3531                // If we are in the background, then check to see if this process
3532                // is bad.  If so, we will just silently fail.
3533                if (mAppErrors.isBadProcessLocked(info)) {
3534                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3535                            + "/" + info.processName);
3536                    return null;
3537                }
3538            } else {
3539                // When the user is explicitly starting a process, then clear its
3540                // crash count so that we won't make it bad until they see at
3541                // least one crash dialog again, and make the process good again
3542                // if it had been bad.
3543                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3544                        + "/" + info.processName);
3545                mAppErrors.resetProcessCrashTimeLocked(info);
3546                if (mAppErrors.isBadProcessLocked(info)) {
3547                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3548                            UserHandle.getUserId(info.uid), info.uid,
3549                            info.processName);
3550                    mAppErrors.clearBadProcessLocked(info);
3551                    if (app != null) {
3552                        app.bad = false;
3553                    }
3554                }
3555            }
3556        } else {
3557            // If this is an isolated process, it can't re-use an existing process.
3558            app = null;
3559        }
3560
3561        // app launch boost for big.little configurations
3562        // use cpusets to migrate freshly launched tasks to big cores
3563        nativeMigrateToBoost();
3564        mIsBoosted = true;
3565        mBoostStartTime = SystemClock.uptimeMillis();
3566        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3567        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3568
3569        // We don't have to do anything more if:
3570        // (1) There is an existing application record; and
3571        // (2) The caller doesn't think it is dead, OR there is no thread
3572        //     object attached to it so we know it couldn't have crashed; and
3573        // (3) There is a pid assigned to it, so it is either starting or
3574        //     already running.
3575        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3576                + " app=" + app + " knownToBeDead=" + knownToBeDead
3577                + " thread=" + (app != null ? app.thread : null)
3578                + " pid=" + (app != null ? app.pid : -1));
3579        if (app != null && app.pid > 0) {
3580            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3581                // We already have the app running, or are waiting for it to
3582                // come up (we have a pid but not yet its thread), so keep it.
3583                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3584                // If this is a new package in the process, add the package to the list
3585                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3586                checkTime(startTime, "startProcess: done, added package to proc");
3587                return app;
3588            }
3589
3590            // An application record is attached to a previous process,
3591            // clean it up now.
3592            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3593            checkTime(startTime, "startProcess: bad proc running, killing");
3594            killProcessGroup(app.uid, app.pid);
3595            handleAppDiedLocked(app, true, true);
3596            checkTime(startTime, "startProcess: done killing old proc");
3597        }
3598
3599        String hostingNameStr = hostingName != null
3600                ? hostingName.flattenToShortString() : null;
3601
3602        if (app == null) {
3603            checkTime(startTime, "startProcess: creating new process record");
3604            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3605            if (app == null) {
3606                Slog.w(TAG, "Failed making new process record for "
3607                        + processName + "/" + info.uid + " isolated=" + isolated);
3608                return null;
3609            }
3610            app.crashHandler = crashHandler;
3611            checkTime(startTime, "startProcess: done creating new process record");
3612        } else {
3613            // If this is a new package in the process, add the package to the list
3614            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3615            checkTime(startTime, "startProcess: added package to existing proc");
3616        }
3617
3618        // If the system is not ready yet, then hold off on starting this
3619        // process until it is.
3620        if (!mProcessesReady
3621                && !isAllowedWhileBooting(info)
3622                && !allowWhileBooting) {
3623            if (!mProcessesOnHold.contains(app)) {
3624                mProcessesOnHold.add(app);
3625            }
3626            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3627                    "System not ready, putting on hold: " + app);
3628            checkTime(startTime, "startProcess: returning with proc on hold");
3629            return app;
3630        }
3631
3632        checkTime(startTime, "startProcess: stepping in to startProcess");
3633        startProcessLocked(
3634                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3635        checkTime(startTime, "startProcess: done starting proc!");
3636        return (app.pid != 0) ? app : null;
3637    }
3638
3639    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3640        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3641    }
3642
3643    private final void startProcessLocked(ProcessRecord app,
3644            String hostingType, String hostingNameStr) {
3645        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3646                null /* entryPoint */, null /* entryPointArgs */);
3647    }
3648
3649    private final void startProcessLocked(ProcessRecord app, String hostingType,
3650            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3651        long startTime = SystemClock.elapsedRealtime();
3652        if (app.pid > 0 && app.pid != MY_PID) {
3653            checkTime(startTime, "startProcess: removing from pids map");
3654            synchronized (mPidsSelfLocked) {
3655                mPidsSelfLocked.remove(app.pid);
3656                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3657            }
3658            checkTime(startTime, "startProcess: done removing from pids map");
3659            app.setPid(0);
3660        }
3661
3662        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3663                "startProcessLocked removing on hold: " + app);
3664        mProcessesOnHold.remove(app);
3665
3666        checkTime(startTime, "startProcess: starting to update cpu stats");
3667        updateCpuStats();
3668        checkTime(startTime, "startProcess: done updating cpu stats");
3669
3670        try {
3671            try {
3672                final int userId = UserHandle.getUserId(app.uid);
3673                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3674            } catch (RemoteException e) {
3675                throw e.rethrowAsRuntimeException();
3676            }
3677
3678            int uid = app.uid;
3679            int[] gids = null;
3680            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3681            if (!app.isolated) {
3682                int[] permGids = null;
3683                try {
3684                    checkTime(startTime, "startProcess: getting gids from package manager");
3685                    final IPackageManager pm = AppGlobals.getPackageManager();
3686                    permGids = pm.getPackageGids(app.info.packageName,
3687                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3688                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3689                            MountServiceInternal.class);
3690                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3691                            app.info.packageName);
3692                } catch (RemoteException e) {
3693                    throw e.rethrowAsRuntimeException();
3694                }
3695
3696                /*
3697                 * Add shared application and profile GIDs so applications can share some
3698                 * resources like shared libraries and access user-wide resources
3699                 */
3700                if (ArrayUtils.isEmpty(permGids)) {
3701                    gids = new int[2];
3702                } else {
3703                    gids = new int[permGids.length + 2];
3704                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3705                }
3706                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3707                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3708            }
3709            checkTime(startTime, "startProcess: building args");
3710            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3711                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3712                        && mTopComponent != null
3713                        && app.processName.equals(mTopComponent.getPackageName())) {
3714                    uid = 0;
3715                }
3716                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3717                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3718                    uid = 0;
3719                }
3720            }
3721            int debugFlags = 0;
3722            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3723                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3724                // Also turn on CheckJNI for debuggable apps. It's quite
3725                // awkward to turn on otherwise.
3726                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3727            }
3728            // Run the app in safe mode if its manifest requests so or the
3729            // system is booted in safe mode.
3730            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3731                mSafeMode == true) {
3732                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3733            }
3734            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3735                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3736            }
3737            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3738            if ("true".equals(genDebugInfoProperty)) {
3739                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3740            }
3741            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3742                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3743            }
3744            if ("1".equals(SystemProperties.get("debug.assert"))) {
3745                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3746            }
3747            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3748                // Enable all debug flags required by the native debugger.
3749                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3750                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3751                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3752                mNativeDebuggingApp = null;
3753            }
3754
3755            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3756            if (requiredAbi == null) {
3757                requiredAbi = Build.SUPPORTED_ABIS[0];
3758            }
3759
3760            String instructionSet = null;
3761            if (app.info.primaryCpuAbi != null) {
3762                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3763            }
3764
3765            app.gids = gids;
3766            app.requiredAbi = requiredAbi;
3767            app.instructionSet = instructionSet;
3768
3769            // Start the process.  It will either succeed and return a result containing
3770            // the PID of the new process, or else throw a RuntimeException.
3771            boolean isActivityProcess = (entryPoint == null);
3772            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3773            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3774                    app.processName);
3775            checkTime(startTime, "startProcess: asking zygote to start proc");
3776            Process.ProcessStartResult startResult = Process.start(entryPoint,
3777                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3778                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3779                    app.info.dataDir, entryPointArgs);
3780            checkTime(startTime, "startProcess: returned from zygote!");
3781            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3782
3783            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3784            checkTime(startTime, "startProcess: done updating battery stats");
3785
3786            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3787                    UserHandle.getUserId(uid), startResult.pid, uid,
3788                    app.processName, hostingType,
3789                    hostingNameStr != null ? hostingNameStr : "");
3790
3791            try {
3792                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3793                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3794            } catch (RemoteException ex) {
3795                // Ignore
3796            }
3797
3798            if (app.persistent) {
3799                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3800            }
3801
3802            checkTime(startTime, "startProcess: building log message");
3803            StringBuilder buf = mStringBuilder;
3804            buf.setLength(0);
3805            buf.append("Start proc ");
3806            buf.append(startResult.pid);
3807            buf.append(':');
3808            buf.append(app.processName);
3809            buf.append('/');
3810            UserHandle.formatUid(buf, uid);
3811            if (!isActivityProcess) {
3812                buf.append(" [");
3813                buf.append(entryPoint);
3814                buf.append("]");
3815            }
3816            buf.append(" for ");
3817            buf.append(hostingType);
3818            if (hostingNameStr != null) {
3819                buf.append(" ");
3820                buf.append(hostingNameStr);
3821            }
3822            Slog.i(TAG, buf.toString());
3823            app.setPid(startResult.pid);
3824            app.usingWrapper = startResult.usingWrapper;
3825            app.removed = false;
3826            app.killed = false;
3827            app.killedByAm = false;
3828            checkTime(startTime, "startProcess: starting to update pids map");
3829            synchronized (mPidsSelfLocked) {
3830                this.mPidsSelfLocked.put(startResult.pid, app);
3831                if (isActivityProcess) {
3832                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3833                    msg.obj = app;
3834                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3835                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3836                }
3837            }
3838            checkTime(startTime, "startProcess: done updating pids map");
3839        } catch (RuntimeException e) {
3840            Slog.e(TAG, "Failure starting process " + app.processName, e);
3841
3842            // Something went very wrong while trying to start this process; one
3843            // common case is when the package is frozen due to an active
3844            // upgrade. To recover, clean up any active bookkeeping related to
3845            // starting this process. (We already invoked this method once when
3846            // the package was initially frozen through KILL_APPLICATION_MSG, so
3847            // it doesn't hurt to use it again.)
3848            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3849                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3850        }
3851    }
3852
3853    void updateUsageStats(ActivityRecord component, boolean resumed) {
3854        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3855                "updateUsageStats: comp=" + component + "res=" + resumed);
3856        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3857        if (resumed) {
3858            if (mUsageStatsService != null) {
3859                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3860                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3861            }
3862            synchronized (stats) {
3863                stats.noteActivityResumedLocked(component.app.uid);
3864            }
3865        } else {
3866            if (mUsageStatsService != null) {
3867                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3868                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3869            }
3870            synchronized (stats) {
3871                stats.noteActivityPausedLocked(component.app.uid);
3872            }
3873        }
3874    }
3875
3876    Intent getHomeIntent() {
3877        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3878        intent.setComponent(mTopComponent);
3879        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3880        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3881            intent.addCategory(Intent.CATEGORY_HOME);
3882        }
3883        return intent;
3884    }
3885
3886    boolean startHomeActivityLocked(int userId, String reason) {
3887        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3888                && mTopAction == null) {
3889            // We are running in factory test mode, but unable to find
3890            // the factory test app, so just sit around displaying the
3891            // error message and don't try to start anything.
3892            return false;
3893        }
3894        Intent intent = getHomeIntent();
3895        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3896        if (aInfo != null) {
3897            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3898            // Don't do this if the home app is currently being
3899            // instrumented.
3900            aInfo = new ActivityInfo(aInfo);
3901            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3902            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3903                    aInfo.applicationInfo.uid, true);
3904            if (app == null || app.instrumentationClass == null) {
3905                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3906                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3907            }
3908        } else {
3909            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3910        }
3911
3912        return true;
3913    }
3914
3915    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3916        ActivityInfo ai = null;
3917        ComponentName comp = intent.getComponent();
3918        try {
3919            if (comp != null) {
3920                // Factory test.
3921                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3922            } else {
3923                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3924                        intent,
3925                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3926                        flags, userId);
3927
3928                if (info != null) {
3929                    ai = info.activityInfo;
3930                }
3931            }
3932        } catch (RemoteException e) {
3933            // ignore
3934        }
3935
3936        return ai;
3937    }
3938
3939    /**
3940     * Starts the "new version setup screen" if appropriate.
3941     */
3942    void startSetupActivityLocked() {
3943        // Only do this once per boot.
3944        if (mCheckedForSetup) {
3945            return;
3946        }
3947
3948        // We will show this screen if the current one is a different
3949        // version than the last one shown, and we are not running in
3950        // low-level factory test mode.
3951        final ContentResolver resolver = mContext.getContentResolver();
3952        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3953                Settings.Global.getInt(resolver,
3954                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3955            mCheckedForSetup = true;
3956
3957            // See if we should be showing the platform update setup UI.
3958            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3959            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3960                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3961            if (!ris.isEmpty()) {
3962                final ResolveInfo ri = ris.get(0);
3963                String vers = ri.activityInfo.metaData != null
3964                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3965                        : null;
3966                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3967                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3968                            Intent.METADATA_SETUP_VERSION);
3969                }
3970                String lastVers = Settings.Secure.getString(
3971                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3972                if (vers != null && !vers.equals(lastVers)) {
3973                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3974                    intent.setComponent(new ComponentName(
3975                            ri.activityInfo.packageName, ri.activityInfo.name));
3976                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3977                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3978                            null, 0, 0, 0, null, false, false, null, null, null);
3979                }
3980            }
3981        }
3982    }
3983
3984    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3985        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3986    }
3987
3988    void enforceNotIsolatedCaller(String caller) {
3989        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3990            throw new SecurityException("Isolated process not allowed to call " + caller);
3991        }
3992    }
3993
3994    void enforceShellRestriction(String restriction, int userHandle) {
3995        if (Binder.getCallingUid() == Process.SHELL_UID) {
3996            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3997                throw new SecurityException("Shell does not have permission to access user "
3998                        + userHandle);
3999            }
4000        }
4001    }
4002
4003    @Override
4004    public int getFrontActivityScreenCompatMode() {
4005        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4006        synchronized (this) {
4007            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4008        }
4009    }
4010
4011    @Override
4012    public void setFrontActivityScreenCompatMode(int mode) {
4013        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4014                "setFrontActivityScreenCompatMode");
4015        synchronized (this) {
4016            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4017        }
4018    }
4019
4020    @Override
4021    public int getPackageScreenCompatMode(String packageName) {
4022        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4023        synchronized (this) {
4024            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4025        }
4026    }
4027
4028    @Override
4029    public void setPackageScreenCompatMode(String packageName, int mode) {
4030        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4031                "setPackageScreenCompatMode");
4032        synchronized (this) {
4033            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4034        }
4035    }
4036
4037    @Override
4038    public boolean getPackageAskScreenCompat(String packageName) {
4039        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4040        synchronized (this) {
4041            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4042        }
4043    }
4044
4045    @Override
4046    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4047        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4048                "setPackageAskScreenCompat");
4049        synchronized (this) {
4050            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4051        }
4052    }
4053
4054    private boolean hasUsageStatsPermission(String callingPackage) {
4055        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4056                Binder.getCallingUid(), callingPackage);
4057        if (mode == AppOpsManager.MODE_DEFAULT) {
4058            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4059                    == PackageManager.PERMISSION_GRANTED;
4060        }
4061        return mode == AppOpsManager.MODE_ALLOWED;
4062    }
4063
4064    @Override
4065    public int getPackageProcessState(String packageName, String callingPackage) {
4066        if (!hasUsageStatsPermission(callingPackage)) {
4067            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4068                    "getPackageProcessState");
4069        }
4070
4071        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4072        synchronized (this) {
4073            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4074                final ProcessRecord proc = mLruProcesses.get(i);
4075                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4076                        || procState > proc.setProcState) {
4077                    boolean found = false;
4078                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4079                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4080                            procState = proc.setProcState;
4081                            found = true;
4082                        }
4083                    }
4084                    if (proc.pkgDeps != null && !found) {
4085                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4086                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4087                                procState = proc.setProcState;
4088                                break;
4089                            }
4090                        }
4091                    }
4092                }
4093            }
4094        }
4095        return procState;
4096    }
4097
4098    @Override
4099    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4100        synchronized (this) {
4101            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4102            if (app == null) {
4103                return false;
4104            }
4105            if (app.trimMemoryLevel < level && app.thread != null &&
4106                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4107                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4108                try {
4109                    app.thread.scheduleTrimMemory(level);
4110                    app.trimMemoryLevel = level;
4111                    return true;
4112                } catch (RemoteException e) {
4113                    // Fallthrough to failure case.
4114                }
4115            }
4116        }
4117        return false;
4118    }
4119
4120    private void dispatchProcessesChanged() {
4121        int N;
4122        synchronized (this) {
4123            N = mPendingProcessChanges.size();
4124            if (mActiveProcessChanges.length < N) {
4125                mActiveProcessChanges = new ProcessChangeItem[N];
4126            }
4127            mPendingProcessChanges.toArray(mActiveProcessChanges);
4128            mPendingProcessChanges.clear();
4129            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4130                    "*** Delivering " + N + " process changes");
4131        }
4132
4133        int i = mProcessObservers.beginBroadcast();
4134        while (i > 0) {
4135            i--;
4136            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4137            if (observer != null) {
4138                try {
4139                    for (int j=0; j<N; j++) {
4140                        ProcessChangeItem item = mActiveProcessChanges[j];
4141                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4142                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4143                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4144                                    + item.uid + ": " + item.foregroundActivities);
4145                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4146                                    item.foregroundActivities);
4147                        }
4148                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4149                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4150                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4151                                    + ": " + item.processState);
4152                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4153                        }
4154                    }
4155                } catch (RemoteException e) {
4156                }
4157            }
4158        }
4159        mProcessObservers.finishBroadcast();
4160
4161        synchronized (this) {
4162            for (int j=0; j<N; j++) {
4163                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4164            }
4165        }
4166    }
4167
4168    private void dispatchProcessDied(int pid, int uid) {
4169        int i = mProcessObservers.beginBroadcast();
4170        while (i > 0) {
4171            i--;
4172            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4173            if (observer != null) {
4174                try {
4175                    observer.onProcessDied(pid, uid);
4176                } catch (RemoteException e) {
4177                }
4178            }
4179        }
4180        mProcessObservers.finishBroadcast();
4181    }
4182
4183    private void dispatchUidsChanged() {
4184        int N;
4185        synchronized (this) {
4186            N = mPendingUidChanges.size();
4187            if (mActiveUidChanges.length < N) {
4188                mActiveUidChanges = new UidRecord.ChangeItem[N];
4189            }
4190            for (int i=0; i<N; i++) {
4191                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4192                mActiveUidChanges[i] = change;
4193                if (change.uidRecord != null) {
4194                    change.uidRecord.pendingChange = null;
4195                    change.uidRecord = null;
4196                }
4197            }
4198            mPendingUidChanges.clear();
4199            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                    "*** Delivering " + N + " uid changes");
4201        }
4202
4203        if (mLocalPowerManager != null) {
4204            for (int j=0; j<N; j++) {
4205                UidRecord.ChangeItem item = mActiveUidChanges[j];
4206                if (item.change == UidRecord.CHANGE_GONE
4207                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4208                    mLocalPowerManager.uidGone(item.uid);
4209                } else {
4210                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4211                }
4212            }
4213        }
4214
4215        int i = mUidObservers.beginBroadcast();
4216        while (i > 0) {
4217            i--;
4218            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4219            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4220            if (observer != null) {
4221                try {
4222                    for (int j=0; j<N; j++) {
4223                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4224                        final int change = item.change;
4225                        UidRecord validateUid = null;
4226                        if (VALIDATE_UID_STATES && i == 0) {
4227                            validateUid = mValidateUids.get(item.uid);
4228                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4229                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4230                                validateUid = new UidRecord(item.uid);
4231                                mValidateUids.put(item.uid, validateUid);
4232                            }
4233                        }
4234                        if (change == UidRecord.CHANGE_IDLE
4235                                || change == UidRecord.CHANGE_GONE_IDLE) {
4236                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4237                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4238                                        "UID idle uid=" + item.uid);
4239                                observer.onUidIdle(item.uid);
4240                            }
4241                            if (VALIDATE_UID_STATES && i == 0) {
4242                                if (validateUid != null) {
4243                                    validateUid.idle = true;
4244                                }
4245                            }
4246                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4247                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4248                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4249                                        "UID active uid=" + item.uid);
4250                                observer.onUidActive(item.uid);
4251                            }
4252                            if (VALIDATE_UID_STATES && i == 0) {
4253                                validateUid.idle = false;
4254                            }
4255                        }
4256                        if (change == UidRecord.CHANGE_GONE
4257                                || change == UidRecord.CHANGE_GONE_IDLE) {
4258                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4259                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4260                                        "UID gone uid=" + item.uid);
4261                                observer.onUidGone(item.uid);
4262                            }
4263                            if (VALIDATE_UID_STATES && i == 0) {
4264                                if (validateUid != null) {
4265                                    mValidateUids.remove(item.uid);
4266                                }
4267                            }
4268                        } else {
4269                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4270                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4271                                        "UID CHANGED uid=" + item.uid
4272                                                + ": " + item.processState);
4273                                observer.onUidStateChanged(item.uid, item.processState);
4274                            }
4275                            if (VALIDATE_UID_STATES && i == 0) {
4276                                validateUid.curProcState = validateUid.setProcState
4277                                        = item.processState;
4278                            }
4279                        }
4280                    }
4281                } catch (RemoteException e) {
4282                }
4283            }
4284        }
4285        mUidObservers.finishBroadcast();
4286
4287        synchronized (this) {
4288            for (int j=0; j<N; j++) {
4289                mAvailUidChanges.add(mActiveUidChanges[j]);
4290            }
4291        }
4292    }
4293
4294    @Override
4295    public final int startActivity(IApplicationThread caller, String callingPackage,
4296            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4297            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4298        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4299                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4300                UserHandle.getCallingUserId());
4301    }
4302
4303    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4304        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4305        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4306                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4307                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4308
4309        // TODO: Switch to user app stacks here.
4310        String mimeType = intent.getType();
4311        final Uri data = intent.getData();
4312        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4313            mimeType = getProviderMimeType(data, userId);
4314        }
4315        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4316
4317        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4318        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4319                null, 0, 0, null, null, null, null, false, userId, container, null);
4320    }
4321
4322    @Override
4323    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4324            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4325            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4326        enforceNotIsolatedCaller("startActivity");
4327        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4328                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4329        // TODO: Switch to user app stacks here.
4330        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4331                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4332                profilerInfo, null, null, bOptions, false, userId, null, null);
4333    }
4334
4335    @Override
4336    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4337            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4338            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4339            int userId) {
4340
4341        // This is very dangerous -- it allows you to perform a start activity (including
4342        // permission grants) as any app that may launch one of your own activities.  So
4343        // we will only allow this to be done from activities that are part of the core framework,
4344        // and then only when they are running as the system.
4345        final ActivityRecord sourceRecord;
4346        final int targetUid;
4347        final String targetPackage;
4348        synchronized (this) {
4349            if (resultTo == null) {
4350                throw new SecurityException("Must be called from an activity");
4351            }
4352            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4353            if (sourceRecord == null) {
4354                throw new SecurityException("Called with bad activity token: " + resultTo);
4355            }
4356            if (!sourceRecord.info.packageName.equals("android")) {
4357                throw new SecurityException(
4358                        "Must be called from an activity that is declared in the android package");
4359            }
4360            if (sourceRecord.app == null) {
4361                throw new SecurityException("Called without a process attached to activity");
4362            }
4363            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4364                // This is still okay, as long as this activity is running under the
4365                // uid of the original calling activity.
4366                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4367                    throw new SecurityException(
4368                            "Calling activity in uid " + sourceRecord.app.uid
4369                                    + " must be system uid or original calling uid "
4370                                    + sourceRecord.launchedFromUid);
4371                }
4372            }
4373            if (ignoreTargetSecurity) {
4374                if (intent.getComponent() == null) {
4375                    throw new SecurityException(
4376                            "Component must be specified with ignoreTargetSecurity");
4377                }
4378                if (intent.getSelector() != null) {
4379                    throw new SecurityException(
4380                            "Selector not allowed with ignoreTargetSecurity");
4381                }
4382            }
4383            targetUid = sourceRecord.launchedFromUid;
4384            targetPackage = sourceRecord.launchedFromPackage;
4385        }
4386
4387        if (userId == UserHandle.USER_NULL) {
4388            userId = UserHandle.getUserId(sourceRecord.app.uid);
4389        }
4390
4391        // TODO: Switch to user app stacks here.
4392        try {
4393            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4394                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4395                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4396            return ret;
4397        } catch (SecurityException e) {
4398            // XXX need to figure out how to propagate to original app.
4399            // A SecurityException here is generally actually a fault of the original
4400            // calling activity (such as a fairly granting permissions), so propagate it
4401            // back to them.
4402            /*
4403            StringBuilder msg = new StringBuilder();
4404            msg.append("While launching");
4405            msg.append(intent.toString());
4406            msg.append(": ");
4407            msg.append(e.getMessage());
4408            */
4409            throw e;
4410        }
4411    }
4412
4413    @Override
4414    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4415            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4416            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4417        enforceNotIsolatedCaller("startActivityAndWait");
4418        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4419                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4420        WaitResult res = new WaitResult();
4421        // TODO: Switch to user app stacks here.
4422        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4423                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4424                bOptions, false, userId, null, null);
4425        return res;
4426    }
4427
4428    @Override
4429    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4430            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4431            int startFlags, Configuration config, Bundle bOptions, int userId) {
4432        enforceNotIsolatedCaller("startActivityWithConfig");
4433        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4434                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4435        // TODO: Switch to user app stacks here.
4436        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4437                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4438                null, null, config, bOptions, false, userId, null, null);
4439        return ret;
4440    }
4441
4442    @Override
4443    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4444            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4445            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4446            throws TransactionTooLargeException {
4447        enforceNotIsolatedCaller("startActivityIntentSender");
4448        // Refuse possible leaked file descriptors
4449        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4450            throw new IllegalArgumentException("File descriptors passed in Intent");
4451        }
4452
4453        IIntentSender sender = intent.getTarget();
4454        if (!(sender instanceof PendingIntentRecord)) {
4455            throw new IllegalArgumentException("Bad PendingIntent object");
4456        }
4457
4458        PendingIntentRecord pir = (PendingIntentRecord)sender;
4459
4460        synchronized (this) {
4461            // If this is coming from the currently resumed activity, it is
4462            // effectively saying that app switches are allowed at this point.
4463            final ActivityStack stack = getFocusedStack();
4464            if (stack.mResumedActivity != null &&
4465                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4466                mAppSwitchesAllowedTime = 0;
4467            }
4468        }
4469        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4470                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4471        return ret;
4472    }
4473
4474    @Override
4475    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4476            Intent intent, String resolvedType, IVoiceInteractionSession session,
4477            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4478            Bundle bOptions, int userId) {
4479        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4480                != PackageManager.PERMISSION_GRANTED) {
4481            String msg = "Permission Denial: startVoiceActivity() from pid="
4482                    + Binder.getCallingPid()
4483                    + ", uid=" + Binder.getCallingUid()
4484                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4485            Slog.w(TAG, msg);
4486            throw new SecurityException(msg);
4487        }
4488        if (session == null || interactor == null) {
4489            throw new NullPointerException("null session or interactor");
4490        }
4491        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4492                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4493        // TODO: Switch to user app stacks here.
4494        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4495                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4496                null, bOptions, false, userId, null, null);
4497    }
4498
4499    @Override
4500    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4501            throws RemoteException {
4502        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4503        synchronized (this) {
4504            ActivityRecord activity = getFocusedStack().topActivity();
4505            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4506                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4507            }
4508            if (mRunningVoice != null || activity.task.voiceSession != null
4509                    || activity.voiceSession != null) {
4510                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4511                return;
4512            }
4513            if (activity.pendingVoiceInteractionStart) {
4514                Slog.w(TAG, "Pending start of voice interaction already.");
4515                return;
4516            }
4517            activity.pendingVoiceInteractionStart = true;
4518        }
4519        LocalServices.getService(VoiceInteractionManagerInternal.class)
4520                .startLocalVoiceInteraction(callingActivity, options);
4521    }
4522
4523    @Override
4524    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4525        LocalServices.getService(VoiceInteractionManagerInternal.class)
4526                .stopLocalVoiceInteraction(callingActivity);
4527    }
4528
4529    @Override
4530    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4531        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4532                .supportsLocalVoiceInteraction();
4533    }
4534
4535    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4536            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4537        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4538        if (activityToCallback == null) return;
4539        activityToCallback.setVoiceSessionLocked(voiceSession);
4540
4541        // Inform the activity
4542        try {
4543            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4544                    voiceInteractor);
4545            long token = Binder.clearCallingIdentity();
4546            try {
4547                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4548            } finally {
4549                Binder.restoreCallingIdentity(token);
4550            }
4551            // TODO: VI Should we cache the activity so that it's easier to find later
4552            // rather than scan through all the stacks and activities?
4553        } catch (RemoteException re) {
4554            activityToCallback.clearVoiceSessionLocked();
4555            // TODO: VI Should this terminate the voice session?
4556        }
4557    }
4558
4559    @Override
4560    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4561        synchronized (this) {
4562            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4563                if (keepAwake) {
4564                    mVoiceWakeLock.acquire();
4565                } else {
4566                    mVoiceWakeLock.release();
4567                }
4568            }
4569        }
4570    }
4571
4572    @Override
4573    public boolean startNextMatchingActivity(IBinder callingActivity,
4574            Intent intent, Bundle bOptions) {
4575        // Refuse possible leaked file descriptors
4576        if (intent != null && intent.hasFileDescriptors() == true) {
4577            throw new IllegalArgumentException("File descriptors passed in Intent");
4578        }
4579        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4580
4581        synchronized (this) {
4582            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4583            if (r == null) {
4584                ActivityOptions.abort(options);
4585                return false;
4586            }
4587            if (r.app == null || r.app.thread == null) {
4588                // The caller is not running...  d'oh!
4589                ActivityOptions.abort(options);
4590                return false;
4591            }
4592            intent = new Intent(intent);
4593            // The caller is not allowed to change the data.
4594            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4595            // And we are resetting to find the next component...
4596            intent.setComponent(null);
4597
4598            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4599
4600            ActivityInfo aInfo = null;
4601            try {
4602                List<ResolveInfo> resolves =
4603                    AppGlobals.getPackageManager().queryIntentActivities(
4604                            intent, r.resolvedType,
4605                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4606                            UserHandle.getCallingUserId()).getList();
4607
4608                // Look for the original activity in the list...
4609                final int N = resolves != null ? resolves.size() : 0;
4610                for (int i=0; i<N; i++) {
4611                    ResolveInfo rInfo = resolves.get(i);
4612                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4613                            && rInfo.activityInfo.name.equals(r.info.name)) {
4614                        // We found the current one...  the next matching is
4615                        // after it.
4616                        i++;
4617                        if (i<N) {
4618                            aInfo = resolves.get(i).activityInfo;
4619                        }
4620                        if (debug) {
4621                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4622                                    + "/" + r.info.name);
4623                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4624                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4625                        }
4626                        break;
4627                    }
4628                }
4629            } catch (RemoteException e) {
4630            }
4631
4632            if (aInfo == null) {
4633                // Nobody who is next!
4634                ActivityOptions.abort(options);
4635                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4636                return false;
4637            }
4638
4639            intent.setComponent(new ComponentName(
4640                    aInfo.applicationInfo.packageName, aInfo.name));
4641            intent.setFlags(intent.getFlags()&~(
4642                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4643                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4644                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4645                    Intent.FLAG_ACTIVITY_NEW_TASK));
4646
4647            // Okay now we need to start the new activity, replacing the
4648            // currently running activity.  This is a little tricky because
4649            // we want to start the new one as if the current one is finished,
4650            // but not finish the current one first so that there is no flicker.
4651            // And thus...
4652            final boolean wasFinishing = r.finishing;
4653            r.finishing = true;
4654
4655            // Propagate reply information over to the new activity.
4656            final ActivityRecord resultTo = r.resultTo;
4657            final String resultWho = r.resultWho;
4658            final int requestCode = r.requestCode;
4659            r.resultTo = null;
4660            if (resultTo != null) {
4661                resultTo.removeResultsLocked(r, resultWho, requestCode);
4662            }
4663
4664            final long origId = Binder.clearCallingIdentity();
4665            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4666                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4667                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4668                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4669                    false, false, null, null, null);
4670            Binder.restoreCallingIdentity(origId);
4671
4672            r.finishing = wasFinishing;
4673            if (res != ActivityManager.START_SUCCESS) {
4674                return false;
4675            }
4676            return true;
4677        }
4678    }
4679
4680    @Override
4681    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4682        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4683            String msg = "Permission Denial: startActivityFromRecents called without " +
4684                    START_TASKS_FROM_RECENTS;
4685            Slog.w(TAG, msg);
4686            throw new SecurityException(msg);
4687        }
4688        final long origId = Binder.clearCallingIdentity();
4689        try {
4690            synchronized (this) {
4691                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4692            }
4693        } finally {
4694            Binder.restoreCallingIdentity(origId);
4695        }
4696    }
4697
4698    final int startActivityInPackage(int uid, String callingPackage,
4699            Intent intent, String resolvedType, IBinder resultTo,
4700            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4701            IActivityContainer container, TaskRecord inTask) {
4702
4703        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4704                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4705
4706        // TODO: Switch to user app stacks here.
4707        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4708                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4709                null, null, null, bOptions, false, userId, container, inTask);
4710        return ret;
4711    }
4712
4713    @Override
4714    public final int startActivities(IApplicationThread caller, String callingPackage,
4715            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4716            int userId) {
4717        enforceNotIsolatedCaller("startActivities");
4718        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4719                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4720        // TODO: Switch to user app stacks here.
4721        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4722                resolvedTypes, resultTo, bOptions, userId);
4723        return ret;
4724    }
4725
4726    final int startActivitiesInPackage(int uid, String callingPackage,
4727            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4728            Bundle bOptions, int userId) {
4729
4730        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4731                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4732        // TODO: Switch to user app stacks here.
4733        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4734                resultTo, bOptions, userId);
4735        return ret;
4736    }
4737
4738    @Override
4739    public void reportActivityFullyDrawn(IBinder token) {
4740        synchronized (this) {
4741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4742            if (r == null) {
4743                return;
4744            }
4745            r.reportFullyDrawnLocked();
4746        }
4747    }
4748
4749    @Override
4750    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4751        synchronized (this) {
4752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4753            if (r == null) {
4754                return;
4755            }
4756            TaskRecord task = r.task;
4757            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4758                // Fixed screen orientation isn't supported when activities aren't in full screen
4759                // mode.
4760                return;
4761            }
4762            final long origId = Binder.clearCallingIdentity();
4763            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4764            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4765                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4766            if (config != null) {
4767                r.frozenBeforeDestroy = true;
4768                if (!updateConfigurationLocked(config, r, false)) {
4769                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4770                }
4771            }
4772            Binder.restoreCallingIdentity(origId);
4773        }
4774    }
4775
4776    @Override
4777    public int getRequestedOrientation(IBinder token) {
4778        synchronized (this) {
4779            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4780            if (r == null) {
4781                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4782            }
4783            return mWindowManager.getAppOrientation(r.appToken);
4784        }
4785    }
4786
4787    /**
4788     * This is the internal entry point for handling Activity.finish().
4789     *
4790     * @param token The Binder token referencing the Activity we want to finish.
4791     * @param resultCode Result code, if any, from this Activity.
4792     * @param resultData Result data (Intent), if any, from this Activity.
4793     * @param finishTask Whether to finish the task associated with this Activity.
4794     *
4795     * @return Returns true if the activity successfully finished, or false if it is still running.
4796     */
4797    @Override
4798    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4799            int finishTask) {
4800        // Refuse possible leaked file descriptors
4801        if (resultData != null && resultData.hasFileDescriptors() == true) {
4802            throw new IllegalArgumentException("File descriptors passed in Intent");
4803        }
4804
4805        synchronized(this) {
4806            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4807            if (r == null) {
4808                return true;
4809            }
4810            // Keep track of the root activity of the task before we finish it
4811            TaskRecord tr = r.task;
4812            ActivityRecord rootR = tr.getRootActivity();
4813            if (rootR == null) {
4814                Slog.w(TAG, "Finishing task with all activities already finished");
4815            }
4816            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4817            // finish.
4818            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4819                    mStackSupervisor.isLastLockedTask(tr)) {
4820                Slog.i(TAG, "Not finishing task in lock task mode");
4821                mStackSupervisor.showLockTaskToast();
4822                return false;
4823            }
4824            if (mController != null) {
4825                // Find the first activity that is not finishing.
4826                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4827                if (next != null) {
4828                    // ask watcher if this is allowed
4829                    boolean resumeOK = true;
4830                    try {
4831                        resumeOK = mController.activityResuming(next.packageName);
4832                    } catch (RemoteException e) {
4833                        mController = null;
4834                        Watchdog.getInstance().setActivityController(null);
4835                    }
4836
4837                    if (!resumeOK) {
4838                        Slog.i(TAG, "Not finishing activity because controller resumed");
4839                        return false;
4840                    }
4841                }
4842            }
4843            final long origId = Binder.clearCallingIdentity();
4844            try {
4845                boolean res;
4846                final boolean finishWithRootActivity =
4847                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4848                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4849                        || (finishWithRootActivity && r == rootR)) {
4850                    // If requested, remove the task that is associated to this activity only if it
4851                    // was the root activity in the task. The result code and data is ignored
4852                    // because we don't support returning them across task boundaries. Also, to
4853                    // keep backwards compatibility we remove the task from recents when finishing
4854                    // task with root activity.
4855                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4856                    if (!res) {
4857                        Slog.i(TAG, "Removing task failed to finish activity");
4858                    }
4859                } else {
4860                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4861                            resultData, "app-request", true);
4862                    if (!res) {
4863                        Slog.i(TAG, "Failed to finish by app-request");
4864                    }
4865                }
4866                return res;
4867            } finally {
4868                Binder.restoreCallingIdentity(origId);
4869            }
4870        }
4871    }
4872
4873    @Override
4874    public final void finishHeavyWeightApp() {
4875        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4876                != PackageManager.PERMISSION_GRANTED) {
4877            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4878                    + Binder.getCallingPid()
4879                    + ", uid=" + Binder.getCallingUid()
4880                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4881            Slog.w(TAG, msg);
4882            throw new SecurityException(msg);
4883        }
4884
4885        synchronized(this) {
4886            if (mHeavyWeightProcess == null) {
4887                return;
4888            }
4889
4890            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4891            for (int i = 0; i < activities.size(); i++) {
4892                ActivityRecord r = activities.get(i);
4893                if (!r.finishing && r.isInStackLocked()) {
4894                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4895                            null, "finish-heavy", true);
4896                }
4897            }
4898
4899            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4900                    mHeavyWeightProcess.userId, 0));
4901            mHeavyWeightProcess = null;
4902        }
4903    }
4904
4905    @Override
4906    public void crashApplication(int uid, int initialPid, String packageName,
4907            String message) {
4908        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4909                != PackageManager.PERMISSION_GRANTED) {
4910            String msg = "Permission Denial: crashApplication() from pid="
4911                    + Binder.getCallingPid()
4912                    + ", uid=" + Binder.getCallingUid()
4913                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4914            Slog.w(TAG, msg);
4915            throw new SecurityException(msg);
4916        }
4917
4918        synchronized(this) {
4919            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4920        }
4921    }
4922
4923    @Override
4924    public final void finishSubActivity(IBinder token, String resultWho,
4925            int requestCode) {
4926        synchronized(this) {
4927            final long origId = Binder.clearCallingIdentity();
4928            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929            if (r != null) {
4930                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4931            }
4932            Binder.restoreCallingIdentity(origId);
4933        }
4934    }
4935
4936    @Override
4937    public boolean finishActivityAffinity(IBinder token) {
4938        synchronized(this) {
4939            final long origId = Binder.clearCallingIdentity();
4940            try {
4941                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4942                if (r == null) {
4943                    return false;
4944                }
4945
4946                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4947                // can finish.
4948                final TaskRecord task = r.task;
4949                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4950                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4951                    mStackSupervisor.showLockTaskToast();
4952                    return false;
4953                }
4954                return task.stack.finishActivityAffinityLocked(r);
4955            } finally {
4956                Binder.restoreCallingIdentity(origId);
4957            }
4958        }
4959    }
4960
4961    @Override
4962    public void finishVoiceTask(IVoiceInteractionSession session) {
4963        synchronized (this) {
4964            final long origId = Binder.clearCallingIdentity();
4965            try {
4966                // TODO: VI Consider treating local voice interactions and voice tasks
4967                // differently here
4968                mStackSupervisor.finishVoiceTask(session);
4969            } finally {
4970                Binder.restoreCallingIdentity(origId);
4971            }
4972        }
4973
4974    }
4975
4976    @Override
4977    public boolean releaseActivityInstance(IBinder token) {
4978        synchronized(this) {
4979            final long origId = Binder.clearCallingIdentity();
4980            try {
4981                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4982                if (r == null) {
4983                    return false;
4984                }
4985                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4986            } finally {
4987                Binder.restoreCallingIdentity(origId);
4988            }
4989        }
4990    }
4991
4992    @Override
4993    public void releaseSomeActivities(IApplicationThread appInt) {
4994        synchronized(this) {
4995            final long origId = Binder.clearCallingIdentity();
4996            try {
4997                ProcessRecord app = getRecordForAppLocked(appInt);
4998                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4999            } finally {
5000                Binder.restoreCallingIdentity(origId);
5001            }
5002        }
5003    }
5004
5005    @Override
5006    public boolean willActivityBeVisible(IBinder token) {
5007        synchronized(this) {
5008            ActivityStack stack = ActivityRecord.getStackLocked(token);
5009            if (stack != null) {
5010                return stack.willActivityBeVisibleLocked(token);
5011            }
5012            return false;
5013        }
5014    }
5015
5016    @Override
5017    public void overridePendingTransition(IBinder token, String packageName,
5018            int enterAnim, int exitAnim) {
5019        synchronized(this) {
5020            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5021            if (self == null) {
5022                return;
5023            }
5024
5025            final long origId = Binder.clearCallingIdentity();
5026
5027            if (self.state == ActivityState.RESUMED
5028                    || self.state == ActivityState.PAUSING) {
5029                mWindowManager.overridePendingAppTransition(packageName,
5030                        enterAnim, exitAnim, null);
5031            }
5032
5033            Binder.restoreCallingIdentity(origId);
5034        }
5035    }
5036
5037    /**
5038     * Main function for removing an existing process from the activity manager
5039     * as a result of that process going away.  Clears out all connections
5040     * to the process.
5041     */
5042    private final void handleAppDiedLocked(ProcessRecord app,
5043            boolean restarting, boolean allowRestart) {
5044        int pid = app.pid;
5045        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5046        if (!kept && !restarting) {
5047            removeLruProcessLocked(app);
5048            if (pid > 0) {
5049                ProcessList.remove(pid);
5050            }
5051        }
5052
5053        if (mProfileProc == app) {
5054            clearProfilerLocked();
5055        }
5056
5057        // Remove this application's activities from active lists.
5058        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5059
5060        app.activities.clear();
5061
5062        if (app.instrumentationClass != null) {
5063            Slog.w(TAG, "Crash of app " + app.processName
5064                  + " running instrumentation " + app.instrumentationClass);
5065            Bundle info = new Bundle();
5066            info.putString("shortMsg", "Process crashed.");
5067            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5068        }
5069
5070        if (!restarting && hasVisibleActivities
5071                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5072            // If there was nothing to resume, and we are not already restarting this process, but
5073            // there is a visible activity that is hosted by the process...  then make sure all
5074            // visible activities are running, taking care of restarting this process.
5075            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5076        }
5077    }
5078
5079    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5080        IBinder threadBinder = thread.asBinder();
5081        // Find the application record.
5082        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5083            ProcessRecord rec = mLruProcesses.get(i);
5084            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5085                return i;
5086            }
5087        }
5088        return -1;
5089    }
5090
5091    final ProcessRecord getRecordForAppLocked(
5092            IApplicationThread thread) {
5093        if (thread == null) {
5094            return null;
5095        }
5096
5097        int appIndex = getLRURecordIndexForAppLocked(thread);
5098        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5099    }
5100
5101    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5102        // If there are no longer any background processes running,
5103        // and the app that died was not running instrumentation,
5104        // then tell everyone we are now low on memory.
5105        boolean haveBg = false;
5106        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5107            ProcessRecord rec = mLruProcesses.get(i);
5108            if (rec.thread != null
5109                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5110                haveBg = true;
5111                break;
5112            }
5113        }
5114
5115        if (!haveBg) {
5116            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5117            if (doReport) {
5118                long now = SystemClock.uptimeMillis();
5119                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5120                    doReport = false;
5121                } else {
5122                    mLastMemUsageReportTime = now;
5123                }
5124            }
5125            final ArrayList<ProcessMemInfo> memInfos
5126                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5127            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5128            long now = SystemClock.uptimeMillis();
5129            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5130                ProcessRecord rec = mLruProcesses.get(i);
5131                if (rec == dyingProc || rec.thread == null) {
5132                    continue;
5133                }
5134                if (doReport) {
5135                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5136                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5137                }
5138                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5139                    // The low memory report is overriding any current
5140                    // state for a GC request.  Make sure to do
5141                    // heavy/important/visible/foreground processes first.
5142                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5143                        rec.lastRequestedGc = 0;
5144                    } else {
5145                        rec.lastRequestedGc = rec.lastLowMemory;
5146                    }
5147                    rec.reportLowMemory = true;
5148                    rec.lastLowMemory = now;
5149                    mProcessesToGc.remove(rec);
5150                    addProcessToGcListLocked(rec);
5151                }
5152            }
5153            if (doReport) {
5154                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5155                mHandler.sendMessage(msg);
5156            }
5157            scheduleAppGcsLocked();
5158        }
5159    }
5160
5161    final void appDiedLocked(ProcessRecord app) {
5162       appDiedLocked(app, app.pid, app.thread, false);
5163    }
5164
5165    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5166            boolean fromBinderDied) {
5167        // First check if this ProcessRecord is actually active for the pid.
5168        synchronized (mPidsSelfLocked) {
5169            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5170            if (curProc != app) {
5171                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5172                return;
5173            }
5174        }
5175
5176        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5177        synchronized (stats) {
5178            stats.noteProcessDiedLocked(app.info.uid, pid);
5179        }
5180
5181        if (!app.killed) {
5182            if (!fromBinderDied) {
5183                Process.killProcessQuiet(pid);
5184            }
5185            killProcessGroup(app.uid, pid);
5186            app.killed = true;
5187        }
5188
5189        // Clean up already done if the process has been re-started.
5190        if (app.pid == pid && app.thread != null &&
5191                app.thread.asBinder() == thread.asBinder()) {
5192            boolean doLowMem = app.instrumentationClass == null;
5193            boolean doOomAdj = doLowMem;
5194            if (!app.killedByAm) {
5195                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5196                        + ") has died");
5197                mAllowLowerMemLevel = true;
5198            } else {
5199                // Note that we always want to do oom adj to update our state with the
5200                // new number of procs.
5201                mAllowLowerMemLevel = false;
5202                doLowMem = false;
5203            }
5204            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5205            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5206                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5207            handleAppDiedLocked(app, false, true);
5208
5209            if (doOomAdj) {
5210                updateOomAdjLocked();
5211            }
5212            if (doLowMem) {
5213                doLowMemReportIfNeededLocked(app);
5214            }
5215        } else if (app.pid != pid) {
5216            // A new process has already been started.
5217            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5218                    + ") has died and restarted (pid " + app.pid + ").");
5219            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5220        } else if (DEBUG_PROCESSES) {
5221            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5222                    + thread.asBinder());
5223        }
5224    }
5225
5226    /**
5227     * If a stack trace dump file is configured, dump process stack traces.
5228     * @param clearTraces causes the dump file to be erased prior to the new
5229     *    traces being written, if true; when false, the new traces will be
5230     *    appended to any existing file content.
5231     * @param firstPids of dalvik VM processes to dump stack traces for first
5232     * @param lastPids of dalvik VM processes to dump stack traces for last
5233     * @param nativeProcs optional list of native process names to dump stack crawls
5234     * @return file containing stack traces, or null if no dump file is configured
5235     */
5236    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5237            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5238        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5239        if (tracesPath == null || tracesPath.length() == 0) {
5240            return null;
5241        }
5242
5243        File tracesFile = new File(tracesPath);
5244        try {
5245            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5246            tracesFile.createNewFile();
5247            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5248        } catch (IOException e) {
5249            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5250            return null;
5251        }
5252
5253        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5254        return tracesFile;
5255    }
5256
5257    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5258            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5259        // Use a FileObserver to detect when traces finish writing.
5260        // The order of traces is considered important to maintain for legibility.
5261        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5262            @Override
5263            public synchronized void onEvent(int event, String path) { notify(); }
5264        };
5265
5266        try {
5267            observer.startWatching();
5268
5269            // First collect all of the stacks of the most important pids.
5270            if (firstPids != null) {
5271                try {
5272                    int num = firstPids.size();
5273                    for (int i = 0; i < num; i++) {
5274                        synchronized (observer) {
5275                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5276                                    + firstPids.get(i));
5277                            final long sime = SystemClock.elapsedRealtime();
5278                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5279                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5280                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5281                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5282                        }
5283                    }
5284                } catch (InterruptedException e) {
5285                    Slog.wtf(TAG, e);
5286                }
5287            }
5288
5289            // Next collect the stacks of the native pids
5290            if (nativeProcs != null) {
5291                int[] pids = Process.getPidsForCommands(nativeProcs);
5292                if (pids != null) {
5293                    for (int pid : pids) {
5294                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5295                        final long sime = SystemClock.elapsedRealtime();
5296                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5297                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5298                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5299                    }
5300                }
5301            }
5302
5303            // Lastly, measure CPU usage.
5304            if (processCpuTracker != null) {
5305                processCpuTracker.init();
5306                System.gc();
5307                processCpuTracker.update();
5308                try {
5309                    synchronized (processCpuTracker) {
5310                        processCpuTracker.wait(500); // measure over 1/2 second.
5311                    }
5312                } catch (InterruptedException e) {
5313                }
5314                processCpuTracker.update();
5315
5316                // We'll take the stack crawls of just the top apps using CPU.
5317                final int N = processCpuTracker.countWorkingStats();
5318                int numProcs = 0;
5319                for (int i=0; i<N && numProcs<5; i++) {
5320                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5321                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5322                        numProcs++;
5323                        try {
5324                            synchronized (observer) {
5325                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5326                                        + stats.pid);
5327                                final long stime = SystemClock.elapsedRealtime();
5328                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5329                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5330                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5331                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5332                            }
5333                        } catch (InterruptedException e) {
5334                            Slog.wtf(TAG, e);
5335                        }
5336                    } else if (DEBUG_ANR) {
5337                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5338                                + stats.pid);
5339                    }
5340                }
5341            }
5342        } finally {
5343            observer.stopWatching();
5344        }
5345    }
5346
5347    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5348        if (true || IS_USER_BUILD) {
5349            return;
5350        }
5351        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5352        if (tracesPath == null || tracesPath.length() == 0) {
5353            return;
5354        }
5355
5356        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5357        StrictMode.allowThreadDiskWrites();
5358        try {
5359            final File tracesFile = new File(tracesPath);
5360            final File tracesDir = tracesFile.getParentFile();
5361            final File tracesTmp = new File(tracesDir, "__tmp__");
5362            try {
5363                if (tracesFile.exists()) {
5364                    tracesTmp.delete();
5365                    tracesFile.renameTo(tracesTmp);
5366                }
5367                StringBuilder sb = new StringBuilder();
5368                Time tobj = new Time();
5369                tobj.set(System.currentTimeMillis());
5370                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5371                sb.append(": ");
5372                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5373                sb.append(" since ");
5374                sb.append(msg);
5375                FileOutputStream fos = new FileOutputStream(tracesFile);
5376                fos.write(sb.toString().getBytes());
5377                if (app == null) {
5378                    fos.write("\n*** No application process!".getBytes());
5379                }
5380                fos.close();
5381                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5382            } catch (IOException e) {
5383                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5384                return;
5385            }
5386
5387            if (app != null) {
5388                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5389                firstPids.add(app.pid);
5390                dumpStackTraces(tracesPath, firstPids, null, null, null);
5391            }
5392
5393            File lastTracesFile = null;
5394            File curTracesFile = null;
5395            for (int i=9; i>=0; i--) {
5396                String name = String.format(Locale.US, "slow%02d.txt", i);
5397                curTracesFile = new File(tracesDir, name);
5398                if (curTracesFile.exists()) {
5399                    if (lastTracesFile != null) {
5400                        curTracesFile.renameTo(lastTracesFile);
5401                    } else {
5402                        curTracesFile.delete();
5403                    }
5404                }
5405                lastTracesFile = curTracesFile;
5406            }
5407            tracesFile.renameTo(curTracesFile);
5408            if (tracesTmp.exists()) {
5409                tracesTmp.renameTo(tracesFile);
5410            }
5411        } finally {
5412            StrictMode.setThreadPolicy(oldPolicy);
5413        }
5414    }
5415
5416    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5417        if (!mLaunchWarningShown) {
5418            mLaunchWarningShown = true;
5419            mUiHandler.post(new Runnable() {
5420                @Override
5421                public void run() {
5422                    synchronized (ActivityManagerService.this) {
5423                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5424                        d.show();
5425                        mUiHandler.postDelayed(new Runnable() {
5426                            @Override
5427                            public void run() {
5428                                synchronized (ActivityManagerService.this) {
5429                                    d.dismiss();
5430                                    mLaunchWarningShown = false;
5431                                }
5432                            }
5433                        }, 4000);
5434                    }
5435                }
5436            });
5437        }
5438    }
5439
5440    @Override
5441    public boolean clearApplicationUserData(final String packageName,
5442            final IPackageDataObserver observer, int userId) {
5443        enforceNotIsolatedCaller("clearApplicationUserData");
5444        int uid = Binder.getCallingUid();
5445        int pid = Binder.getCallingPid();
5446        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5447                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5448
5449
5450        long callingId = Binder.clearCallingIdentity();
5451        try {
5452            IPackageManager pm = AppGlobals.getPackageManager();
5453            int pkgUid = -1;
5454            synchronized(this) {
5455                if (getPackageManagerInternalLocked().isPackageDataProtected(
5456                        userId, packageName)) {
5457                    throw new SecurityException(
5458                            "Cannot clear data for a protected package: " + packageName);
5459                }
5460
5461                try {
5462                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5463                } catch (RemoteException e) {
5464                }
5465                if (pkgUid == -1) {
5466                    Slog.w(TAG, "Invalid packageName: " + packageName);
5467                    if (observer != null) {
5468                        try {
5469                            observer.onRemoveCompleted(packageName, false);
5470                        } catch (RemoteException e) {
5471                            Slog.i(TAG, "Observer no longer exists.");
5472                        }
5473                    }
5474                    return false;
5475                }
5476                if (uid == pkgUid || checkComponentPermission(
5477                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5478                        pid, uid, -1, true)
5479                        == PackageManager.PERMISSION_GRANTED) {
5480                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5481                } else {
5482                    throw new SecurityException("PID " + pid + " does not have permission "
5483                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5484                                    + " of package " + packageName);
5485                }
5486
5487                // Remove all tasks match the cleared application package and user
5488                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5489                    final TaskRecord tr = mRecentTasks.get(i);
5490                    final String taskPackageName =
5491                            tr.getBaseIntent().getComponent().getPackageName();
5492                    if (tr.userId != userId) continue;
5493                    if (!taskPackageName.equals(packageName)) continue;
5494                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5495                }
5496            }
5497
5498            final int pkgUidF = pkgUid;
5499            final int userIdF = userId;
5500            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5501                @Override
5502                public void onRemoveCompleted(String packageName, boolean succeeded)
5503                        throws RemoteException {
5504                    synchronized (ActivityManagerService.this) {
5505                        finishForceStopPackageLocked(packageName, pkgUidF);
5506                    }
5507
5508                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5509                            Uri.fromParts("package", packageName, null));
5510                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5511                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5512                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5513                            null, null, 0, null, null, null, null, false, false, userIdF);
5514
5515                    if (observer != null) {
5516                        observer.onRemoveCompleted(packageName, succeeded);
5517                    }
5518                }
5519            };
5520
5521            try {
5522                // Clear application user data
5523                pm.clearApplicationUserData(packageName, localObserver, userId);
5524
5525                synchronized(this) {
5526                    // Remove all permissions granted from/to this package
5527                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5528                }
5529
5530                // Remove all zen rules created by this package; revoke it's zen access.
5531                INotificationManager inm = NotificationManager.getService();
5532                inm.removeAutomaticZenRules(packageName);
5533                inm.setNotificationPolicyAccessGranted(packageName, false);
5534
5535            } catch (RemoteException e) {
5536            }
5537        } finally {
5538            Binder.restoreCallingIdentity(callingId);
5539        }
5540        return true;
5541    }
5542
5543    @Override
5544    public void killBackgroundProcesses(final String packageName, int userId) {
5545        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5546                != PackageManager.PERMISSION_GRANTED &&
5547                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5548                        != PackageManager.PERMISSION_GRANTED) {
5549            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5550                    + Binder.getCallingPid()
5551                    + ", uid=" + Binder.getCallingUid()
5552                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5553            Slog.w(TAG, msg);
5554            throw new SecurityException(msg);
5555        }
5556
5557        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5558                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5559        long callingId = Binder.clearCallingIdentity();
5560        try {
5561            IPackageManager pm = AppGlobals.getPackageManager();
5562            synchronized(this) {
5563                int appId = -1;
5564                try {
5565                    appId = UserHandle.getAppId(
5566                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5567                } catch (RemoteException e) {
5568                }
5569                if (appId == -1) {
5570                    Slog.w(TAG, "Invalid packageName: " + packageName);
5571                    return;
5572                }
5573                killPackageProcessesLocked(packageName, appId, userId,
5574                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5575            }
5576        } finally {
5577            Binder.restoreCallingIdentity(callingId);
5578        }
5579    }
5580
5581    @Override
5582    public void killAllBackgroundProcesses() {
5583        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5584                != PackageManager.PERMISSION_GRANTED) {
5585            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5586                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5587                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5588            Slog.w(TAG, msg);
5589            throw new SecurityException(msg);
5590        }
5591
5592        final long callingId = Binder.clearCallingIdentity();
5593        try {
5594            synchronized (this) {
5595                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5596                final int NP = mProcessNames.getMap().size();
5597                for (int ip = 0; ip < NP; ip++) {
5598                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5599                    final int NA = apps.size();
5600                    for (int ia = 0; ia < NA; ia++) {
5601                        final ProcessRecord app = apps.valueAt(ia);
5602                        if (app.persistent) {
5603                            // We don't kill persistent processes.
5604                            continue;
5605                        }
5606                        if (app.removed) {
5607                            procs.add(app);
5608                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5609                            app.removed = true;
5610                            procs.add(app);
5611                        }
5612                    }
5613                }
5614
5615                final int N = procs.size();
5616                for (int i = 0; i < N; i++) {
5617                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5618                }
5619
5620                mAllowLowerMemLevel = true;
5621
5622                updateOomAdjLocked();
5623                doLowMemReportIfNeededLocked(null);
5624            }
5625        } finally {
5626            Binder.restoreCallingIdentity(callingId);
5627        }
5628    }
5629
5630    /**
5631     * Kills all background processes, except those matching any of the
5632     * specified properties.
5633     *
5634     * @param minTargetSdk the target SDK version at or above which to preserve
5635     *                     processes, or {@code -1} to ignore the target SDK
5636     * @param maxProcState the process state at or below which to preserve
5637     *                     processes, or {@code -1} to ignore the process state
5638     */
5639    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5640        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5641                != PackageManager.PERMISSION_GRANTED) {
5642            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5643                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5644                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5645            Slog.w(TAG, msg);
5646            throw new SecurityException(msg);
5647        }
5648
5649        final long callingId = Binder.clearCallingIdentity();
5650        try {
5651            synchronized (this) {
5652                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5653                final int NP = mProcessNames.getMap().size();
5654                for (int ip = 0; ip < NP; ip++) {
5655                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656                    final int NA = apps.size();
5657                    for (int ia = 0; ia < NA; ia++) {
5658                        final ProcessRecord app = apps.valueAt(ia);
5659                        if (app.removed) {
5660                            procs.add(app);
5661                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5662                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5663                            app.removed = true;
5664                            procs.add(app);
5665                        }
5666                    }
5667                }
5668
5669                final int N = procs.size();
5670                for (int i = 0; i < N; i++) {
5671                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5672                }
5673            }
5674        } finally {
5675            Binder.restoreCallingIdentity(callingId);
5676        }
5677    }
5678
5679    @Override
5680    public void forceStopPackage(final String packageName, int userId) {
5681        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5682                != PackageManager.PERMISSION_GRANTED) {
5683            String msg = "Permission Denial: forceStopPackage() from pid="
5684                    + Binder.getCallingPid()
5685                    + ", uid=" + Binder.getCallingUid()
5686                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5687            Slog.w(TAG, msg);
5688            throw new SecurityException(msg);
5689        }
5690        final int callingPid = Binder.getCallingPid();
5691        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5692                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5693        long callingId = Binder.clearCallingIdentity();
5694        try {
5695            IPackageManager pm = AppGlobals.getPackageManager();
5696            synchronized(this) {
5697                int[] users = userId == UserHandle.USER_ALL
5698                        ? mUserController.getUsers() : new int[] { userId };
5699                for (int user : users) {
5700                    int pkgUid = -1;
5701                    try {
5702                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5703                                user);
5704                    } catch (RemoteException e) {
5705                    }
5706                    if (pkgUid == -1) {
5707                        Slog.w(TAG, "Invalid packageName: " + packageName);
5708                        continue;
5709                    }
5710                    try {
5711                        pm.setPackageStoppedState(packageName, true, user);
5712                    } catch (RemoteException e) {
5713                    } catch (IllegalArgumentException e) {
5714                        Slog.w(TAG, "Failed trying to unstop package "
5715                                + packageName + ": " + e);
5716                    }
5717                    if (mUserController.isUserRunningLocked(user, 0)) {
5718                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5719                        finishForceStopPackageLocked(packageName, pkgUid);
5720                    }
5721                }
5722            }
5723        } finally {
5724            Binder.restoreCallingIdentity(callingId);
5725        }
5726    }
5727
5728    @Override
5729    public void addPackageDependency(String packageName) {
5730        synchronized (this) {
5731            int callingPid = Binder.getCallingPid();
5732            if (callingPid == Process.myPid()) {
5733                //  Yeah, um, no.
5734                return;
5735            }
5736            ProcessRecord proc;
5737            synchronized (mPidsSelfLocked) {
5738                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5739            }
5740            if (proc != null) {
5741                if (proc.pkgDeps == null) {
5742                    proc.pkgDeps = new ArraySet<String>(1);
5743                }
5744                proc.pkgDeps.add(packageName);
5745            }
5746        }
5747    }
5748
5749    /*
5750     * The pkg name and app id have to be specified.
5751     */
5752    @Override
5753    public void killApplication(String pkg, int appId, int userId, String reason) {
5754        if (pkg == null) {
5755            return;
5756        }
5757        // Make sure the uid is valid.
5758        if (appId < 0) {
5759            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5760            return;
5761        }
5762        int callerUid = Binder.getCallingUid();
5763        // Only the system server can kill an application
5764        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5765            // Post an aysnc message to kill the application
5766            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5767            msg.arg1 = appId;
5768            msg.arg2 = userId;
5769            Bundle bundle = new Bundle();
5770            bundle.putString("pkg", pkg);
5771            bundle.putString("reason", reason);
5772            msg.obj = bundle;
5773            mHandler.sendMessage(msg);
5774        } else {
5775            throw new SecurityException(callerUid + " cannot kill pkg: " +
5776                    pkg);
5777        }
5778    }
5779
5780    @Override
5781    public void closeSystemDialogs(String reason) {
5782        enforceNotIsolatedCaller("closeSystemDialogs");
5783
5784        final int pid = Binder.getCallingPid();
5785        final int uid = Binder.getCallingUid();
5786        final long origId = Binder.clearCallingIdentity();
5787        try {
5788            synchronized (this) {
5789                // Only allow this from foreground processes, so that background
5790                // applications can't abuse it to prevent system UI from being shown.
5791                if (uid >= Process.FIRST_APPLICATION_UID) {
5792                    ProcessRecord proc;
5793                    synchronized (mPidsSelfLocked) {
5794                        proc = mPidsSelfLocked.get(pid);
5795                    }
5796                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5797                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5798                                + " from background process " + proc);
5799                        return;
5800                    }
5801                }
5802                closeSystemDialogsLocked(reason);
5803            }
5804        } finally {
5805            Binder.restoreCallingIdentity(origId);
5806        }
5807    }
5808
5809    void closeSystemDialogsLocked(String reason) {
5810        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5811        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5812                | Intent.FLAG_RECEIVER_FOREGROUND);
5813        if (reason != null) {
5814            intent.putExtra("reason", reason);
5815        }
5816        mWindowManager.closeSystemDialogs(reason);
5817
5818        mStackSupervisor.closeSystemDialogsLocked();
5819
5820        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5821                AppOpsManager.OP_NONE, null, false, false,
5822                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5823    }
5824
5825    @Override
5826    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5827        enforceNotIsolatedCaller("getProcessMemoryInfo");
5828        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5829        for (int i=pids.length-1; i>=0; i--) {
5830            ProcessRecord proc;
5831            int oomAdj;
5832            synchronized (this) {
5833                synchronized (mPidsSelfLocked) {
5834                    proc = mPidsSelfLocked.get(pids[i]);
5835                    oomAdj = proc != null ? proc.setAdj : 0;
5836                }
5837            }
5838            infos[i] = new Debug.MemoryInfo();
5839            Debug.getMemoryInfo(pids[i], infos[i]);
5840            if (proc != null) {
5841                synchronized (this) {
5842                    if (proc.thread != null && proc.setAdj == oomAdj) {
5843                        // Record this for posterity if the process has been stable.
5844                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5845                                infos[i].getTotalUss(), false, proc.pkgList);
5846                    }
5847                }
5848            }
5849        }
5850        return infos;
5851    }
5852
5853    @Override
5854    public long[] getProcessPss(int[] pids) {
5855        enforceNotIsolatedCaller("getProcessPss");
5856        long[] pss = new long[pids.length];
5857        for (int i=pids.length-1; i>=0; i--) {
5858            ProcessRecord proc;
5859            int oomAdj;
5860            synchronized (this) {
5861                synchronized (mPidsSelfLocked) {
5862                    proc = mPidsSelfLocked.get(pids[i]);
5863                    oomAdj = proc != null ? proc.setAdj : 0;
5864                }
5865            }
5866            long[] tmpUss = new long[1];
5867            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5868            if (proc != null) {
5869                synchronized (this) {
5870                    if (proc.thread != null && proc.setAdj == oomAdj) {
5871                        // Record this for posterity if the process has been stable.
5872                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5873                    }
5874                }
5875            }
5876        }
5877        return pss;
5878    }
5879
5880    @Override
5881    public void killApplicationProcess(String processName, int uid) {
5882        if (processName == null) {
5883            return;
5884        }
5885
5886        int callerUid = Binder.getCallingUid();
5887        // Only the system server can kill an application
5888        if (callerUid == Process.SYSTEM_UID) {
5889            synchronized (this) {
5890                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5891                if (app != null && app.thread != null) {
5892                    try {
5893                        app.thread.scheduleSuicide();
5894                    } catch (RemoteException e) {
5895                        // If the other end already died, then our work here is done.
5896                    }
5897                } else {
5898                    Slog.w(TAG, "Process/uid not found attempting kill of "
5899                            + processName + " / " + uid);
5900                }
5901            }
5902        } else {
5903            throw new SecurityException(callerUid + " cannot kill app process: " +
5904                    processName);
5905        }
5906    }
5907
5908    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5909        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5910                false, true, false, false, UserHandle.getUserId(uid), reason);
5911    }
5912
5913    private void finishForceStopPackageLocked(final String packageName, int uid) {
5914        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5915                Uri.fromParts("package", packageName, null));
5916        if (!mProcessesReady) {
5917            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5918                    | Intent.FLAG_RECEIVER_FOREGROUND);
5919        }
5920        intent.putExtra(Intent.EXTRA_UID, uid);
5921        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5922        broadcastIntentLocked(null, null, intent,
5923                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5924                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5925    }
5926
5927
5928    private final boolean killPackageProcessesLocked(String packageName, int appId,
5929            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5930            boolean doit, boolean evenPersistent, String reason) {
5931        ArrayList<ProcessRecord> procs = new ArrayList<>();
5932
5933        // Remove all processes this package may have touched: all with the
5934        // same UID (except for the system or root user), and all whose name
5935        // matches the package name.
5936        final int NP = mProcessNames.getMap().size();
5937        for (int ip=0; ip<NP; ip++) {
5938            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5939            final int NA = apps.size();
5940            for (int ia=0; ia<NA; ia++) {
5941                ProcessRecord app = apps.valueAt(ia);
5942                if (app.persistent && !evenPersistent) {
5943                    // we don't kill persistent processes
5944                    continue;
5945                }
5946                if (app.removed) {
5947                    if (doit) {
5948                        procs.add(app);
5949                    }
5950                    continue;
5951                }
5952
5953                // Skip process if it doesn't meet our oom adj requirement.
5954                if (app.setAdj < minOomAdj) {
5955                    continue;
5956                }
5957
5958                // If no package is specified, we call all processes under the
5959                // give user id.
5960                if (packageName == null) {
5961                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5962                        continue;
5963                    }
5964                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5965                        continue;
5966                    }
5967                // Package has been specified, we want to hit all processes
5968                // that match it.  We need to qualify this by the processes
5969                // that are running under the specified app and user ID.
5970                } else {
5971                    final boolean isDep = app.pkgDeps != null
5972                            && app.pkgDeps.contains(packageName);
5973                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5974                        continue;
5975                    }
5976                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5977                        continue;
5978                    }
5979                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5980                        continue;
5981                    }
5982                }
5983
5984                // Process has passed all conditions, kill it!
5985                if (!doit) {
5986                    return true;
5987                }
5988                app.removed = true;
5989                procs.add(app);
5990            }
5991        }
5992
5993        int N = procs.size();
5994        for (int i=0; i<N; i++) {
5995            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5996        }
5997        updateOomAdjLocked();
5998        return N > 0;
5999    }
6000
6001    private void cleanupDisabledPackageComponentsLocked(
6002            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6003
6004        Set<String> disabledClasses = null;
6005        boolean packageDisabled = false;
6006        IPackageManager pm = AppGlobals.getPackageManager();
6007
6008        if (changedClasses == null) {
6009            // Nothing changed...
6010            return;
6011        }
6012
6013        // Determine enable/disable state of the package and its components.
6014        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6015        for (int i = changedClasses.length - 1; i >= 0; i--) {
6016            final String changedClass = changedClasses[i];
6017
6018            if (changedClass.equals(packageName)) {
6019                try {
6020                    // Entire package setting changed
6021                    enabled = pm.getApplicationEnabledSetting(packageName,
6022                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6023                } catch (Exception e) {
6024                    // No such package/component; probably racing with uninstall.  In any
6025                    // event it means we have nothing further to do here.
6026                    return;
6027                }
6028                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6029                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6030                if (packageDisabled) {
6031                    // Entire package is disabled.
6032                    // No need to continue to check component states.
6033                    disabledClasses = null;
6034                    break;
6035                }
6036            } else {
6037                try {
6038                    enabled = pm.getComponentEnabledSetting(
6039                            new ComponentName(packageName, changedClass),
6040                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6041                } catch (Exception e) {
6042                    // As above, probably racing with uninstall.
6043                    return;
6044                }
6045                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6046                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6047                    if (disabledClasses == null) {
6048                        disabledClasses = new ArraySet<>(changedClasses.length);
6049                    }
6050                    disabledClasses.add(changedClass);
6051                }
6052            }
6053        }
6054
6055        if (!packageDisabled && disabledClasses == null) {
6056            // Nothing to do here...
6057            return;
6058        }
6059
6060        // Clean-up disabled activities.
6061        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6062                packageName, disabledClasses, true, false, userId) && mBooted) {
6063            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6064            mStackSupervisor.scheduleIdleLocked();
6065        }
6066
6067        // Clean-up disabled tasks
6068        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6069
6070        // Clean-up disabled services.
6071        mServices.bringDownDisabledPackageServicesLocked(
6072                packageName, disabledClasses, userId, false, killProcess, true);
6073
6074        // Clean-up disabled providers.
6075        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6076        mProviderMap.collectPackageProvidersLocked(
6077                packageName, disabledClasses, true, false, userId, providers);
6078        for (int i = providers.size() - 1; i >= 0; i--) {
6079            removeDyingProviderLocked(null, providers.get(i), true);
6080        }
6081
6082        // Clean-up disabled broadcast receivers.
6083        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6084            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6085                    packageName, disabledClasses, userId, true);
6086        }
6087
6088    }
6089
6090    final boolean clearBroadcastQueueForUserLocked(int userId) {
6091        boolean didSomething = false;
6092        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6093            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6094                    null, null, userId, true);
6095        }
6096        return didSomething;
6097    }
6098
6099    final boolean forceStopPackageLocked(String packageName, int appId,
6100            boolean callerWillRestart, boolean purgeCache, boolean doit,
6101            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6102        int i;
6103
6104        if (userId == UserHandle.USER_ALL && packageName == null) {
6105            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6106        }
6107
6108        if (appId < 0 && packageName != null) {
6109            try {
6110                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6111                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6112            } catch (RemoteException e) {
6113            }
6114        }
6115
6116        if (doit) {
6117            if (packageName != null) {
6118                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6119                        + " user=" + userId + ": " + reason);
6120            } else {
6121                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6122            }
6123
6124            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6125        }
6126
6127        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6128                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6129                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6130
6131        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6132                packageName, null, doit, evenPersistent, userId)) {
6133            if (!doit) {
6134                return true;
6135            }
6136            didSomething = true;
6137        }
6138
6139        if (mServices.bringDownDisabledPackageServicesLocked(
6140                packageName, null, userId, evenPersistent, true, doit)) {
6141            if (!doit) {
6142                return true;
6143            }
6144            didSomething = true;
6145        }
6146
6147        if (packageName == null) {
6148            // Remove all sticky broadcasts from this user.
6149            mStickyBroadcasts.remove(userId);
6150        }
6151
6152        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6153        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6154                userId, providers)) {
6155            if (!doit) {
6156                return true;
6157            }
6158            didSomething = true;
6159        }
6160        for (i = providers.size() - 1; i >= 0; i--) {
6161            removeDyingProviderLocked(null, providers.get(i), true);
6162        }
6163
6164        // Remove transient permissions granted from/to this package/user
6165        removeUriPermissionsForPackageLocked(packageName, userId, false);
6166
6167        if (doit) {
6168            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6169                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6170                        packageName, null, userId, doit);
6171            }
6172        }
6173
6174        if (packageName == null || uninstalling) {
6175            // Remove pending intents.  For now we only do this when force
6176            // stopping users, because we have some problems when doing this
6177            // for packages -- app widgets are not currently cleaned up for
6178            // such packages, so they can be left with bad pending intents.
6179            if (mIntentSenderRecords.size() > 0) {
6180                Iterator<WeakReference<PendingIntentRecord>> it
6181                        = mIntentSenderRecords.values().iterator();
6182                while (it.hasNext()) {
6183                    WeakReference<PendingIntentRecord> wpir = it.next();
6184                    if (wpir == null) {
6185                        it.remove();
6186                        continue;
6187                    }
6188                    PendingIntentRecord pir = wpir.get();
6189                    if (pir == null) {
6190                        it.remove();
6191                        continue;
6192                    }
6193                    if (packageName == null) {
6194                        // Stopping user, remove all objects for the user.
6195                        if (pir.key.userId != userId) {
6196                            // Not the same user, skip it.
6197                            continue;
6198                        }
6199                    } else {
6200                        if (UserHandle.getAppId(pir.uid) != appId) {
6201                            // Different app id, skip it.
6202                            continue;
6203                        }
6204                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6205                            // Different user, skip it.
6206                            continue;
6207                        }
6208                        if (!pir.key.packageName.equals(packageName)) {
6209                            // Different package, skip it.
6210                            continue;
6211                        }
6212                    }
6213                    if (!doit) {
6214                        return true;
6215                    }
6216                    didSomething = true;
6217                    it.remove();
6218                    pir.canceled = true;
6219                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6220                        pir.key.activity.pendingResults.remove(pir.ref);
6221                    }
6222                }
6223            }
6224        }
6225
6226        if (doit) {
6227            if (purgeCache && packageName != null) {
6228                AttributeCache ac = AttributeCache.instance();
6229                if (ac != null) {
6230                    ac.removePackage(packageName);
6231                }
6232            }
6233            if (mBooted) {
6234                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6235                mStackSupervisor.scheduleIdleLocked();
6236            }
6237        }
6238
6239        return didSomething;
6240    }
6241
6242    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6243        ProcessRecord old = mProcessNames.remove(name, uid);
6244        if (old != null) {
6245            old.uidRecord.numProcs--;
6246            if (old.uidRecord.numProcs == 0) {
6247                // No more processes using this uid, tell clients it is gone.
6248                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6249                        "No more processes in " + old.uidRecord);
6250                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6251                mActiveUids.remove(uid);
6252                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6253            }
6254            old.uidRecord = null;
6255        }
6256        mIsolatedProcesses.remove(uid);
6257        return old;
6258    }
6259
6260    private final void addProcessNameLocked(ProcessRecord proc) {
6261        // We shouldn't already have a process under this name, but just in case we
6262        // need to clean up whatever may be there now.
6263        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6264        if (old == proc && proc.persistent) {
6265            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6266            Slog.w(TAG, "Re-adding persistent process " + proc);
6267        } else if (old != null) {
6268            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6269        }
6270        UidRecord uidRec = mActiveUids.get(proc.uid);
6271        if (uidRec == null) {
6272            uidRec = new UidRecord(proc.uid);
6273            // This is the first appearance of the uid, report it now!
6274            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6275                    "Creating new process uid: " + uidRec);
6276            mActiveUids.put(proc.uid, uidRec);
6277            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6278            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6279        }
6280        proc.uidRecord = uidRec;
6281
6282        // Reset render thread tid if it was already set, so new process can set it again.
6283        proc.renderThreadTid = 0;
6284        uidRec.numProcs++;
6285        mProcessNames.put(proc.processName, proc.uid, proc);
6286        if (proc.isolated) {
6287            mIsolatedProcesses.put(proc.uid, proc);
6288        }
6289    }
6290
6291    boolean removeProcessLocked(ProcessRecord app,
6292            boolean callerWillRestart, boolean allowRestart, String reason) {
6293        final String name = app.processName;
6294        final int uid = app.uid;
6295        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6296            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6297
6298        ProcessRecord old = mProcessNames.get(name, uid);
6299        if (old != app) {
6300            // This process is no longer active, so nothing to do.
6301            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6302            return false;
6303        }
6304        removeProcessNameLocked(name, uid);
6305        if (mHeavyWeightProcess == app) {
6306            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6307                    mHeavyWeightProcess.userId, 0));
6308            mHeavyWeightProcess = null;
6309        }
6310        boolean needRestart = false;
6311        if (app.pid > 0 && app.pid != MY_PID) {
6312            int pid = app.pid;
6313            synchronized (mPidsSelfLocked) {
6314                mPidsSelfLocked.remove(pid);
6315                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6316            }
6317            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6318            if (app.isolated) {
6319                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6320            }
6321            boolean willRestart = false;
6322            if (app.persistent && !app.isolated) {
6323                if (!callerWillRestart) {
6324                    willRestart = true;
6325                } else {
6326                    needRestart = true;
6327                }
6328            }
6329            app.kill(reason, true);
6330            handleAppDiedLocked(app, willRestart, allowRestart);
6331            if (willRestart) {
6332                removeLruProcessLocked(app);
6333                addAppLocked(app.info, false, null /* ABI override */);
6334            }
6335        } else {
6336            mRemovedProcesses.add(app);
6337        }
6338
6339        return needRestart;
6340    }
6341
6342    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6343        cleanupAppInLaunchingProvidersLocked(app, true);
6344        removeProcessLocked(app, false, true, "timeout publishing content providers");
6345    }
6346
6347    private final void processStartTimedOutLocked(ProcessRecord app) {
6348        final int pid = app.pid;
6349        boolean gone = false;
6350        synchronized (mPidsSelfLocked) {
6351            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6352            if (knownApp != null && knownApp.thread == null) {
6353                mPidsSelfLocked.remove(pid);
6354                gone = true;
6355            }
6356        }
6357
6358        if (gone) {
6359            Slog.w(TAG, "Process " + app + " failed to attach");
6360            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6361                    pid, app.uid, app.processName);
6362            removeProcessNameLocked(app.processName, app.uid);
6363            if (mHeavyWeightProcess == app) {
6364                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6365                        mHeavyWeightProcess.userId, 0));
6366                mHeavyWeightProcess = null;
6367            }
6368            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6369            if (app.isolated) {
6370                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6371            }
6372            // Take care of any launching providers waiting for this process.
6373            cleanupAppInLaunchingProvidersLocked(app, true);
6374            // Take care of any services that are waiting for the process.
6375            mServices.processStartTimedOutLocked(app);
6376            app.kill("start timeout", true);
6377            removeLruProcessLocked(app);
6378            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6379                Slog.w(TAG, "Unattached app died before backup, skipping");
6380                try {
6381                    IBackupManager bm = IBackupManager.Stub.asInterface(
6382                            ServiceManager.getService(Context.BACKUP_SERVICE));
6383                    bm.agentDisconnected(app.info.packageName);
6384                } catch (RemoteException e) {
6385                    // Can't happen; the backup manager is local
6386                }
6387            }
6388            if (isPendingBroadcastProcessLocked(pid)) {
6389                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6390                skipPendingBroadcastLocked(pid);
6391            }
6392        } else {
6393            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6394        }
6395    }
6396
6397    private final boolean attachApplicationLocked(IApplicationThread thread,
6398            int pid) {
6399
6400        // Find the application record that is being attached...  either via
6401        // the pid if we are running in multiple processes, or just pull the
6402        // next app record if we are emulating process with anonymous threads.
6403        ProcessRecord app;
6404        if (pid != MY_PID && pid >= 0) {
6405            synchronized (mPidsSelfLocked) {
6406                app = mPidsSelfLocked.get(pid);
6407            }
6408        } else {
6409            app = null;
6410        }
6411
6412        if (app == null) {
6413            Slog.w(TAG, "No pending application record for pid " + pid
6414                    + " (IApplicationThread " + thread + "); dropping process");
6415            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6416            if (pid > 0 && pid != MY_PID) {
6417                Process.killProcessQuiet(pid);
6418                //TODO: killProcessGroup(app.info.uid, pid);
6419            } else {
6420                try {
6421                    thread.scheduleExit();
6422                } catch (Exception e) {
6423                    // Ignore exceptions.
6424                }
6425            }
6426            return false;
6427        }
6428
6429        // If this application record is still attached to a previous
6430        // process, clean it up now.
6431        if (app.thread != null) {
6432            handleAppDiedLocked(app, true, true);
6433        }
6434
6435        // Tell the process all about itself.
6436
6437        if (DEBUG_ALL) Slog.v(
6438                TAG, "Binding process pid " + pid + " to record " + app);
6439
6440        final String processName = app.processName;
6441        try {
6442            AppDeathRecipient adr = new AppDeathRecipient(
6443                    app, pid, thread);
6444            thread.asBinder().linkToDeath(adr, 0);
6445            app.deathRecipient = adr;
6446        } catch (RemoteException e) {
6447            app.resetPackageList(mProcessStats);
6448            startProcessLocked(app, "link fail", processName);
6449            return false;
6450        }
6451
6452        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6453
6454        app.makeActive(thread, mProcessStats);
6455        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6456        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6457        app.forcingToForeground = null;
6458        updateProcessForegroundLocked(app, false, false);
6459        app.hasShownUi = false;
6460        app.debugging = false;
6461        app.cached = false;
6462        app.killedByAm = false;
6463
6464        // We carefully use the same state that PackageManager uses for
6465        // filtering, since we use this flag to decide if we need to install
6466        // providers when user is unlocked later
6467        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6468
6469        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6470
6471        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6472        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6473
6474        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6475            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6476            msg.obj = app;
6477            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6478        }
6479
6480        if (!normalMode) {
6481            Slog.i(TAG, "Launching preboot mode app: " + app);
6482        }
6483
6484        if (DEBUG_ALL) Slog.v(
6485            TAG, "New app record " + app
6486            + " thread=" + thread.asBinder() + " pid=" + pid);
6487        try {
6488            int testMode = IApplicationThread.DEBUG_OFF;
6489            if (mDebugApp != null && mDebugApp.equals(processName)) {
6490                testMode = mWaitForDebugger
6491                    ? IApplicationThread.DEBUG_WAIT
6492                    : IApplicationThread.DEBUG_ON;
6493                app.debugging = true;
6494                if (mDebugTransient) {
6495                    mDebugApp = mOrigDebugApp;
6496                    mWaitForDebugger = mOrigWaitForDebugger;
6497                }
6498            }
6499            String profileFile = app.instrumentationProfileFile;
6500            ParcelFileDescriptor profileFd = null;
6501            int samplingInterval = 0;
6502            boolean profileAutoStop = false;
6503            if (mProfileApp != null && mProfileApp.equals(processName)) {
6504                mProfileProc = app;
6505                profileFile = mProfileFile;
6506                profileFd = mProfileFd;
6507                samplingInterval = mSamplingInterval;
6508                profileAutoStop = mAutoStopProfiler;
6509            }
6510            boolean enableTrackAllocation = false;
6511            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6512                enableTrackAllocation = true;
6513                mTrackAllocationApp = null;
6514            }
6515
6516            // If the app is being launched for restore or full backup, set it up specially
6517            boolean isRestrictedBackupMode = false;
6518            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6519                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6520                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6521                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6522                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6523            }
6524
6525            if (app.instrumentationClass != null) {
6526                notifyPackageUse(app.instrumentationClass.getPackageName(),
6527                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6528            }
6529            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6530                    + processName + " with config " + mConfiguration);
6531            ApplicationInfo appInfo = app.instrumentationInfo != null
6532                    ? app.instrumentationInfo : app.info;
6533            app.compat = compatibilityInfoForPackageLocked(appInfo);
6534            if (profileFd != null) {
6535                profileFd = profileFd.dup();
6536            }
6537            ProfilerInfo profilerInfo = profileFile == null ? null
6538                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6539            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6540                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6541                    app.instrumentationUiAutomationConnection, testMode,
6542                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6543                    isRestrictedBackupMode || !normalMode, app.persistent,
6544                    new Configuration(mConfiguration), app.compat,
6545                    getCommonServicesLocked(app.isolated),
6546                    mCoreSettingsObserver.getCoreSettingsLocked());
6547            updateLruProcessLocked(app, false, null);
6548            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6549        } catch (Exception e) {
6550            // todo: Yikes!  What should we do?  For now we will try to
6551            // start another process, but that could easily get us in
6552            // an infinite loop of restarting processes...
6553            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6554
6555            app.resetPackageList(mProcessStats);
6556            app.unlinkDeathRecipient();
6557            startProcessLocked(app, "bind fail", processName);
6558            return false;
6559        }
6560
6561        // Remove this record from the list of starting applications.
6562        mPersistentStartingProcesses.remove(app);
6563        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6564                "Attach application locked removing on hold: " + app);
6565        mProcessesOnHold.remove(app);
6566
6567        boolean badApp = false;
6568        boolean didSomething = false;
6569
6570        // See if the top visible activity is waiting to run in this process...
6571        if (normalMode) {
6572            try {
6573                if (mStackSupervisor.attachApplicationLocked(app)) {
6574                    didSomething = true;
6575                }
6576            } catch (Exception e) {
6577                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6578                badApp = true;
6579            }
6580        }
6581
6582        // Find any services that should be running in this process...
6583        if (!badApp) {
6584            try {
6585                didSomething |= mServices.attachApplicationLocked(app, processName);
6586            } catch (Exception e) {
6587                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6588                badApp = true;
6589            }
6590        }
6591
6592        // Check if a next-broadcast receiver is in this process...
6593        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6594            try {
6595                didSomething |= sendPendingBroadcastsLocked(app);
6596            } catch (Exception e) {
6597                // If the app died trying to launch the receiver we declare it 'bad'
6598                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6599                badApp = true;
6600            }
6601        }
6602
6603        // Check whether the next backup agent is in this process...
6604        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6605            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6606                    "New app is backup target, launching agent for " + app);
6607            notifyPackageUse(mBackupTarget.appInfo.packageName,
6608                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6609            try {
6610                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6611                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6612                        mBackupTarget.backupMode);
6613            } catch (Exception e) {
6614                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6615                badApp = true;
6616            }
6617        }
6618
6619        if (badApp) {
6620            app.kill("error during init", true);
6621            handleAppDiedLocked(app, false, true);
6622            return false;
6623        }
6624
6625        if (!didSomething) {
6626            updateOomAdjLocked();
6627        }
6628
6629        return true;
6630    }
6631
6632    @Override
6633    public final void attachApplication(IApplicationThread thread) {
6634        synchronized (this) {
6635            int callingPid = Binder.getCallingPid();
6636            final long origId = Binder.clearCallingIdentity();
6637            attachApplicationLocked(thread, callingPid);
6638            Binder.restoreCallingIdentity(origId);
6639        }
6640    }
6641
6642    @Override
6643    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6644        final long origId = Binder.clearCallingIdentity();
6645        synchronized (this) {
6646            ActivityStack stack = ActivityRecord.getStackLocked(token);
6647            if (stack != null) {
6648                ActivityRecord r =
6649                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6650                if (stopProfiling) {
6651                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6652                        try {
6653                            mProfileFd.close();
6654                        } catch (IOException e) {
6655                        }
6656                        clearProfilerLocked();
6657                    }
6658                }
6659            }
6660        }
6661        Binder.restoreCallingIdentity(origId);
6662    }
6663
6664    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6665        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6666                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6667    }
6668
6669    void enableScreenAfterBoot() {
6670        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6671                SystemClock.uptimeMillis());
6672        mWindowManager.enableScreenAfterBoot();
6673
6674        synchronized (this) {
6675            updateEventDispatchingLocked();
6676        }
6677    }
6678
6679    @Override
6680    public void showBootMessage(final CharSequence msg, final boolean always) {
6681        if (Binder.getCallingUid() != Process.myUid()) {
6682            throw new SecurityException();
6683        }
6684        mWindowManager.showBootMessage(msg, always);
6685    }
6686
6687    @Override
6688    public void keyguardWaitingForActivityDrawn() {
6689        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6690        final long token = Binder.clearCallingIdentity();
6691        try {
6692            synchronized (this) {
6693                if (DEBUG_LOCKSCREEN) logLockScreen("");
6694                mWindowManager.keyguardWaitingForActivityDrawn();
6695                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6696                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6697                    updateSleepIfNeededLocked();
6698                }
6699            }
6700        } finally {
6701            Binder.restoreCallingIdentity(token);
6702        }
6703    }
6704
6705    @Override
6706    public void keyguardGoingAway(int flags) {
6707        enforceNotIsolatedCaller("keyguardGoingAway");
6708        final long token = Binder.clearCallingIdentity();
6709        try {
6710            synchronized (this) {
6711                if (DEBUG_LOCKSCREEN) logLockScreen("");
6712                mWindowManager.keyguardGoingAway(flags);
6713                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6714                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6715                    updateSleepIfNeededLocked();
6716
6717                    // Some stack visibility might change (e.g. docked stack)
6718                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6719                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6720                }
6721            }
6722        } finally {
6723            Binder.restoreCallingIdentity(token);
6724        }
6725    }
6726
6727    final void finishBooting() {
6728        synchronized (this) {
6729            if (!mBootAnimationComplete) {
6730                mCallFinishBooting = true;
6731                return;
6732            }
6733            mCallFinishBooting = false;
6734        }
6735
6736        ArraySet<String> completedIsas = new ArraySet<String>();
6737        for (String abi : Build.SUPPORTED_ABIS) {
6738            Process.establishZygoteConnectionForAbi(abi);
6739            final String instructionSet = VMRuntime.getInstructionSet(abi);
6740            if (!completedIsas.contains(instructionSet)) {
6741                try {
6742                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6743                } catch (InstallerException e) {
6744                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6745                            e.getMessage() +")");
6746                }
6747                completedIsas.add(instructionSet);
6748            }
6749        }
6750
6751        IntentFilter pkgFilter = new IntentFilter();
6752        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6753        pkgFilter.addDataScheme("package");
6754        mContext.registerReceiver(new BroadcastReceiver() {
6755            @Override
6756            public void onReceive(Context context, Intent intent) {
6757                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6758                if (pkgs != null) {
6759                    for (String pkg : pkgs) {
6760                        synchronized (ActivityManagerService.this) {
6761                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6762                                    0, "query restart")) {
6763                                setResultCode(Activity.RESULT_OK);
6764                                return;
6765                            }
6766                        }
6767                    }
6768                }
6769            }
6770        }, pkgFilter);
6771
6772        IntentFilter dumpheapFilter = new IntentFilter();
6773        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6774        mContext.registerReceiver(new BroadcastReceiver() {
6775            @Override
6776            public void onReceive(Context context, Intent intent) {
6777                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6778                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6779                } else {
6780                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6781                }
6782            }
6783        }, dumpheapFilter);
6784
6785        // Let system services know.
6786        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6787
6788        synchronized (this) {
6789            // Ensure that any processes we had put on hold are now started
6790            // up.
6791            final int NP = mProcessesOnHold.size();
6792            if (NP > 0) {
6793                ArrayList<ProcessRecord> procs =
6794                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6795                for (int ip=0; ip<NP; ip++) {
6796                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6797                            + procs.get(ip));
6798                    startProcessLocked(procs.get(ip), "on-hold", null);
6799                }
6800            }
6801
6802            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6803                // Start looking for apps that are abusing wake locks.
6804                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6805                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6806                // Tell anyone interested that we are done booting!
6807                SystemProperties.set("sys.boot_completed", "1");
6808
6809                // And trigger dev.bootcomplete if we are not showing encryption progress
6810                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6811                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6812                    SystemProperties.set("dev.bootcomplete", "1");
6813                }
6814                mUserController.sendBootCompletedLocked(
6815                        new IIntentReceiver.Stub() {
6816                            @Override
6817                            public void performReceive(Intent intent, int resultCode,
6818                                    String data, Bundle extras, boolean ordered,
6819                                    boolean sticky, int sendingUser) {
6820                                synchronized (ActivityManagerService.this) {
6821                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6822                                            true, false);
6823                                }
6824                            }
6825                        });
6826                scheduleStartProfilesLocked();
6827            }
6828        }
6829    }
6830
6831    @Override
6832    public void bootAnimationComplete() {
6833        final boolean callFinishBooting;
6834        synchronized (this) {
6835            callFinishBooting = mCallFinishBooting;
6836            mBootAnimationComplete = true;
6837        }
6838        if (callFinishBooting) {
6839            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6840            finishBooting();
6841            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6842        }
6843    }
6844
6845    final void ensureBootCompleted() {
6846        boolean booting;
6847        boolean enableScreen;
6848        synchronized (this) {
6849            booting = mBooting;
6850            mBooting = false;
6851            enableScreen = !mBooted;
6852            mBooted = true;
6853        }
6854
6855        if (booting) {
6856            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6857            finishBooting();
6858            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6859        }
6860
6861        if (enableScreen) {
6862            enableScreenAfterBoot();
6863        }
6864    }
6865
6866    @Override
6867    public final void activityResumed(IBinder token) {
6868        final long origId = Binder.clearCallingIdentity();
6869        synchronized(this) {
6870            ActivityStack stack = ActivityRecord.getStackLocked(token);
6871            if (stack != null) {
6872                stack.activityResumedLocked(token);
6873            }
6874        }
6875        Binder.restoreCallingIdentity(origId);
6876    }
6877
6878    @Override
6879    public final void activityPaused(IBinder token) {
6880        final long origId = Binder.clearCallingIdentity();
6881        synchronized(this) {
6882            ActivityStack stack = ActivityRecord.getStackLocked(token);
6883            if (stack != null) {
6884                stack.activityPausedLocked(token, false);
6885            }
6886        }
6887        Binder.restoreCallingIdentity(origId);
6888    }
6889
6890    @Override
6891    public final void activityStopped(IBinder token, Bundle icicle,
6892            PersistableBundle persistentState, CharSequence description) {
6893        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6894
6895        // Refuse possible leaked file descriptors
6896        if (icicle != null && icicle.hasFileDescriptors()) {
6897            throw new IllegalArgumentException("File descriptors passed in Bundle");
6898        }
6899
6900        final long origId = Binder.clearCallingIdentity();
6901
6902        synchronized (this) {
6903            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6904            if (r != null) {
6905                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6906            }
6907        }
6908
6909        trimApplications();
6910
6911        Binder.restoreCallingIdentity(origId);
6912    }
6913
6914    @Override
6915    public final void activityDestroyed(IBinder token) {
6916        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6917        synchronized (this) {
6918            ActivityStack stack = ActivityRecord.getStackLocked(token);
6919            if (stack != null) {
6920                stack.activityDestroyedLocked(token, "activityDestroyed");
6921            }
6922        }
6923    }
6924
6925    @Override
6926    public final void activityRelaunched(IBinder token) {
6927        final long origId = Binder.clearCallingIdentity();
6928        synchronized (this) {
6929            mStackSupervisor.activityRelaunchedLocked(token);
6930        }
6931        Binder.restoreCallingIdentity(origId);
6932    }
6933
6934    @Override
6935    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6936            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6937        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6938                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6939        synchronized (this) {
6940            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6941            if (record == null) {
6942                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6943                        + "found for: " + token);
6944            }
6945            record.setSizeConfigurations(horizontalSizeConfiguration,
6946                    verticalSizeConfigurations, smallestSizeConfigurations);
6947        }
6948    }
6949
6950    @Override
6951    public final void backgroundResourcesReleased(IBinder token) {
6952        final long origId = Binder.clearCallingIdentity();
6953        try {
6954            synchronized (this) {
6955                ActivityStack stack = ActivityRecord.getStackLocked(token);
6956                if (stack != null) {
6957                    stack.backgroundResourcesReleased();
6958                }
6959            }
6960        } finally {
6961            Binder.restoreCallingIdentity(origId);
6962        }
6963    }
6964
6965    @Override
6966    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6967        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6968    }
6969
6970    @Override
6971    public final void notifyEnterAnimationComplete(IBinder token) {
6972        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6973    }
6974
6975    @Override
6976    public String getCallingPackage(IBinder token) {
6977        synchronized (this) {
6978            ActivityRecord r = getCallingRecordLocked(token);
6979            return r != null ? r.info.packageName : null;
6980        }
6981    }
6982
6983    @Override
6984    public ComponentName getCallingActivity(IBinder token) {
6985        synchronized (this) {
6986            ActivityRecord r = getCallingRecordLocked(token);
6987            return r != null ? r.intent.getComponent() : null;
6988        }
6989    }
6990
6991    private ActivityRecord getCallingRecordLocked(IBinder token) {
6992        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6993        if (r == null) {
6994            return null;
6995        }
6996        return r.resultTo;
6997    }
6998
6999    @Override
7000    public ComponentName getActivityClassForToken(IBinder token) {
7001        synchronized(this) {
7002            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7003            if (r == null) {
7004                return null;
7005            }
7006            return r.intent.getComponent();
7007        }
7008    }
7009
7010    @Override
7011    public String getPackageForToken(IBinder token) {
7012        synchronized(this) {
7013            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7014            if (r == null) {
7015                return null;
7016            }
7017            return r.packageName;
7018        }
7019    }
7020
7021    @Override
7022    public boolean isRootVoiceInteraction(IBinder token) {
7023        synchronized(this) {
7024            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7025            if (r == null) {
7026                return false;
7027            }
7028            return r.rootVoiceInteraction;
7029        }
7030    }
7031
7032    @Override
7033    public IIntentSender getIntentSender(int type,
7034            String packageName, IBinder token, String resultWho,
7035            int requestCode, Intent[] intents, String[] resolvedTypes,
7036            int flags, Bundle bOptions, int userId) {
7037        enforceNotIsolatedCaller("getIntentSender");
7038        // Refuse possible leaked file descriptors
7039        if (intents != null) {
7040            if (intents.length < 1) {
7041                throw new IllegalArgumentException("Intents array length must be >= 1");
7042            }
7043            for (int i=0; i<intents.length; i++) {
7044                Intent intent = intents[i];
7045                if (intent != null) {
7046                    if (intent.hasFileDescriptors()) {
7047                        throw new IllegalArgumentException("File descriptors passed in Intent");
7048                    }
7049                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7050                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7051                        throw new IllegalArgumentException(
7052                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7053                    }
7054                    intents[i] = new Intent(intent);
7055                }
7056            }
7057            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7058                throw new IllegalArgumentException(
7059                        "Intent array length does not match resolvedTypes length");
7060            }
7061        }
7062        if (bOptions != null) {
7063            if (bOptions.hasFileDescriptors()) {
7064                throw new IllegalArgumentException("File descriptors passed in options");
7065            }
7066        }
7067
7068        synchronized(this) {
7069            int callingUid = Binder.getCallingUid();
7070            int origUserId = userId;
7071            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7072                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7073                    ALLOW_NON_FULL, "getIntentSender", null);
7074            if (origUserId == UserHandle.USER_CURRENT) {
7075                // We don't want to evaluate this until the pending intent is
7076                // actually executed.  However, we do want to always do the
7077                // security checking for it above.
7078                userId = UserHandle.USER_CURRENT;
7079            }
7080            try {
7081                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7082                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7083                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7084                    if (!UserHandle.isSameApp(callingUid, uid)) {
7085                        String msg = "Permission Denial: getIntentSender() from pid="
7086                            + Binder.getCallingPid()
7087                            + ", uid=" + Binder.getCallingUid()
7088                            + ", (need uid=" + uid + ")"
7089                            + " is not allowed to send as package " + packageName;
7090                        Slog.w(TAG, msg);
7091                        throw new SecurityException(msg);
7092                    }
7093                }
7094
7095                return getIntentSenderLocked(type, packageName, callingUid, userId,
7096                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7097
7098            } catch (RemoteException e) {
7099                throw new SecurityException(e);
7100            }
7101        }
7102    }
7103
7104    IIntentSender getIntentSenderLocked(int type, String packageName,
7105            int callingUid, int userId, IBinder token, String resultWho,
7106            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7107            Bundle bOptions) {
7108        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7109        ActivityRecord activity = null;
7110        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7111            activity = ActivityRecord.isInStackLocked(token);
7112            if (activity == null) {
7113                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7114                return null;
7115            }
7116            if (activity.finishing) {
7117                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7118                return null;
7119            }
7120        }
7121
7122        // We're going to be splicing together extras before sending, so we're
7123        // okay poking into any contained extras.
7124        if (intents != null) {
7125            for (int i = 0; i < intents.length; i++) {
7126                intents[i].setDefusable(true);
7127            }
7128        }
7129        Bundle.setDefusable(bOptions, true);
7130
7131        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7132        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7133        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7134        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7135                |PendingIntent.FLAG_UPDATE_CURRENT);
7136
7137        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7138                type, packageName, activity, resultWho,
7139                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7140        WeakReference<PendingIntentRecord> ref;
7141        ref = mIntentSenderRecords.get(key);
7142        PendingIntentRecord rec = ref != null ? ref.get() : null;
7143        if (rec != null) {
7144            if (!cancelCurrent) {
7145                if (updateCurrent) {
7146                    if (rec.key.requestIntent != null) {
7147                        rec.key.requestIntent.replaceExtras(intents != null ?
7148                                intents[intents.length - 1] : null);
7149                    }
7150                    if (intents != null) {
7151                        intents[intents.length-1] = rec.key.requestIntent;
7152                        rec.key.allIntents = intents;
7153                        rec.key.allResolvedTypes = resolvedTypes;
7154                    } else {
7155                        rec.key.allIntents = null;
7156                        rec.key.allResolvedTypes = null;
7157                    }
7158                }
7159                return rec;
7160            }
7161            rec.canceled = true;
7162            mIntentSenderRecords.remove(key);
7163        }
7164        if (noCreate) {
7165            return rec;
7166        }
7167        rec = new PendingIntentRecord(this, key, callingUid);
7168        mIntentSenderRecords.put(key, rec.ref);
7169        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7170            if (activity.pendingResults == null) {
7171                activity.pendingResults
7172                        = new HashSet<WeakReference<PendingIntentRecord>>();
7173            }
7174            activity.pendingResults.add(rec.ref);
7175        }
7176        return rec;
7177    }
7178
7179    @Override
7180    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7181            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7182        if (target instanceof PendingIntentRecord) {
7183            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7184                    finishedReceiver, requiredPermission, options);
7185        } else {
7186            if (intent == null) {
7187                // Weird case: someone has given us their own custom IIntentSender, and now
7188                // they have someone else trying to send to it but of course this isn't
7189                // really a PendingIntent, so there is no base Intent, and the caller isn't
7190                // supplying an Intent... but we never want to dispatch a null Intent to
7191                // a receiver, so um...  let's make something up.
7192                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7193                intent = new Intent(Intent.ACTION_MAIN);
7194            }
7195            try {
7196                target.send(code, intent, resolvedType, null, requiredPermission, options);
7197            } catch (RemoteException e) {
7198            }
7199            // Platform code can rely on getting a result back when the send is done, but if
7200            // this intent sender is from outside of the system we can't rely on it doing that.
7201            // So instead we don't give it the result receiver, and instead just directly
7202            // report the finish immediately.
7203            if (finishedReceiver != null) {
7204                try {
7205                    finishedReceiver.performReceive(intent, 0,
7206                            null, null, false, false, UserHandle.getCallingUserId());
7207                } catch (RemoteException e) {
7208                }
7209            }
7210            return 0;
7211        }
7212    }
7213
7214    /**
7215     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7216     *
7217     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7218     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7219     */
7220    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7221        if (DEBUG_WHITELISTS) {
7222            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7223                    + targetUid + ", " + duration + ")");
7224        }
7225        synchronized (mPidsSelfLocked) {
7226            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7227            if (pr == null) {
7228                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7229                return;
7230            }
7231            if (!pr.whitelistManager) {
7232                if (DEBUG_WHITELISTS) {
7233                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7234                            + callerPid + " is not allowed");
7235                }
7236                return;
7237            }
7238        }
7239
7240        final long token = Binder.clearCallingIdentity();
7241        try {
7242            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7243                    true, "pe from uid:" + callerUid);
7244        } finally {
7245            Binder.restoreCallingIdentity(token);
7246        }
7247    }
7248
7249    @Override
7250    public void cancelIntentSender(IIntentSender sender) {
7251        if (!(sender instanceof PendingIntentRecord)) {
7252            return;
7253        }
7254        synchronized(this) {
7255            PendingIntentRecord rec = (PendingIntentRecord)sender;
7256            try {
7257                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7258                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7259                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7260                    String msg = "Permission Denial: cancelIntentSender() from pid="
7261                        + Binder.getCallingPid()
7262                        + ", uid=" + Binder.getCallingUid()
7263                        + " is not allowed to cancel packges "
7264                        + rec.key.packageName;
7265                    Slog.w(TAG, msg);
7266                    throw new SecurityException(msg);
7267                }
7268            } catch (RemoteException e) {
7269                throw new SecurityException(e);
7270            }
7271            cancelIntentSenderLocked(rec, true);
7272        }
7273    }
7274
7275    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7276        rec.canceled = true;
7277        mIntentSenderRecords.remove(rec.key);
7278        if (cleanActivity && rec.key.activity != null) {
7279            rec.key.activity.pendingResults.remove(rec.ref);
7280        }
7281    }
7282
7283    @Override
7284    public String getPackageForIntentSender(IIntentSender pendingResult) {
7285        if (!(pendingResult instanceof PendingIntentRecord)) {
7286            return null;
7287        }
7288        try {
7289            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7290            return res.key.packageName;
7291        } catch (ClassCastException e) {
7292        }
7293        return null;
7294    }
7295
7296    @Override
7297    public int getUidForIntentSender(IIntentSender sender) {
7298        if (sender instanceof PendingIntentRecord) {
7299            try {
7300                PendingIntentRecord res = (PendingIntentRecord)sender;
7301                return res.uid;
7302            } catch (ClassCastException e) {
7303            }
7304        }
7305        return -1;
7306    }
7307
7308    @Override
7309    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7310        if (!(pendingResult instanceof PendingIntentRecord)) {
7311            return false;
7312        }
7313        try {
7314            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7315            if (res.key.allIntents == null) {
7316                return false;
7317            }
7318            for (int i=0; i<res.key.allIntents.length; i++) {
7319                Intent intent = res.key.allIntents[i];
7320                if (intent.getPackage() != null && intent.getComponent() != null) {
7321                    return false;
7322                }
7323            }
7324            return true;
7325        } catch (ClassCastException e) {
7326        }
7327        return false;
7328    }
7329
7330    @Override
7331    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7332        if (!(pendingResult instanceof PendingIntentRecord)) {
7333            return false;
7334        }
7335        try {
7336            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7337            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7338                return true;
7339            }
7340            return false;
7341        } catch (ClassCastException e) {
7342        }
7343        return false;
7344    }
7345
7346    @Override
7347    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7348        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7349                "getIntentForIntentSender()");
7350        if (!(pendingResult instanceof PendingIntentRecord)) {
7351            return null;
7352        }
7353        try {
7354            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7355            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7356        } catch (ClassCastException e) {
7357        }
7358        return null;
7359    }
7360
7361    @Override
7362    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7363        if (!(pendingResult instanceof PendingIntentRecord)) {
7364            return null;
7365        }
7366        try {
7367            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7368            synchronized (this) {
7369                return getTagForIntentSenderLocked(res, prefix);
7370            }
7371        } catch (ClassCastException e) {
7372        }
7373        return null;
7374    }
7375
7376    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7377        final Intent intent = res.key.requestIntent;
7378        if (intent != null) {
7379            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7380                    || res.lastTagPrefix.equals(prefix))) {
7381                return res.lastTag;
7382            }
7383            res.lastTagPrefix = prefix;
7384            final StringBuilder sb = new StringBuilder(128);
7385            if (prefix != null) {
7386                sb.append(prefix);
7387            }
7388            if (intent.getAction() != null) {
7389                sb.append(intent.getAction());
7390            } else if (intent.getComponent() != null) {
7391                intent.getComponent().appendShortString(sb);
7392            } else {
7393                sb.append("?");
7394            }
7395            return res.lastTag = sb.toString();
7396        }
7397        return null;
7398    }
7399
7400    @Override
7401    public void setProcessLimit(int max) {
7402        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7403                "setProcessLimit()");
7404        synchronized (this) {
7405            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7406            mProcessLimitOverride = max;
7407        }
7408        trimApplications();
7409    }
7410
7411    @Override
7412    public int getProcessLimit() {
7413        synchronized (this) {
7414            return mProcessLimitOverride;
7415        }
7416    }
7417
7418    void foregroundTokenDied(ForegroundToken token) {
7419        synchronized (ActivityManagerService.this) {
7420            synchronized (mPidsSelfLocked) {
7421                ForegroundToken cur
7422                    = mForegroundProcesses.get(token.pid);
7423                if (cur != token) {
7424                    return;
7425                }
7426                mForegroundProcesses.remove(token.pid);
7427                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7428                if (pr == null) {
7429                    return;
7430                }
7431                pr.forcingToForeground = null;
7432                updateProcessForegroundLocked(pr, false, false);
7433            }
7434            updateOomAdjLocked();
7435        }
7436    }
7437
7438    @Override
7439    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7440        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7441                "setProcessForeground()");
7442        synchronized(this) {
7443            boolean changed = false;
7444
7445            synchronized (mPidsSelfLocked) {
7446                ProcessRecord pr = mPidsSelfLocked.get(pid);
7447                if (pr == null && isForeground) {
7448                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7449                    return;
7450                }
7451                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7452                if (oldToken != null) {
7453                    oldToken.token.unlinkToDeath(oldToken, 0);
7454                    mForegroundProcesses.remove(pid);
7455                    if (pr != null) {
7456                        pr.forcingToForeground = null;
7457                    }
7458                    changed = true;
7459                }
7460                if (isForeground && token != null) {
7461                    ForegroundToken newToken = new ForegroundToken() {
7462                        @Override
7463                        public void binderDied() {
7464                            foregroundTokenDied(this);
7465                        }
7466                    };
7467                    newToken.pid = pid;
7468                    newToken.token = token;
7469                    try {
7470                        token.linkToDeath(newToken, 0);
7471                        mForegroundProcesses.put(pid, newToken);
7472                        pr.forcingToForeground = token;
7473                        changed = true;
7474                    } catch (RemoteException e) {
7475                        // If the process died while doing this, we will later
7476                        // do the cleanup with the process death link.
7477                    }
7478                }
7479            }
7480
7481            if (changed) {
7482                updateOomAdjLocked();
7483            }
7484        }
7485    }
7486
7487    @Override
7488    public boolean isAppForeground(int uid) throws RemoteException {
7489        synchronized (this) {
7490            UidRecord uidRec = mActiveUids.get(uid);
7491            if (uidRec == null || uidRec.idle) {
7492                return false;
7493            }
7494            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7495        }
7496    }
7497
7498    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7499    // be guarded by permission checking.
7500    int getUidState(int uid) {
7501        synchronized (this) {
7502            UidRecord uidRec = mActiveUids.get(uid);
7503            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7504        }
7505    }
7506
7507    @Override
7508    public boolean isInMultiWindowMode(IBinder token) {
7509        final long origId = Binder.clearCallingIdentity();
7510        try {
7511            synchronized(this) {
7512                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7513                if (r == null) {
7514                    return false;
7515                }
7516                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7517                return !r.task.mFullscreen;
7518            }
7519        } finally {
7520            Binder.restoreCallingIdentity(origId);
7521        }
7522    }
7523
7524    @Override
7525    public boolean isInPictureInPictureMode(IBinder token) {
7526        final long origId = Binder.clearCallingIdentity();
7527        try {
7528            synchronized(this) {
7529                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7530                if (stack == null) {
7531                    return false;
7532                }
7533                return stack.mStackId == PINNED_STACK_ID;
7534            }
7535        } finally {
7536            Binder.restoreCallingIdentity(origId);
7537        }
7538    }
7539
7540    @Override
7541    public void enterPictureInPictureMode(IBinder token) {
7542        final long origId = Binder.clearCallingIdentity();
7543        try {
7544            synchronized(this) {
7545                if (!mSupportsPictureInPicture) {
7546                    throw new IllegalStateException("enterPictureInPictureMode: "
7547                            + "Device doesn't support picture-in-picture mode.");
7548                }
7549
7550                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7551
7552                if (r == null) {
7553                    throw new IllegalStateException("enterPictureInPictureMode: "
7554                            + "Can't find activity for token=" + token);
7555                }
7556
7557                if (!r.supportsPictureInPicture()) {
7558                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7559                            + "Picture-In-Picture not supported for r=" + r);
7560                }
7561
7562                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7563                // current bounds.
7564                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7565                final Rect bounds = (pinnedStack != null)
7566                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7567
7568                mStackSupervisor.moveActivityToPinnedStackLocked(
7569                        r, "enterPictureInPictureMode", bounds);
7570            }
7571        } finally {
7572            Binder.restoreCallingIdentity(origId);
7573        }
7574    }
7575
7576    // =========================================================
7577    // PROCESS INFO
7578    // =========================================================
7579
7580    static class ProcessInfoService extends IProcessInfoService.Stub {
7581        final ActivityManagerService mActivityManagerService;
7582        ProcessInfoService(ActivityManagerService activityManagerService) {
7583            mActivityManagerService = activityManagerService;
7584        }
7585
7586        @Override
7587        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7588            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7589                    /*in*/ pids, /*out*/ states, null);
7590        }
7591
7592        @Override
7593        public void getProcessStatesAndOomScoresFromPids(
7594                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7595            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7596                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7597        }
7598    }
7599
7600    /**
7601     * For each PID in the given input array, write the current process state
7602     * for that process into the states array, or -1 to indicate that no
7603     * process with the given PID exists. If scores array is provided, write
7604     * the oom score for the process into the scores array, with INVALID_ADJ
7605     * indicating the PID doesn't exist.
7606     */
7607    public void getProcessStatesAndOomScoresForPIDs(
7608            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7609        if (scores != null) {
7610            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7611                    "getProcessStatesAndOomScoresForPIDs()");
7612        }
7613
7614        if (pids == null) {
7615            throw new NullPointerException("pids");
7616        } else if (states == null) {
7617            throw new NullPointerException("states");
7618        } else if (pids.length != states.length) {
7619            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7620        } else if (scores != null && pids.length != scores.length) {
7621            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7622        }
7623
7624        synchronized (mPidsSelfLocked) {
7625            for (int i = 0; i < pids.length; i++) {
7626                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7627                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7628                        pr.curProcState;
7629                if (scores != null) {
7630                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7631                }
7632            }
7633        }
7634    }
7635
7636    // =========================================================
7637    // PERMISSIONS
7638    // =========================================================
7639
7640    static class PermissionController extends IPermissionController.Stub {
7641        ActivityManagerService mActivityManagerService;
7642        PermissionController(ActivityManagerService activityManagerService) {
7643            mActivityManagerService = activityManagerService;
7644        }
7645
7646        @Override
7647        public boolean checkPermission(String permission, int pid, int uid) {
7648            return mActivityManagerService.checkPermission(permission, pid,
7649                    uid) == PackageManager.PERMISSION_GRANTED;
7650        }
7651
7652        @Override
7653        public String[] getPackagesForUid(int uid) {
7654            return mActivityManagerService.mContext.getPackageManager()
7655                    .getPackagesForUid(uid);
7656        }
7657
7658        @Override
7659        public boolean isRuntimePermission(String permission) {
7660            try {
7661                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7662                        .getPermissionInfo(permission, 0);
7663                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7664            } catch (NameNotFoundException nnfe) {
7665                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7666            }
7667            return false;
7668        }
7669    }
7670
7671    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7672        @Override
7673        public int checkComponentPermission(String permission, int pid, int uid,
7674                int owningUid, boolean exported) {
7675            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7676                    owningUid, exported);
7677        }
7678
7679        @Override
7680        public Object getAMSLock() {
7681            return ActivityManagerService.this;
7682        }
7683    }
7684
7685    /**
7686     * This can be called with or without the global lock held.
7687     */
7688    int checkComponentPermission(String permission, int pid, int uid,
7689            int owningUid, boolean exported) {
7690        if (pid == MY_PID) {
7691            return PackageManager.PERMISSION_GRANTED;
7692        }
7693        return ActivityManager.checkComponentPermission(permission, uid,
7694                owningUid, exported);
7695    }
7696
7697    /**
7698     * As the only public entry point for permissions checking, this method
7699     * can enforce the semantic that requesting a check on a null global
7700     * permission is automatically denied.  (Internally a null permission
7701     * string is used when calling {@link #checkComponentPermission} in cases
7702     * when only uid-based security is needed.)
7703     *
7704     * This can be called with or without the global lock held.
7705     */
7706    @Override
7707    public int checkPermission(String permission, int pid, int uid) {
7708        if (permission == null) {
7709            return PackageManager.PERMISSION_DENIED;
7710        }
7711        return checkComponentPermission(permission, pid, uid, -1, true);
7712    }
7713
7714    @Override
7715    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7716        if (permission == null) {
7717            return PackageManager.PERMISSION_DENIED;
7718        }
7719
7720        // We might be performing an operation on behalf of an indirect binder
7721        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7722        // client identity accordingly before proceeding.
7723        Identity tlsIdentity = sCallerIdentity.get();
7724        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7725            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7726                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7727            uid = tlsIdentity.uid;
7728            pid = tlsIdentity.pid;
7729        }
7730
7731        return checkComponentPermission(permission, pid, uid, -1, true);
7732    }
7733
7734    /**
7735     * Binder IPC calls go through the public entry point.
7736     * This can be called with or without the global lock held.
7737     */
7738    int checkCallingPermission(String permission) {
7739        return checkPermission(permission,
7740                Binder.getCallingPid(),
7741                UserHandle.getAppId(Binder.getCallingUid()));
7742    }
7743
7744    /**
7745     * This can be called with or without the global lock held.
7746     */
7747    void enforceCallingPermission(String permission, String func) {
7748        if (checkCallingPermission(permission)
7749                == PackageManager.PERMISSION_GRANTED) {
7750            return;
7751        }
7752
7753        String msg = "Permission Denial: " + func + " from pid="
7754                + Binder.getCallingPid()
7755                + ", uid=" + Binder.getCallingUid()
7756                + " requires " + permission;
7757        Slog.w(TAG, msg);
7758        throw new SecurityException(msg);
7759    }
7760
7761    /**
7762     * Determine if UID is holding permissions required to access {@link Uri} in
7763     * the given {@link ProviderInfo}. Final permission checking is always done
7764     * in {@link ContentProvider}.
7765     */
7766    private final boolean checkHoldingPermissionsLocked(
7767            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7768        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7769                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7770        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7771            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7772                    != PERMISSION_GRANTED) {
7773                return false;
7774            }
7775        }
7776        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7777    }
7778
7779    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7780            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7781        if (pi.applicationInfo.uid == uid) {
7782            return true;
7783        } else if (!pi.exported) {
7784            return false;
7785        }
7786
7787        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7788        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7789        try {
7790            // check if target holds top-level <provider> permissions
7791            if (!readMet && pi.readPermission != null && considerUidPermissions
7792                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7793                readMet = true;
7794            }
7795            if (!writeMet && pi.writePermission != null && considerUidPermissions
7796                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7797                writeMet = true;
7798            }
7799
7800            // track if unprotected read/write is allowed; any denied
7801            // <path-permission> below removes this ability
7802            boolean allowDefaultRead = pi.readPermission == null;
7803            boolean allowDefaultWrite = pi.writePermission == null;
7804
7805            // check if target holds any <path-permission> that match uri
7806            final PathPermission[] pps = pi.pathPermissions;
7807            if (pps != null) {
7808                final String path = grantUri.uri.getPath();
7809                int i = pps.length;
7810                while (i > 0 && (!readMet || !writeMet)) {
7811                    i--;
7812                    PathPermission pp = pps[i];
7813                    if (pp.match(path)) {
7814                        if (!readMet) {
7815                            final String pprperm = pp.getReadPermission();
7816                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7817                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7818                                    + ": match=" + pp.match(path)
7819                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7820                            if (pprperm != null) {
7821                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7822                                        == PERMISSION_GRANTED) {
7823                                    readMet = true;
7824                                } else {
7825                                    allowDefaultRead = false;
7826                                }
7827                            }
7828                        }
7829                        if (!writeMet) {
7830                            final String ppwperm = pp.getWritePermission();
7831                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7832                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7833                                    + ": match=" + pp.match(path)
7834                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7835                            if (ppwperm != null) {
7836                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7837                                        == PERMISSION_GRANTED) {
7838                                    writeMet = true;
7839                                } else {
7840                                    allowDefaultWrite = false;
7841                                }
7842                            }
7843                        }
7844                    }
7845                }
7846            }
7847
7848            // grant unprotected <provider> read/write, if not blocked by
7849            // <path-permission> above
7850            if (allowDefaultRead) readMet = true;
7851            if (allowDefaultWrite) writeMet = true;
7852
7853        } catch (RemoteException e) {
7854            return false;
7855        }
7856
7857        return readMet && writeMet;
7858    }
7859
7860    public int getAppStartMode(int uid, String packageName) {
7861        synchronized (this) {
7862            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7863        }
7864    }
7865
7866    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7867            boolean allowWhenForeground) {
7868        UidRecord uidRec = mActiveUids.get(uid);
7869        if (!mLenientBackgroundCheck) {
7870            if (!allowWhenForeground || uidRec == null
7871                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7872                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7873                        packageName) != AppOpsManager.MODE_ALLOWED) {
7874                    return ActivityManager.APP_START_MODE_DELAYED;
7875                }
7876            }
7877
7878        } else if (uidRec == null || uidRec.idle) {
7879            if (callingPid >= 0) {
7880                ProcessRecord proc;
7881                synchronized (mPidsSelfLocked) {
7882                    proc = mPidsSelfLocked.get(callingPid);
7883                }
7884                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7885                    // Whoever is instigating this is in the foreground, so we will allow it
7886                    // to go through.
7887                    return ActivityManager.APP_START_MODE_NORMAL;
7888                }
7889            }
7890            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7891                    != AppOpsManager.MODE_ALLOWED) {
7892                return ActivityManager.APP_START_MODE_DELAYED;
7893            }
7894        }
7895        return ActivityManager.APP_START_MODE_NORMAL;
7896    }
7897
7898    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7899        ProviderInfo pi = null;
7900        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7901        if (cpr != null) {
7902            pi = cpr.info;
7903        } else {
7904            try {
7905                pi = AppGlobals.getPackageManager().resolveContentProvider(
7906                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7907                        userHandle);
7908            } catch (RemoteException ex) {
7909            }
7910        }
7911        return pi;
7912    }
7913
7914    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7915        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7916        if (targetUris != null) {
7917            return targetUris.get(grantUri);
7918        }
7919        return null;
7920    }
7921
7922    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7923            String targetPkg, int targetUid, GrantUri grantUri) {
7924        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7925        if (targetUris == null) {
7926            targetUris = Maps.newArrayMap();
7927            mGrantedUriPermissions.put(targetUid, targetUris);
7928        }
7929
7930        UriPermission perm = targetUris.get(grantUri);
7931        if (perm == null) {
7932            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7933            targetUris.put(grantUri, perm);
7934        }
7935
7936        return perm;
7937    }
7938
7939    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7940            final int modeFlags) {
7941        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7942        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7943                : UriPermission.STRENGTH_OWNED;
7944
7945        // Root gets to do everything.
7946        if (uid == 0) {
7947            return true;
7948        }
7949
7950        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7951        if (perms == null) return false;
7952
7953        // First look for exact match
7954        final UriPermission exactPerm = perms.get(grantUri);
7955        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7956            return true;
7957        }
7958
7959        // No exact match, look for prefixes
7960        final int N = perms.size();
7961        for (int i = 0; i < N; i++) {
7962            final UriPermission perm = perms.valueAt(i);
7963            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7964                    && perm.getStrength(modeFlags) >= minStrength) {
7965                return true;
7966            }
7967        }
7968
7969        return false;
7970    }
7971
7972    /**
7973     * @param uri This uri must NOT contain an embedded userId.
7974     * @param userId The userId in which the uri is to be resolved.
7975     */
7976    @Override
7977    public int checkUriPermission(Uri uri, int pid, int uid,
7978            final int modeFlags, int userId, IBinder callerToken) {
7979        enforceNotIsolatedCaller("checkUriPermission");
7980
7981        // Another redirected-binder-call permissions check as in
7982        // {@link checkPermissionWithToken}.
7983        Identity tlsIdentity = sCallerIdentity.get();
7984        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7985            uid = tlsIdentity.uid;
7986            pid = tlsIdentity.pid;
7987        }
7988
7989        // Our own process gets to do everything.
7990        if (pid == MY_PID) {
7991            return PackageManager.PERMISSION_GRANTED;
7992        }
7993        synchronized (this) {
7994            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7995                    ? PackageManager.PERMISSION_GRANTED
7996                    : PackageManager.PERMISSION_DENIED;
7997        }
7998    }
7999
8000    /**
8001     * Check if the targetPkg can be granted permission to access uri by
8002     * the callingUid using the given modeFlags.  Throws a security exception
8003     * if callingUid is not allowed to do this.  Returns the uid of the target
8004     * if the URI permission grant should be performed; returns -1 if it is not
8005     * needed (for example targetPkg already has permission to access the URI).
8006     * If you already know the uid of the target, you can supply it in
8007     * lastTargetUid else set that to -1.
8008     */
8009    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8010            final int modeFlags, int lastTargetUid) {
8011        if (!Intent.isAccessUriMode(modeFlags)) {
8012            return -1;
8013        }
8014
8015        if (targetPkg != null) {
8016            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8017                    "Checking grant " + targetPkg + " permission to " + grantUri);
8018        }
8019
8020        final IPackageManager pm = AppGlobals.getPackageManager();
8021
8022        // If this is not a content: uri, we can't do anything with it.
8023        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8024            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8025                    "Can't grant URI permission for non-content URI: " + grantUri);
8026            return -1;
8027        }
8028
8029        final String authority = grantUri.uri.getAuthority();
8030        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8031                MATCH_DEBUG_TRIAGED_MISSING);
8032        if (pi == null) {
8033            Slog.w(TAG, "No content provider found for permission check: " +
8034                    grantUri.uri.toSafeString());
8035            return -1;
8036        }
8037
8038        int targetUid = lastTargetUid;
8039        if (targetUid < 0 && targetPkg != null) {
8040            try {
8041                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8042                        UserHandle.getUserId(callingUid));
8043                if (targetUid < 0) {
8044                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8045                            "Can't grant URI permission no uid for: " + targetPkg);
8046                    return -1;
8047                }
8048            } catch (RemoteException ex) {
8049                return -1;
8050            }
8051        }
8052
8053        if (targetUid >= 0) {
8054            // First...  does the target actually need this permission?
8055            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8056                // No need to grant the target this permission.
8057                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8058                        "Target " + targetPkg + " already has full permission to " + grantUri);
8059                return -1;
8060            }
8061        } else {
8062            // First...  there is no target package, so can anyone access it?
8063            boolean allowed = pi.exported;
8064            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8065                if (pi.readPermission != null) {
8066                    allowed = false;
8067                }
8068            }
8069            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8070                if (pi.writePermission != null) {
8071                    allowed = false;
8072                }
8073            }
8074            if (allowed) {
8075                return -1;
8076            }
8077        }
8078
8079        /* There is a special cross user grant if:
8080         * - The target is on another user.
8081         * - Apps on the current user can access the uri without any uid permissions.
8082         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8083         * grant uri permissions.
8084         */
8085        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8086                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8087                modeFlags, false /*without considering the uid permissions*/);
8088
8089        // Second...  is the provider allowing granting of URI permissions?
8090        if (!specialCrossUserGrant) {
8091            if (!pi.grantUriPermissions) {
8092                throw new SecurityException("Provider " + pi.packageName
8093                        + "/" + pi.name
8094                        + " does not allow granting of Uri permissions (uri "
8095                        + grantUri + ")");
8096            }
8097            if (pi.uriPermissionPatterns != null) {
8098                final int N = pi.uriPermissionPatterns.length;
8099                boolean allowed = false;
8100                for (int i=0; i<N; i++) {
8101                    if (pi.uriPermissionPatterns[i] != null
8102                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8103                        allowed = true;
8104                        break;
8105                    }
8106                }
8107                if (!allowed) {
8108                    throw new SecurityException("Provider " + pi.packageName
8109                            + "/" + pi.name
8110                            + " does not allow granting of permission to path of Uri "
8111                            + grantUri);
8112                }
8113            }
8114        }
8115
8116        // Third...  does the caller itself have permission to access
8117        // this uri?
8118        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8119            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8120                // Require they hold a strong enough Uri permission
8121                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8122                    throw new SecurityException("Uid " + callingUid
8123                            + " does not have permission to uri " + grantUri);
8124                }
8125            }
8126        }
8127        return targetUid;
8128    }
8129
8130    /**
8131     * @param uri This uri must NOT contain an embedded userId.
8132     * @param userId The userId in which the uri is to be resolved.
8133     */
8134    @Override
8135    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8136            final int modeFlags, int userId) {
8137        enforceNotIsolatedCaller("checkGrantUriPermission");
8138        synchronized(this) {
8139            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8140                    new GrantUri(userId, uri, false), modeFlags, -1);
8141        }
8142    }
8143
8144    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8145            final int modeFlags, UriPermissionOwner owner) {
8146        if (!Intent.isAccessUriMode(modeFlags)) {
8147            return;
8148        }
8149
8150        // So here we are: the caller has the assumed permission
8151        // to the uri, and the target doesn't.  Let's now give this to
8152        // the target.
8153
8154        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8155                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8156
8157        final String authority = grantUri.uri.getAuthority();
8158        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8159                MATCH_DEBUG_TRIAGED_MISSING);
8160        if (pi == null) {
8161            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8162            return;
8163        }
8164
8165        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8166            grantUri.prefix = true;
8167        }
8168        final UriPermission perm = findOrCreateUriPermissionLocked(
8169                pi.packageName, targetPkg, targetUid, grantUri);
8170        perm.grantModes(modeFlags, owner);
8171    }
8172
8173    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8174            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8175        if (targetPkg == null) {
8176            throw new NullPointerException("targetPkg");
8177        }
8178        int targetUid;
8179        final IPackageManager pm = AppGlobals.getPackageManager();
8180        try {
8181            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8182        } catch (RemoteException ex) {
8183            return;
8184        }
8185
8186        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8187                targetUid);
8188        if (targetUid < 0) {
8189            return;
8190        }
8191
8192        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8193                owner);
8194    }
8195
8196    static class NeededUriGrants extends ArrayList<GrantUri> {
8197        final String targetPkg;
8198        final int targetUid;
8199        final int flags;
8200
8201        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8202            this.targetPkg = targetPkg;
8203            this.targetUid = targetUid;
8204            this.flags = flags;
8205        }
8206    }
8207
8208    /**
8209     * Like checkGrantUriPermissionLocked, but takes an Intent.
8210     */
8211    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8212            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8213        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8214                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8215                + " clip=" + (intent != null ? intent.getClipData() : null)
8216                + " from " + intent + "; flags=0x"
8217                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8218
8219        if (targetPkg == null) {
8220            throw new NullPointerException("targetPkg");
8221        }
8222
8223        if (intent == null) {
8224            return null;
8225        }
8226        Uri data = intent.getData();
8227        ClipData clip = intent.getClipData();
8228        if (data == null && clip == null) {
8229            return null;
8230        }
8231        // Default userId for uris in the intent (if they don't specify it themselves)
8232        int contentUserHint = intent.getContentUserHint();
8233        if (contentUserHint == UserHandle.USER_CURRENT) {
8234            contentUserHint = UserHandle.getUserId(callingUid);
8235        }
8236        final IPackageManager pm = AppGlobals.getPackageManager();
8237        int targetUid;
8238        if (needed != null) {
8239            targetUid = needed.targetUid;
8240        } else {
8241            try {
8242                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8243                        targetUserId);
8244            } catch (RemoteException ex) {
8245                return null;
8246            }
8247            if (targetUid < 0) {
8248                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8249                        "Can't grant URI permission no uid for: " + targetPkg
8250                        + " on user " + targetUserId);
8251                return null;
8252            }
8253        }
8254        if (data != null) {
8255            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8256            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8257                    targetUid);
8258            if (targetUid > 0) {
8259                if (needed == null) {
8260                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8261                }
8262                needed.add(grantUri);
8263            }
8264        }
8265        if (clip != null) {
8266            for (int i=0; i<clip.getItemCount(); i++) {
8267                Uri uri = clip.getItemAt(i).getUri();
8268                if (uri != null) {
8269                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8270                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8271                            targetUid);
8272                    if (targetUid > 0) {
8273                        if (needed == null) {
8274                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8275                        }
8276                        needed.add(grantUri);
8277                    }
8278                } else {
8279                    Intent clipIntent = clip.getItemAt(i).getIntent();
8280                    if (clipIntent != null) {
8281                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8282                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8283                        if (newNeeded != null) {
8284                            needed = newNeeded;
8285                        }
8286                    }
8287                }
8288            }
8289        }
8290
8291        return needed;
8292    }
8293
8294    /**
8295     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8296     */
8297    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8298            UriPermissionOwner owner) {
8299        if (needed != null) {
8300            for (int i=0; i<needed.size(); i++) {
8301                GrantUri grantUri = needed.get(i);
8302                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8303                        grantUri, needed.flags, owner);
8304            }
8305        }
8306    }
8307
8308    void grantUriPermissionFromIntentLocked(int callingUid,
8309            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8310        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8311                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8312        if (needed == null) {
8313            return;
8314        }
8315
8316        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8317    }
8318
8319    /**
8320     * @param uri This uri must NOT contain an embedded userId.
8321     * @param userId The userId in which the uri is to be resolved.
8322     */
8323    @Override
8324    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8325            final int modeFlags, int userId) {
8326        enforceNotIsolatedCaller("grantUriPermission");
8327        GrantUri grantUri = new GrantUri(userId, uri, false);
8328        synchronized(this) {
8329            final ProcessRecord r = getRecordForAppLocked(caller);
8330            if (r == null) {
8331                throw new SecurityException("Unable to find app for caller "
8332                        + caller
8333                        + " when granting permission to uri " + grantUri);
8334            }
8335            if (targetPkg == null) {
8336                throw new IllegalArgumentException("null target");
8337            }
8338            if (grantUri == null) {
8339                throw new IllegalArgumentException("null uri");
8340            }
8341
8342            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8343                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8344                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8345                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8346
8347            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8348                    UserHandle.getUserId(r.uid));
8349        }
8350    }
8351
8352    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8353        if (perm.modeFlags == 0) {
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8355                    perm.targetUid);
8356            if (perms != null) {
8357                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8358                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8359
8360                perms.remove(perm.uri);
8361                if (perms.isEmpty()) {
8362                    mGrantedUriPermissions.remove(perm.targetUid);
8363                }
8364            }
8365        }
8366    }
8367
8368    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8369        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8370                "Revoking all granted permissions to " + grantUri);
8371
8372        final IPackageManager pm = AppGlobals.getPackageManager();
8373        final String authority = grantUri.uri.getAuthority();
8374        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8375                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8376        if (pi == null) {
8377            Slog.w(TAG, "No content provider found for permission revoke: "
8378                    + grantUri.toSafeString());
8379            return;
8380        }
8381
8382        // Does the caller have this permission on the URI?
8383        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8384            // If they don't have direct access to the URI, then revoke any
8385            // ownerless URI permissions that have been granted to them.
8386            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8387            if (perms != null) {
8388                boolean persistChanged = false;
8389                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8390                    final UriPermission perm = it.next();
8391                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8392                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8393                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8394                                "Revoking non-owned " + perm.targetUid
8395                                + " permission to " + perm.uri);
8396                        persistChanged |= perm.revokeModes(
8397                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8398                        if (perm.modeFlags == 0) {
8399                            it.remove();
8400                        }
8401                    }
8402                }
8403                if (perms.isEmpty()) {
8404                    mGrantedUriPermissions.remove(callingUid);
8405                }
8406                if (persistChanged) {
8407                    schedulePersistUriGrants();
8408                }
8409            }
8410            return;
8411        }
8412
8413        boolean persistChanged = false;
8414
8415        // Go through all of the permissions and remove any that match.
8416        int N = mGrantedUriPermissions.size();
8417        for (int i = 0; i < N; i++) {
8418            final int targetUid = mGrantedUriPermissions.keyAt(i);
8419            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8420
8421            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8422                final UriPermission perm = it.next();
8423                if (perm.uri.sourceUserId == grantUri.sourceUserId
8424                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8425                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8426                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8427                    persistChanged |= perm.revokeModes(
8428                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8429                    if (perm.modeFlags == 0) {
8430                        it.remove();
8431                    }
8432                }
8433            }
8434
8435            if (perms.isEmpty()) {
8436                mGrantedUriPermissions.remove(targetUid);
8437                N--;
8438                i--;
8439            }
8440        }
8441
8442        if (persistChanged) {
8443            schedulePersistUriGrants();
8444        }
8445    }
8446
8447    /**
8448     * @param uri This uri must NOT contain an embedded userId.
8449     * @param userId The userId in which the uri is to be resolved.
8450     */
8451    @Override
8452    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8453            int userId) {
8454        enforceNotIsolatedCaller("revokeUriPermission");
8455        synchronized(this) {
8456            final ProcessRecord r = getRecordForAppLocked(caller);
8457            if (r == null) {
8458                throw new SecurityException("Unable to find app for caller "
8459                        + caller
8460                        + " when revoking permission to uri " + uri);
8461            }
8462            if (uri == null) {
8463                Slog.w(TAG, "revokeUriPermission: null uri");
8464                return;
8465            }
8466
8467            if (!Intent.isAccessUriMode(modeFlags)) {
8468                return;
8469            }
8470
8471            final String authority = uri.getAuthority();
8472            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8473                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8474            if (pi == null) {
8475                Slog.w(TAG, "No content provider found for permission revoke: "
8476                        + uri.toSafeString());
8477                return;
8478            }
8479
8480            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8481        }
8482    }
8483
8484    /**
8485     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8486     * given package.
8487     *
8488     * @param packageName Package name to match, or {@code null} to apply to all
8489     *            packages.
8490     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8491     *            to all users.
8492     * @param persistable If persistable grants should be removed.
8493     */
8494    private void removeUriPermissionsForPackageLocked(
8495            String packageName, int userHandle, boolean persistable) {
8496        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8497            throw new IllegalArgumentException("Must narrow by either package or user");
8498        }
8499
8500        boolean persistChanged = false;
8501
8502        int N = mGrantedUriPermissions.size();
8503        for (int i = 0; i < N; i++) {
8504            final int targetUid = mGrantedUriPermissions.keyAt(i);
8505            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8506
8507            // Only inspect grants matching user
8508            if (userHandle == UserHandle.USER_ALL
8509                    || userHandle == UserHandle.getUserId(targetUid)) {
8510                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8511                    final UriPermission perm = it.next();
8512
8513                    // Only inspect grants matching package
8514                    if (packageName == null || perm.sourcePkg.equals(packageName)
8515                            || perm.targetPkg.equals(packageName)) {
8516                        persistChanged |= perm.revokeModes(persistable
8517                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8518
8519                        // Only remove when no modes remain; any persisted grants
8520                        // will keep this alive.
8521                        if (perm.modeFlags == 0) {
8522                            it.remove();
8523                        }
8524                    }
8525                }
8526
8527                if (perms.isEmpty()) {
8528                    mGrantedUriPermissions.remove(targetUid);
8529                    N--;
8530                    i--;
8531                }
8532            }
8533        }
8534
8535        if (persistChanged) {
8536            schedulePersistUriGrants();
8537        }
8538    }
8539
8540    @Override
8541    public IBinder newUriPermissionOwner(String name) {
8542        enforceNotIsolatedCaller("newUriPermissionOwner");
8543        synchronized(this) {
8544            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8545            return owner.getExternalTokenLocked();
8546        }
8547    }
8548
8549    @Override
8550    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8551        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8552        synchronized(this) {
8553            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8554            if (r == null) {
8555                throw new IllegalArgumentException("Activity does not exist; token="
8556                        + activityToken);
8557            }
8558            return r.getUriPermissionsLocked().getExternalTokenLocked();
8559        }
8560    }
8561    /**
8562     * @param uri This uri must NOT contain an embedded userId.
8563     * @param sourceUserId The userId in which the uri is to be resolved.
8564     * @param targetUserId The userId of the app that receives the grant.
8565     */
8566    @Override
8567    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8568            final int modeFlags, int sourceUserId, int targetUserId) {
8569        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8570                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8571                "grantUriPermissionFromOwner", null);
8572        synchronized(this) {
8573            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8574            if (owner == null) {
8575                throw new IllegalArgumentException("Unknown owner: " + token);
8576            }
8577            if (fromUid != Binder.getCallingUid()) {
8578                if (Binder.getCallingUid() != Process.myUid()) {
8579                    // Only system code can grant URI permissions on behalf
8580                    // of other users.
8581                    throw new SecurityException("nice try");
8582                }
8583            }
8584            if (targetPkg == null) {
8585                throw new IllegalArgumentException("null target");
8586            }
8587            if (uri == null) {
8588                throw new IllegalArgumentException("null uri");
8589            }
8590
8591            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8592                    modeFlags, owner, targetUserId);
8593        }
8594    }
8595
8596    /**
8597     * @param uri This uri must NOT contain an embedded userId.
8598     * @param userId The userId in which the uri is to be resolved.
8599     */
8600    @Override
8601    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8602        synchronized(this) {
8603            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8604            if (owner == null) {
8605                throw new IllegalArgumentException("Unknown owner: " + token);
8606            }
8607
8608            if (uri == null) {
8609                owner.removeUriPermissionsLocked(mode);
8610            } else {
8611                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8612                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8613            }
8614        }
8615    }
8616
8617    private void schedulePersistUriGrants() {
8618        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8619            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8620                    10 * DateUtils.SECOND_IN_MILLIS);
8621        }
8622    }
8623
8624    private void writeGrantedUriPermissions() {
8625        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8626
8627        // Snapshot permissions so we can persist without lock
8628        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8629        synchronized (this) {
8630            final int size = mGrantedUriPermissions.size();
8631            for (int i = 0; i < size; i++) {
8632                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8633                for (UriPermission perm : perms.values()) {
8634                    if (perm.persistedModeFlags != 0) {
8635                        persist.add(perm.snapshot());
8636                    }
8637                }
8638            }
8639        }
8640
8641        FileOutputStream fos = null;
8642        try {
8643            fos = mGrantFile.startWrite();
8644
8645            XmlSerializer out = new FastXmlSerializer();
8646            out.setOutput(fos, StandardCharsets.UTF_8.name());
8647            out.startDocument(null, true);
8648            out.startTag(null, TAG_URI_GRANTS);
8649            for (UriPermission.Snapshot perm : persist) {
8650                out.startTag(null, TAG_URI_GRANT);
8651                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8652                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8653                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8654                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8655                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8656                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8657                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8658                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8659                out.endTag(null, TAG_URI_GRANT);
8660            }
8661            out.endTag(null, TAG_URI_GRANTS);
8662            out.endDocument();
8663
8664            mGrantFile.finishWrite(fos);
8665        } catch (IOException e) {
8666            if (fos != null) {
8667                mGrantFile.failWrite(fos);
8668            }
8669        }
8670    }
8671
8672    private void readGrantedUriPermissionsLocked() {
8673        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8674
8675        final long now = System.currentTimeMillis();
8676
8677        FileInputStream fis = null;
8678        try {
8679            fis = mGrantFile.openRead();
8680            final XmlPullParser in = Xml.newPullParser();
8681            in.setInput(fis, StandardCharsets.UTF_8.name());
8682
8683            int type;
8684            while ((type = in.next()) != END_DOCUMENT) {
8685                final String tag = in.getName();
8686                if (type == START_TAG) {
8687                    if (TAG_URI_GRANT.equals(tag)) {
8688                        final int sourceUserId;
8689                        final int targetUserId;
8690                        final int userHandle = readIntAttribute(in,
8691                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8692                        if (userHandle != UserHandle.USER_NULL) {
8693                            // For backwards compatibility.
8694                            sourceUserId = userHandle;
8695                            targetUserId = userHandle;
8696                        } else {
8697                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8698                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8699                        }
8700                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8701                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8702                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8703                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8704                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8705                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8706
8707                        // Sanity check that provider still belongs to source package
8708                        // Both direct boot aware and unaware packages are fine as we
8709                        // will do filtering at query time to avoid multiple parsing.
8710                        final ProviderInfo pi = getProviderInfoLocked(
8711                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8712                                        | MATCH_DIRECT_BOOT_UNAWARE);
8713                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8714                            int targetUid = -1;
8715                            try {
8716                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8717                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8718                            } catch (RemoteException e) {
8719                            }
8720                            if (targetUid != -1) {
8721                                final UriPermission perm = findOrCreateUriPermissionLocked(
8722                                        sourcePkg, targetPkg, targetUid,
8723                                        new GrantUri(sourceUserId, uri, prefix));
8724                                perm.initPersistedModes(modeFlags, createdTime);
8725                            }
8726                        } else {
8727                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8728                                    + " but instead found " + pi);
8729                        }
8730                    }
8731                }
8732            }
8733        } catch (FileNotFoundException e) {
8734            // Missing grants is okay
8735        } catch (IOException e) {
8736            Slog.wtf(TAG, "Failed reading Uri grants", e);
8737        } catch (XmlPullParserException e) {
8738            Slog.wtf(TAG, "Failed reading Uri grants", e);
8739        } finally {
8740            IoUtils.closeQuietly(fis);
8741        }
8742    }
8743
8744    /**
8745     * @param uri This uri must NOT contain an embedded userId.
8746     * @param userId The userId in which the uri is to be resolved.
8747     */
8748    @Override
8749    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8750        enforceNotIsolatedCaller("takePersistableUriPermission");
8751
8752        Preconditions.checkFlagsArgument(modeFlags,
8753                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8754
8755        synchronized (this) {
8756            final int callingUid = Binder.getCallingUid();
8757            boolean persistChanged = false;
8758            GrantUri grantUri = new GrantUri(userId, uri, false);
8759
8760            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8761                    new GrantUri(userId, uri, false));
8762            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8763                    new GrantUri(userId, uri, true));
8764
8765            final boolean exactValid = (exactPerm != null)
8766                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8767            final boolean prefixValid = (prefixPerm != null)
8768                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8769
8770            if (!(exactValid || prefixValid)) {
8771                throw new SecurityException("No persistable permission grants found for UID "
8772                        + callingUid + " and Uri " + grantUri.toSafeString());
8773            }
8774
8775            if (exactValid) {
8776                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8777            }
8778            if (prefixValid) {
8779                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8780            }
8781
8782            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8783
8784            if (persistChanged) {
8785                schedulePersistUriGrants();
8786            }
8787        }
8788    }
8789
8790    /**
8791     * @param uri This uri must NOT contain an embedded userId.
8792     * @param userId The userId in which the uri is to be resolved.
8793     */
8794    @Override
8795    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8796        enforceNotIsolatedCaller("releasePersistableUriPermission");
8797
8798        Preconditions.checkFlagsArgument(modeFlags,
8799                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8800
8801        synchronized (this) {
8802            final int callingUid = Binder.getCallingUid();
8803            boolean persistChanged = false;
8804
8805            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8806                    new GrantUri(userId, uri, false));
8807            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8808                    new GrantUri(userId, uri, true));
8809            if (exactPerm == null && prefixPerm == null) {
8810                throw new SecurityException("No permission grants found for UID " + callingUid
8811                        + " and Uri " + uri.toSafeString());
8812            }
8813
8814            if (exactPerm != null) {
8815                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8816                removeUriPermissionIfNeededLocked(exactPerm);
8817            }
8818            if (prefixPerm != null) {
8819                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8820                removeUriPermissionIfNeededLocked(prefixPerm);
8821            }
8822
8823            if (persistChanged) {
8824                schedulePersistUriGrants();
8825            }
8826        }
8827    }
8828
8829    /**
8830     * Prune any older {@link UriPermission} for the given UID until outstanding
8831     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8832     *
8833     * @return if any mutations occured that require persisting.
8834     */
8835    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8836        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8837        if (perms == null) return false;
8838        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8839
8840        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8841        for (UriPermission perm : perms.values()) {
8842            if (perm.persistedModeFlags != 0) {
8843                persisted.add(perm);
8844            }
8845        }
8846
8847        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8848        if (trimCount <= 0) return false;
8849
8850        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8851        for (int i = 0; i < trimCount; i++) {
8852            final UriPermission perm = persisted.get(i);
8853
8854            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8855                    "Trimming grant created at " + perm.persistedCreateTime);
8856
8857            perm.releasePersistableModes(~0);
8858            removeUriPermissionIfNeededLocked(perm);
8859        }
8860
8861        return true;
8862    }
8863
8864    @Override
8865    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8866            String packageName, boolean incoming) {
8867        enforceNotIsolatedCaller("getPersistedUriPermissions");
8868        Preconditions.checkNotNull(packageName, "packageName");
8869
8870        final int callingUid = Binder.getCallingUid();
8871        final int callingUserId = UserHandle.getUserId(callingUid);
8872        final IPackageManager pm = AppGlobals.getPackageManager();
8873        try {
8874            final int packageUid = pm.getPackageUid(packageName,
8875                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8876            if (packageUid != callingUid) {
8877                throw new SecurityException(
8878                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8879            }
8880        } catch (RemoteException e) {
8881            throw new SecurityException("Failed to verify package name ownership");
8882        }
8883
8884        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8885        synchronized (this) {
8886            if (incoming) {
8887                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8888                        callingUid);
8889                if (perms == null) {
8890                    Slog.w(TAG, "No permission grants found for " + packageName);
8891                } else {
8892                    for (UriPermission perm : perms.values()) {
8893                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8894                            result.add(perm.buildPersistedPublicApiObject());
8895                        }
8896                    }
8897                }
8898            } else {
8899                final int size = mGrantedUriPermissions.size();
8900                for (int i = 0; i < size; i++) {
8901                    final ArrayMap<GrantUri, UriPermission> perms =
8902                            mGrantedUriPermissions.valueAt(i);
8903                    for (UriPermission perm : perms.values()) {
8904                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8905                            result.add(perm.buildPersistedPublicApiObject());
8906                        }
8907                    }
8908                }
8909            }
8910        }
8911        return new ParceledListSlice<android.content.UriPermission>(result);
8912    }
8913
8914    @Override
8915    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8916            String packageName, int userId) {
8917        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8918                "getGrantedUriPermissions");
8919
8920        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8921        synchronized (this) {
8922            final int size = mGrantedUriPermissions.size();
8923            for (int i = 0; i < size; i++) {
8924                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8925                for (UriPermission perm : perms.values()) {
8926                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8927                            && perm.persistedModeFlags != 0) {
8928                        result.add(perm.buildPersistedPublicApiObject());
8929                    }
8930                }
8931            }
8932        }
8933        return new ParceledListSlice<android.content.UriPermission>(result);
8934    }
8935
8936    @Override
8937    public void clearGrantedUriPermissions(String packageName, int userId) {
8938        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8939                "clearGrantedUriPermissions");
8940        removeUriPermissionsForPackageLocked(packageName, userId, true);
8941    }
8942
8943    @Override
8944    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8945        synchronized (this) {
8946            ProcessRecord app =
8947                who != null ? getRecordForAppLocked(who) : null;
8948            if (app == null) return;
8949
8950            Message msg = Message.obtain();
8951            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8952            msg.obj = app;
8953            msg.arg1 = waiting ? 1 : 0;
8954            mUiHandler.sendMessage(msg);
8955        }
8956    }
8957
8958    @Override
8959    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8960        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8961        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8962        outInfo.availMem = Process.getFreeMemory();
8963        outInfo.totalMem = Process.getTotalMemory();
8964        outInfo.threshold = homeAppMem;
8965        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8966        outInfo.hiddenAppThreshold = cachedAppMem;
8967        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8968                ProcessList.SERVICE_ADJ);
8969        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8970                ProcessList.VISIBLE_APP_ADJ);
8971        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8972                ProcessList.FOREGROUND_APP_ADJ);
8973    }
8974
8975    // =========================================================
8976    // TASK MANAGEMENT
8977    // =========================================================
8978
8979    @Override
8980    public List<IAppTask> getAppTasks(String callingPackage) {
8981        int callingUid = Binder.getCallingUid();
8982        long ident = Binder.clearCallingIdentity();
8983
8984        synchronized(this) {
8985            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8986            try {
8987                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8988
8989                final int N = mRecentTasks.size();
8990                for (int i = 0; i < N; i++) {
8991                    TaskRecord tr = mRecentTasks.get(i);
8992                    // Skip tasks that do not match the caller.  We don't need to verify
8993                    // callingPackage, because we are also limiting to callingUid and know
8994                    // that will limit to the correct security sandbox.
8995                    if (tr.effectiveUid != callingUid) {
8996                        continue;
8997                    }
8998                    Intent intent = tr.getBaseIntent();
8999                    if (intent == null ||
9000                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9001                        continue;
9002                    }
9003                    ActivityManager.RecentTaskInfo taskInfo =
9004                            createRecentTaskInfoFromTaskRecord(tr);
9005                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9006                    list.add(taskImpl);
9007                }
9008            } finally {
9009                Binder.restoreCallingIdentity(ident);
9010            }
9011            return list;
9012        }
9013    }
9014
9015    @Override
9016    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9017        final int callingUid = Binder.getCallingUid();
9018        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9019
9020        synchronized(this) {
9021            if (DEBUG_ALL) Slog.v(
9022                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9023
9024            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9025                    callingUid);
9026
9027            // TODO: Improve with MRU list from all ActivityStacks.
9028            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9029        }
9030
9031        return list;
9032    }
9033
9034    /**
9035     * Creates a new RecentTaskInfo from a TaskRecord.
9036     */
9037    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9038        // Update the task description to reflect any changes in the task stack
9039        tr.updateTaskDescription();
9040
9041        // Compose the recent task info
9042        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9043        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9044        rti.persistentId = tr.taskId;
9045        rti.baseIntent = new Intent(tr.getBaseIntent());
9046        rti.origActivity = tr.origActivity;
9047        rti.realActivity = tr.realActivity;
9048        rti.description = tr.lastDescription;
9049        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9050        rti.userId = tr.userId;
9051        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9052        rti.firstActiveTime = tr.firstActiveTime;
9053        rti.lastActiveTime = tr.lastActiveTime;
9054        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9055        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9056        rti.numActivities = 0;
9057        if (tr.mBounds != null) {
9058            rti.bounds = new Rect(tr.mBounds);
9059        }
9060        rti.isDockable = tr.canGoInDockedStack();
9061        rti.resizeMode = tr.mResizeMode;
9062
9063        ActivityRecord base = null;
9064        ActivityRecord top = null;
9065        ActivityRecord tmp;
9066
9067        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9068            tmp = tr.mActivities.get(i);
9069            if (tmp.finishing) {
9070                continue;
9071            }
9072            base = tmp;
9073            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9074                top = base;
9075            }
9076            rti.numActivities++;
9077        }
9078
9079        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9080        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9081
9082        return rti;
9083    }
9084
9085    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9086        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9087                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9088        if (!allowed) {
9089            if (checkPermission(android.Manifest.permission.GET_TASKS,
9090                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9091                // Temporary compatibility: some existing apps on the system image may
9092                // still be requesting the old permission and not switched to the new
9093                // one; if so, we'll still allow them full access.  This means we need
9094                // to see if they are holding the old permission and are a system app.
9095                try {
9096                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9097                        allowed = true;
9098                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9099                                + " is using old GET_TASKS but privileged; allowing");
9100                    }
9101                } catch (RemoteException e) {
9102                }
9103            }
9104        }
9105        if (!allowed) {
9106            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9107                    + " does not hold REAL_GET_TASKS; limiting output");
9108        }
9109        return allowed;
9110    }
9111
9112    @Override
9113    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9114            int userId) {
9115        final int callingUid = Binder.getCallingUid();
9116        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9117                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9118
9119        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9120        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9121        synchronized (this) {
9122            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9123                    callingUid);
9124            final boolean detailed = checkCallingPermission(
9125                    android.Manifest.permission.GET_DETAILED_TASKS)
9126                    == PackageManager.PERMISSION_GRANTED;
9127
9128            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9129                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9130                return ParceledListSlice.emptyList();
9131            }
9132            mRecentTasks.loadUserRecentsLocked(userId);
9133
9134            final int recentsCount = mRecentTasks.size();
9135            ArrayList<ActivityManager.RecentTaskInfo> res =
9136                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9137
9138            final Set<Integer> includedUsers;
9139            if (includeProfiles) {
9140                includedUsers = mUserController.getProfileIds(userId);
9141            } else {
9142                includedUsers = new HashSet<>();
9143            }
9144            includedUsers.add(Integer.valueOf(userId));
9145
9146            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9147                TaskRecord tr = mRecentTasks.get(i);
9148                // Only add calling user or related users recent tasks
9149                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9150                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9151                    continue;
9152                }
9153
9154                if (tr.realActivitySuspended) {
9155                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9156                    continue;
9157                }
9158
9159                // Return the entry if desired by the caller.  We always return
9160                // the first entry, because callers always expect this to be the
9161                // foreground app.  We may filter others if the caller has
9162                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9163                // we should exclude the entry.
9164
9165                if (i == 0
9166                        || withExcluded
9167                        || (tr.intent == null)
9168                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9169                                == 0)) {
9170                    if (!allowed) {
9171                        // If the caller doesn't have the GET_TASKS permission, then only
9172                        // allow them to see a small subset of tasks -- their own and home.
9173                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9174                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9175                            continue;
9176                        }
9177                    }
9178                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9179                        if (tr.stack != null && tr.stack.isHomeStack()) {
9180                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9181                                    "Skipping, home stack task: " + tr);
9182                            continue;
9183                        }
9184                    }
9185                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9186                        final ActivityStack stack = tr.stack;
9187                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9188                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9189                                    "Skipping, top task in docked stack: " + tr);
9190                            continue;
9191                        }
9192                    }
9193                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9194                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9195                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9196                                    "Skipping, pinned stack task: " + tr);
9197                            continue;
9198                        }
9199                    }
9200                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9201                        // Don't include auto remove tasks that are finished or finishing.
9202                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9203                                "Skipping, auto-remove without activity: " + tr);
9204                        continue;
9205                    }
9206                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9207                            && !tr.isAvailable) {
9208                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9209                                "Skipping, unavail real act: " + tr);
9210                        continue;
9211                    }
9212
9213                    if (!tr.mUserSetupComplete) {
9214                        // Don't include task launched while user is not done setting-up.
9215                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9216                                "Skipping, user setup not complete: " + tr);
9217                        continue;
9218                    }
9219
9220                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9221                    if (!detailed) {
9222                        rti.baseIntent.replaceExtras((Bundle)null);
9223                    }
9224
9225                    res.add(rti);
9226                    maxNum--;
9227                }
9228            }
9229            return new ParceledListSlice<>(res);
9230        }
9231    }
9232
9233    @Override
9234    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9235        synchronized (this) {
9236            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9237                    "getTaskThumbnail()");
9238            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9239                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9240            if (tr != null) {
9241                return tr.getTaskThumbnailLocked();
9242            }
9243        }
9244        return null;
9245    }
9246
9247    @Override
9248    public int addAppTask(IBinder activityToken, Intent intent,
9249            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9250        final int callingUid = Binder.getCallingUid();
9251        final long callingIdent = Binder.clearCallingIdentity();
9252
9253        try {
9254            synchronized (this) {
9255                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9256                if (r == null) {
9257                    throw new IllegalArgumentException("Activity does not exist; token="
9258                            + activityToken);
9259                }
9260                ComponentName comp = intent.getComponent();
9261                if (comp == null) {
9262                    throw new IllegalArgumentException("Intent " + intent
9263                            + " must specify explicit component");
9264                }
9265                if (thumbnail.getWidth() != mThumbnailWidth
9266                        || thumbnail.getHeight() != mThumbnailHeight) {
9267                    throw new IllegalArgumentException("Bad thumbnail size: got "
9268                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9269                            + mThumbnailWidth + "x" + mThumbnailHeight);
9270                }
9271                if (intent.getSelector() != null) {
9272                    intent.setSelector(null);
9273                }
9274                if (intent.getSourceBounds() != null) {
9275                    intent.setSourceBounds(null);
9276                }
9277                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9278                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9279                        // The caller has added this as an auto-remove task...  that makes no
9280                        // sense, so turn off auto-remove.
9281                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9282                    }
9283                }
9284                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9285                    mLastAddedTaskActivity = null;
9286                }
9287                ActivityInfo ainfo = mLastAddedTaskActivity;
9288                if (ainfo == null) {
9289                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9290                            comp, 0, UserHandle.getUserId(callingUid));
9291                    if (ainfo.applicationInfo.uid != callingUid) {
9292                        throw new SecurityException(
9293                                "Can't add task for another application: target uid="
9294                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9295                    }
9296                }
9297
9298                // Use the full screen as the context for the task thumbnail
9299                final Point displaySize = new Point();
9300                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9301                r.task.stack.getDisplaySize(displaySize);
9302                thumbnailInfo.taskWidth = displaySize.x;
9303                thumbnailInfo.taskHeight = displaySize.y;
9304                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9305
9306                TaskRecord task = new TaskRecord(this,
9307                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9308                        ainfo, intent, description, thumbnailInfo);
9309
9310                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9311                if (trimIdx >= 0) {
9312                    // If this would have caused a trim, then we'll abort because that
9313                    // means it would be added at the end of the list but then just removed.
9314                    return INVALID_TASK_ID;
9315                }
9316
9317                final int N = mRecentTasks.size();
9318                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9319                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9320                    tr.removedFromRecents();
9321                }
9322
9323                task.inRecents = true;
9324                mRecentTasks.add(task);
9325                r.task.stack.addTask(task, false, "addAppTask");
9326
9327                task.setLastThumbnailLocked(thumbnail);
9328                task.freeLastThumbnail();
9329
9330                return task.taskId;
9331            }
9332        } finally {
9333            Binder.restoreCallingIdentity(callingIdent);
9334        }
9335    }
9336
9337    @Override
9338    public Point getAppTaskThumbnailSize() {
9339        synchronized (this) {
9340            return new Point(mThumbnailWidth,  mThumbnailHeight);
9341        }
9342    }
9343
9344    @Override
9345    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9346        synchronized (this) {
9347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9348            if (r != null) {
9349                r.setTaskDescription(td);
9350                r.task.updateTaskDescription();
9351            }
9352        }
9353    }
9354
9355    @Override
9356    public void setTaskResizeable(int taskId, int resizeableMode) {
9357        synchronized (this) {
9358            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9359                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9360            if (task == null) {
9361                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9362                return;
9363            }
9364            if (task.mResizeMode != resizeableMode) {
9365                task.mResizeMode = resizeableMode;
9366                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9367                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9368                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9369            }
9370        }
9371    }
9372
9373    @Override
9374    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9375        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9376        long ident = Binder.clearCallingIdentity();
9377        try {
9378            synchronized (this) {
9379                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9380                if (task == null) {
9381                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9382                    return;
9383                }
9384                int stackId = task.stack.mStackId;
9385                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9386                // in crop windows resize mode or if the task size is affected by the docked stack
9387                // changing size. No need to update configuration.
9388                if (bounds != null && task.inCropWindowsResizeMode()
9389                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9390                    mWindowManager.scrollTask(task.taskId, bounds);
9391                    return;
9392                }
9393
9394                // Place the task in the right stack if it isn't there already based on
9395                // the requested bounds.
9396                // The stack transition logic is:
9397                // - a null bounds on a freeform task moves that task to fullscreen
9398                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9399                //   that task to freeform
9400                // - otherwise the task is not moved
9401                if (!StackId.isTaskResizeAllowed(stackId)) {
9402                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9403                }
9404                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9405                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9406                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9407                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9408                }
9409                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9410                if (stackId != task.stack.mStackId) {
9411                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9412                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9413                    preserveWindow = false;
9414                }
9415
9416                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9417                        false /* deferResume */);
9418            }
9419        } finally {
9420            Binder.restoreCallingIdentity(ident);
9421        }
9422    }
9423
9424    @Override
9425    public Rect getTaskBounds(int taskId) {
9426        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9427        long ident = Binder.clearCallingIdentity();
9428        Rect rect = new Rect();
9429        try {
9430            synchronized (this) {
9431                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9432                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9433                if (task == null) {
9434                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9435                    return rect;
9436                }
9437                if (task.stack != null) {
9438                    // Return the bounds from window manager since it will be adjusted for various
9439                    // things like the presense of a docked stack for tasks that aren't resizeable.
9440                    mWindowManager.getTaskBounds(task.taskId, rect);
9441                } else {
9442                    // Task isn't in window manager yet since it isn't associated with a stack.
9443                    // Return the persist value from activity manager
9444                    if (task.mBounds != null) {
9445                        rect.set(task.mBounds);
9446                    } else if (task.mLastNonFullscreenBounds != null) {
9447                        rect.set(task.mLastNonFullscreenBounds);
9448                    }
9449                }
9450            }
9451        } finally {
9452            Binder.restoreCallingIdentity(ident);
9453        }
9454        return rect;
9455    }
9456
9457    @Override
9458    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9459        if (userId != UserHandle.getCallingUserId()) {
9460            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9461                    "getTaskDescriptionIcon");
9462        }
9463        final File passedIconFile = new File(filePath);
9464        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9465                passedIconFile.getName());
9466        if (!legitIconFile.getPath().equals(filePath)
9467                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9468            throw new IllegalArgumentException("Bad file path: " + filePath
9469                    + " passed for userId " + userId);
9470        }
9471        return mRecentTasks.getTaskDescriptionIcon(filePath);
9472    }
9473
9474    @Override
9475    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9476            throws RemoteException {
9477        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9478                opts.getCustomInPlaceResId() == 0) {
9479            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9480                    "with valid animation");
9481        }
9482        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9483        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9484                opts.getCustomInPlaceResId());
9485        mWindowManager.executeAppTransition();
9486    }
9487
9488    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9489            boolean removeFromRecents) {
9490        if (removeFromRecents) {
9491            mRecentTasks.remove(tr);
9492            tr.removedFromRecents();
9493        }
9494        ComponentName component = tr.getBaseIntent().getComponent();
9495        if (component == null) {
9496            Slog.w(TAG, "No component for base intent of task: " + tr);
9497            return;
9498        }
9499
9500        // Find any running services associated with this app and stop if needed.
9501        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9502
9503        if (!killProcess) {
9504            return;
9505        }
9506
9507        // Determine if the process(es) for this task should be killed.
9508        final String pkg = component.getPackageName();
9509        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9510        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9511        for (int i = 0; i < pmap.size(); i++) {
9512
9513            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9514            for (int j = 0; j < uids.size(); j++) {
9515                ProcessRecord proc = uids.valueAt(j);
9516                if (proc.userId != tr.userId) {
9517                    // Don't kill process for a different user.
9518                    continue;
9519                }
9520                if (proc == mHomeProcess) {
9521                    // Don't kill the home process along with tasks from the same package.
9522                    continue;
9523                }
9524                if (!proc.pkgList.containsKey(pkg)) {
9525                    // Don't kill process that is not associated with this task.
9526                    continue;
9527                }
9528
9529                for (int k = 0; k < proc.activities.size(); k++) {
9530                    TaskRecord otherTask = proc.activities.get(k).task;
9531                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9532                        // Don't kill process(es) that has an activity in a different task that is
9533                        // also in recents.
9534                        return;
9535                    }
9536                }
9537
9538                if (proc.foregroundServices) {
9539                    // Don't kill process(es) with foreground service.
9540                    return;
9541                }
9542
9543                // Add process to kill list.
9544                procsToKill.add(proc);
9545            }
9546        }
9547
9548        // Kill the running processes.
9549        for (int i = 0; i < procsToKill.size(); i++) {
9550            ProcessRecord pr = procsToKill.get(i);
9551            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9552                    && pr.curReceiver == null) {
9553                pr.kill("remove task", true);
9554            } else {
9555                // We delay killing processes that are not in the background or running a receiver.
9556                pr.waitingToKill = "remove task";
9557            }
9558        }
9559    }
9560
9561    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9562        // Remove all tasks with activities in the specified package from the list of recent tasks
9563        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9564            TaskRecord tr = mRecentTasks.get(i);
9565            if (tr.userId != userId) continue;
9566
9567            ComponentName cn = tr.intent.getComponent();
9568            if (cn != null && cn.getPackageName().equals(packageName)) {
9569                // If the package name matches, remove the task.
9570                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9571            }
9572        }
9573    }
9574
9575    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9576            int userId) {
9577
9578        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9579            TaskRecord tr = mRecentTasks.get(i);
9580            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9581                continue;
9582            }
9583
9584            ComponentName cn = tr.intent.getComponent();
9585            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9586                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9587            if (sameComponent) {
9588                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9589            }
9590        }
9591    }
9592
9593    /**
9594     * Removes the task with the specified task id.
9595     *
9596     * @param taskId Identifier of the task to be removed.
9597     * @param killProcess Kill any process associated with the task if possible.
9598     * @param removeFromRecents Whether to also remove the task from recents.
9599     * @return Returns true if the given task was found and removed.
9600     */
9601    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9602            boolean removeFromRecents) {
9603        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9604                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9605        if (tr != null) {
9606            tr.removeTaskActivitiesLocked();
9607            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9608            if (tr.isPersistable) {
9609                notifyTaskPersisterLocked(null, true);
9610            }
9611            return true;
9612        }
9613        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9614        return false;
9615    }
9616
9617    @Override
9618    public void removeStack(int stackId) {
9619        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9620        if (stackId == HOME_STACK_ID) {
9621            throw new IllegalArgumentException("Removing home stack is not allowed.");
9622        }
9623
9624        synchronized (this) {
9625            final long ident = Binder.clearCallingIdentity();
9626            try {
9627                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9628                if (stack == null) {
9629                    return;
9630                }
9631                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9632                for (int i = tasks.size() - 1; i >= 0; i--) {
9633                    removeTaskByIdLocked(
9634                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9635                }
9636            } finally {
9637                Binder.restoreCallingIdentity(ident);
9638            }
9639        }
9640    }
9641
9642    @Override
9643    public boolean removeTask(int taskId) {
9644        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9645        synchronized (this) {
9646            final long ident = Binder.clearCallingIdentity();
9647            try {
9648                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9649            } finally {
9650                Binder.restoreCallingIdentity(ident);
9651            }
9652        }
9653    }
9654
9655    /**
9656     * TODO: Add mController hook
9657     */
9658    @Override
9659    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9660        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9661
9662        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9663        synchronized(this) {
9664            moveTaskToFrontLocked(taskId, flags, bOptions);
9665        }
9666    }
9667
9668    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9669        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9670
9671        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9672                Binder.getCallingUid(), -1, -1, "Task to front")) {
9673            ActivityOptions.abort(options);
9674            return;
9675        }
9676        final long origId = Binder.clearCallingIdentity();
9677        try {
9678            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9679            if (task == null) {
9680                Slog.d(TAG, "Could not find task for id: "+ taskId);
9681                return;
9682            }
9683            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9684                mStackSupervisor.showLockTaskToast();
9685                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9686                return;
9687            }
9688            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9689            if (prev != null && prev.isRecentsActivity()) {
9690                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9691            }
9692            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9693                    false /* forceNonResizable */);
9694        } finally {
9695            Binder.restoreCallingIdentity(origId);
9696        }
9697        ActivityOptions.abort(options);
9698    }
9699
9700    /**
9701     * Moves an activity, and all of the other activities within the same task, to the bottom
9702     * of the history stack.  The activity's order within the task is unchanged.
9703     *
9704     * @param token A reference to the activity we wish to move
9705     * @param nonRoot If false then this only works if the activity is the root
9706     *                of a task; if true it will work for any activity in a task.
9707     * @return Returns true if the move completed, false if not.
9708     */
9709    @Override
9710    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9711        enforceNotIsolatedCaller("moveActivityTaskToBack");
9712        synchronized(this) {
9713            final long origId = Binder.clearCallingIdentity();
9714            try {
9715                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9716                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9717                if (task != null) {
9718                    if (mStackSupervisor.isLockedTask(task)) {
9719                        mStackSupervisor.showLockTaskToast();
9720                        return false;
9721                    }
9722                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9723                }
9724            } finally {
9725                Binder.restoreCallingIdentity(origId);
9726            }
9727        }
9728        return false;
9729    }
9730
9731    @Override
9732    public void moveTaskBackwards(int task) {
9733        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9734                "moveTaskBackwards()");
9735
9736        synchronized(this) {
9737            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9738                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9739                return;
9740            }
9741            final long origId = Binder.clearCallingIdentity();
9742            moveTaskBackwardsLocked(task);
9743            Binder.restoreCallingIdentity(origId);
9744        }
9745    }
9746
9747    private final void moveTaskBackwardsLocked(int task) {
9748        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9749    }
9750
9751    @Override
9752    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9753            IActivityContainerCallback callback) throws RemoteException {
9754        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9755        synchronized (this) {
9756            if (parentActivityToken == null) {
9757                throw new IllegalArgumentException("parent token must not be null");
9758            }
9759            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9760            if (r == null) {
9761                return null;
9762            }
9763            if (callback == null) {
9764                throw new IllegalArgumentException("callback must not be null");
9765            }
9766            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9767        }
9768    }
9769
9770    @Override
9771    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9772        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9773        synchronized (this) {
9774            mStackSupervisor.deleteActivityContainer(container);
9775        }
9776    }
9777
9778    @Override
9779    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9780        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9781        synchronized (this) {
9782            final int stackId = mStackSupervisor.getNextStackId();
9783            final ActivityStack stack =
9784                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9785            if (stack == null) {
9786                return null;
9787            }
9788            return stack.mActivityContainer;
9789        }
9790    }
9791
9792    @Override
9793    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9794        synchronized (this) {
9795            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9796            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9797                return stack.mActivityContainer.getDisplayId();
9798            }
9799            return Display.DEFAULT_DISPLAY;
9800        }
9801    }
9802
9803    @Override
9804    public int getActivityStackId(IBinder token) throws RemoteException {
9805        synchronized (this) {
9806            ActivityStack stack = ActivityRecord.getStackLocked(token);
9807            if (stack == null) {
9808                return INVALID_STACK_ID;
9809            }
9810            return stack.mStackId;
9811        }
9812    }
9813
9814    @Override
9815    public void exitFreeformMode(IBinder token) throws RemoteException {
9816        synchronized (this) {
9817            long ident = Binder.clearCallingIdentity();
9818            try {
9819                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9820                if (r == null) {
9821                    throw new IllegalArgumentException(
9822                            "exitFreeformMode: No activity record matching token=" + token);
9823                }
9824                final ActivityStack stack = r.getStackLocked(token);
9825                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9826                    throw new IllegalStateException(
9827                            "exitFreeformMode: You can only go fullscreen from freeform.");
9828                }
9829                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9830                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9831                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9832            } finally {
9833                Binder.restoreCallingIdentity(ident);
9834            }
9835        }
9836    }
9837
9838    @Override
9839    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9840        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9841        if (stackId == HOME_STACK_ID) {
9842            throw new IllegalArgumentException(
9843                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9844        }
9845        synchronized (this) {
9846            long ident = Binder.clearCallingIdentity();
9847            try {
9848                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9849                        + " to stackId=" + stackId + " toTop=" + toTop);
9850                if (stackId == DOCKED_STACK_ID) {
9851                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9852                            null /* initialBounds */);
9853                }
9854                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9855                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9856                if (result && stackId == DOCKED_STACK_ID) {
9857                    // If task moved to docked stack - show recents if needed.
9858                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9859                            "moveTaskToDockedStack");
9860                }
9861            } finally {
9862                Binder.restoreCallingIdentity(ident);
9863            }
9864        }
9865    }
9866
9867    @Override
9868    public void swapDockedAndFullscreenStack() throws RemoteException {
9869        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9870        synchronized (this) {
9871            long ident = Binder.clearCallingIdentity();
9872            try {
9873                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9874                        FULLSCREEN_WORKSPACE_STACK_ID);
9875                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9876                        : null;
9877                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9878                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9879                        : null;
9880                if (topTask == null || tasks == null || tasks.size() == 0) {
9881                    Slog.w(TAG,
9882                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9883                    return;
9884                }
9885
9886                // TODO: App transition
9887                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9888
9889                // Defer the resume so resume/pausing while moving stacks is dangerous.
9890                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9891                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9892                        ANIMATE, true /* deferResume */);
9893                final int size = tasks.size();
9894                for (int i = 0; i < size; i++) {
9895                    final int id = tasks.get(i).taskId;
9896                    if (id == topTask.taskId) {
9897                        continue;
9898                    }
9899                    mStackSupervisor.moveTaskToStackLocked(id,
9900                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9901                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9902                }
9903
9904                // Because we deferred the resume, to avoid conflicts with stack switches while
9905                // resuming, we need to do it after all the tasks are moved.
9906                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9907                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9908
9909                mWindowManager.executeAppTransition();
9910            } finally {
9911                Binder.restoreCallingIdentity(ident);
9912            }
9913        }
9914    }
9915
9916    /**
9917     * Moves the input task to the docked stack.
9918     *
9919     * @param taskId Id of task to move.
9920     * @param createMode The mode the docked stack should be created in if it doesn't exist
9921     *                   already. See
9922     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9923     *                   and
9924     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9925     * @param toTop If the task and stack should be moved to the top.
9926     * @param animate Whether we should play an animation for the moving the task
9927     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9928     *                      docked stack. Pass {@code null} to use default bounds.
9929     */
9930    @Override
9931    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9932            Rect initialBounds, boolean moveHomeStackFront) {
9933        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9934        synchronized (this) {
9935            long ident = Binder.clearCallingIdentity();
9936            try {
9937                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9938                        + " to createMode=" + createMode + " toTop=" + toTop);
9939                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9940                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9941                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9942                        animate, DEFER_RESUME);
9943                if (moved) {
9944                    if (moveHomeStackFront) {
9945                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9946                    }
9947                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9948                }
9949                return moved;
9950            } finally {
9951                Binder.restoreCallingIdentity(ident);
9952            }
9953        }
9954    }
9955
9956    /**
9957     * Moves the top activity in the input stackId to the pinned stack.
9958     *
9959     * @param stackId Id of stack to move the top activity to pinned stack.
9960     * @param bounds Bounds to use for pinned stack.
9961     *
9962     * @return True if the top activity of the input stack was successfully moved to the pinned
9963     *          stack.
9964     */
9965    @Override
9966    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9967        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9968        synchronized (this) {
9969            if (!mSupportsPictureInPicture) {
9970                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9971                        + "Device doesn't support picture-in-pciture mode");
9972            }
9973
9974            long ident = Binder.clearCallingIdentity();
9975            try {
9976                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9977            } finally {
9978                Binder.restoreCallingIdentity(ident);
9979            }
9980        }
9981    }
9982
9983    @Override
9984    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9985            boolean preserveWindows, boolean animate, int animationDuration) {
9986        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9987        long ident = Binder.clearCallingIdentity();
9988        try {
9989            synchronized (this) {
9990                if (animate) {
9991                    if (stackId == PINNED_STACK_ID) {
9992                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9993                    } else {
9994                        throw new IllegalArgumentException("Stack: " + stackId
9995                                + " doesn't support animated resize.");
9996                    }
9997                } else {
9998                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9999                            null /* tempTaskInsetBounds */, preserveWindows,
10000                            allowResizeInDockedMode, !DEFER_RESUME);
10001                }
10002            }
10003        } finally {
10004            Binder.restoreCallingIdentity(ident);
10005        }
10006    }
10007
10008    @Override
10009    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10010            Rect tempDockedTaskInsetBounds,
10011            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10012        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10013                "resizeDockedStack()");
10014        long ident = Binder.clearCallingIdentity();
10015        try {
10016            synchronized (this) {
10017                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10018                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10019                        PRESERVE_WINDOWS);
10020            }
10021        } finally {
10022            Binder.restoreCallingIdentity(ident);
10023        }
10024    }
10025
10026    @Override
10027    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10028        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10029                "resizePinnedStack()");
10030        final long ident = Binder.clearCallingIdentity();
10031        try {
10032            synchronized (this) {
10033                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10034            }
10035        } finally {
10036            Binder.restoreCallingIdentity(ident);
10037        }
10038    }
10039
10040    @Override
10041    public void positionTaskInStack(int taskId, int stackId, int position) {
10042        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10043        if (stackId == HOME_STACK_ID) {
10044            throw new IllegalArgumentException(
10045                    "positionTaskInStack: Attempt to change the position of task "
10046                    + taskId + " in/to home stack");
10047        }
10048        synchronized (this) {
10049            long ident = Binder.clearCallingIdentity();
10050            try {
10051                if (DEBUG_STACK) Slog.d(TAG_STACK,
10052                        "positionTaskInStack: positioning task=" + taskId
10053                        + " in stackId=" + stackId + " at position=" + position);
10054                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10055            } finally {
10056                Binder.restoreCallingIdentity(ident);
10057            }
10058        }
10059    }
10060
10061    @Override
10062    public List<StackInfo> getAllStackInfos() {
10063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10064        long ident = Binder.clearCallingIdentity();
10065        try {
10066            synchronized (this) {
10067                return mStackSupervisor.getAllStackInfosLocked();
10068            }
10069        } finally {
10070            Binder.restoreCallingIdentity(ident);
10071        }
10072    }
10073
10074    @Override
10075    public StackInfo getStackInfo(int stackId) {
10076        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10077        long ident = Binder.clearCallingIdentity();
10078        try {
10079            synchronized (this) {
10080                return mStackSupervisor.getStackInfoLocked(stackId);
10081            }
10082        } finally {
10083            Binder.restoreCallingIdentity(ident);
10084        }
10085    }
10086
10087    @Override
10088    public boolean isInHomeStack(int taskId) {
10089        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10090        long ident = Binder.clearCallingIdentity();
10091        try {
10092            synchronized (this) {
10093                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10094                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10095                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10096            }
10097        } finally {
10098            Binder.restoreCallingIdentity(ident);
10099        }
10100    }
10101
10102    @Override
10103    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10104        synchronized(this) {
10105            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10106        }
10107    }
10108
10109    @Override
10110    public void updateDeviceOwner(String packageName) {
10111        final int callingUid = Binder.getCallingUid();
10112        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10113            throw new SecurityException("updateDeviceOwner called from non-system process");
10114        }
10115        synchronized (this) {
10116            mDeviceOwnerName = packageName;
10117        }
10118    }
10119
10120    @Override
10121    public void updateLockTaskPackages(int userId, String[] packages) {
10122        final int callingUid = Binder.getCallingUid();
10123        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10124            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10125                    "updateLockTaskPackages()");
10126        }
10127        synchronized (this) {
10128            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10129                    Arrays.toString(packages));
10130            mLockTaskPackages.put(userId, packages);
10131            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10132        }
10133    }
10134
10135
10136    void startLockTaskModeLocked(TaskRecord task) {
10137        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10138        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10139            return;
10140        }
10141
10142        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10143        // is initiated by system after the pinning request was shown and locked mode is initiated
10144        // by an authorized app directly
10145        final int callingUid = Binder.getCallingUid();
10146        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10147        long ident = Binder.clearCallingIdentity();
10148        try {
10149            if (!isSystemInitiated) {
10150                task.mLockTaskUid = callingUid;
10151                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10152                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10153                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10154                    StatusBarManagerInternal statusBarManager =
10155                            LocalServices.getService(StatusBarManagerInternal.class);
10156                    if (statusBarManager != null) {
10157                        statusBarManager.showScreenPinningRequest(task.taskId);
10158                    }
10159                    return;
10160                }
10161
10162                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10163                if (stack == null || task != stack.topTask()) {
10164                    throw new IllegalArgumentException("Invalid task, not in foreground");
10165                }
10166            }
10167            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10168                    "Locking fully");
10169            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10170                    ActivityManager.LOCK_TASK_MODE_PINNED :
10171                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10172                    "startLockTask", true);
10173        } finally {
10174            Binder.restoreCallingIdentity(ident);
10175        }
10176    }
10177
10178    @Override
10179    public void startLockTaskMode(int taskId) {
10180        synchronized (this) {
10181            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10182            if (task != null) {
10183                startLockTaskModeLocked(task);
10184            }
10185        }
10186    }
10187
10188    @Override
10189    public void startLockTaskMode(IBinder token) {
10190        synchronized (this) {
10191            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10192            if (r == null) {
10193                return;
10194            }
10195            final TaskRecord task = r.task;
10196            if (task != null) {
10197                startLockTaskModeLocked(task);
10198            }
10199        }
10200    }
10201
10202    @Override
10203    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10204        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10205        // This makes inner call to look as if it was initiated by system.
10206        long ident = Binder.clearCallingIdentity();
10207        try {
10208            synchronized (this) {
10209                startLockTaskMode(taskId);
10210            }
10211        } finally {
10212            Binder.restoreCallingIdentity(ident);
10213        }
10214    }
10215
10216    @Override
10217    public void stopLockTaskMode() {
10218        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10219        if (lockTask == null) {
10220            // Our work here is done.
10221            return;
10222        }
10223
10224        final int callingUid = Binder.getCallingUid();
10225        final int lockTaskUid = lockTask.mLockTaskUid;
10226        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10227        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10228            // Done.
10229            return;
10230        } else {
10231            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10232            // It is possible lockTaskMode was started by the system process because
10233            // android:lockTaskMode is set to a locking value in the application manifest
10234            // instead of the app calling startLockTaskMode. In this case
10235            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10236            // {@link TaskRecord.effectiveUid} instead. Also caller with
10237            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10238            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10239                    && callingUid != lockTaskUid
10240                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10241                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10242                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10243            }
10244        }
10245        long ident = Binder.clearCallingIdentity();
10246        try {
10247            Log.d(TAG, "stopLockTaskMode");
10248            // Stop lock task
10249            synchronized (this) {
10250                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10251                        "stopLockTask", true);
10252            }
10253            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10254            if (tm != null) {
10255                tm.showInCallScreen(false);
10256            }
10257        } finally {
10258            Binder.restoreCallingIdentity(ident);
10259        }
10260    }
10261
10262    /**
10263     * This API should be called by SystemUI only when user perform certain action to dismiss
10264     * lock task mode. We should only dismiss pinned lock task mode in this case.
10265     */
10266    @Override
10267    public void stopSystemLockTaskMode() throws RemoteException {
10268        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10269            stopLockTaskMode();
10270        } else {
10271            mStackSupervisor.showLockTaskToast();
10272        }
10273    }
10274
10275    @Override
10276    public boolean isInLockTaskMode() {
10277        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10278    }
10279
10280    @Override
10281    public int getLockTaskModeState() {
10282        synchronized (this) {
10283            return mStackSupervisor.getLockTaskModeState();
10284        }
10285    }
10286
10287    @Override
10288    public void showLockTaskEscapeMessage(IBinder token) {
10289        synchronized (this) {
10290            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10291            if (r == null) {
10292                return;
10293            }
10294            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10295        }
10296    }
10297
10298    // =========================================================
10299    // CONTENT PROVIDERS
10300    // =========================================================
10301
10302    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10303        List<ProviderInfo> providers = null;
10304        try {
10305            providers = AppGlobals.getPackageManager()
10306                    .queryContentProviders(app.processName, app.uid,
10307                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10308                                    | MATCH_DEBUG_TRIAGED_MISSING)
10309                    .getList();
10310        } catch (RemoteException ex) {
10311        }
10312        if (DEBUG_MU) Slog.v(TAG_MU,
10313                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10314        int userId = app.userId;
10315        if (providers != null) {
10316            int N = providers.size();
10317            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10318            for (int i=0; i<N; i++) {
10319                // TODO: keep logic in sync with installEncryptionUnawareProviders
10320                ProviderInfo cpi =
10321                    (ProviderInfo)providers.get(i);
10322                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10323                        cpi.name, cpi.flags);
10324                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10325                    // This is a singleton provider, but a user besides the
10326                    // default user is asking to initialize a process it runs
10327                    // in...  well, no, it doesn't actually run in this process,
10328                    // it runs in the process of the default user.  Get rid of it.
10329                    providers.remove(i);
10330                    N--;
10331                    i--;
10332                    continue;
10333                }
10334
10335                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10336                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10337                if (cpr == null) {
10338                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10339                    mProviderMap.putProviderByClass(comp, cpr);
10340                }
10341                if (DEBUG_MU) Slog.v(TAG_MU,
10342                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10343                app.pubProviders.put(cpi.name, cpr);
10344                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10345                    // Don't add this if it is a platform component that is marked
10346                    // to run in multiple processes, because this is actually
10347                    // part of the framework so doesn't make sense to track as a
10348                    // separate apk in the process.
10349                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10350                            mProcessStats);
10351                }
10352                notifyPackageUse(cpi.applicationInfo.packageName,
10353                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10354            }
10355        }
10356        return providers;
10357    }
10358
10359    /**
10360     * Check if {@link ProcessRecord} has a possible chance at accessing the
10361     * given {@link ProviderInfo}. Final permission checking is always done
10362     * in {@link ContentProvider}.
10363     */
10364    private final String checkContentProviderPermissionLocked(
10365            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10366        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10367        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10368        boolean checkedGrants = false;
10369        if (checkUser) {
10370            // Looking for cross-user grants before enforcing the typical cross-users permissions
10371            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10372            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10373                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10374                    return null;
10375                }
10376                checkedGrants = true;
10377            }
10378            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10379                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10380            if (userId != tmpTargetUserId) {
10381                // When we actually went to determine the final targer user ID, this ended
10382                // up different than our initial check for the authority.  This is because
10383                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10384                // SELF.  So we need to re-check the grants again.
10385                checkedGrants = false;
10386            }
10387        }
10388        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10389                cpi.applicationInfo.uid, cpi.exported)
10390                == PackageManager.PERMISSION_GRANTED) {
10391            return null;
10392        }
10393        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10394                cpi.applicationInfo.uid, cpi.exported)
10395                == PackageManager.PERMISSION_GRANTED) {
10396            return null;
10397        }
10398
10399        PathPermission[] pps = cpi.pathPermissions;
10400        if (pps != null) {
10401            int i = pps.length;
10402            while (i > 0) {
10403                i--;
10404                PathPermission pp = pps[i];
10405                String pprperm = pp.getReadPermission();
10406                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10407                        cpi.applicationInfo.uid, cpi.exported)
10408                        == PackageManager.PERMISSION_GRANTED) {
10409                    return null;
10410                }
10411                String ppwperm = pp.getWritePermission();
10412                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10413                        cpi.applicationInfo.uid, cpi.exported)
10414                        == PackageManager.PERMISSION_GRANTED) {
10415                    return null;
10416                }
10417            }
10418        }
10419        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10420            return null;
10421        }
10422
10423        String msg;
10424        if (!cpi.exported) {
10425            msg = "Permission Denial: opening provider " + cpi.name
10426                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10427                    + ", uid=" + callingUid + ") that is not exported from uid "
10428                    + cpi.applicationInfo.uid;
10429        } else {
10430            msg = "Permission Denial: opening provider " + cpi.name
10431                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10432                    + ", uid=" + callingUid + ") requires "
10433                    + cpi.readPermission + " or " + cpi.writePermission;
10434        }
10435        Slog.w(TAG, msg);
10436        return msg;
10437    }
10438
10439    /**
10440     * Returns if the ContentProvider has granted a uri to callingUid
10441     */
10442    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10443        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10444        if (perms != null) {
10445            for (int i=perms.size()-1; i>=0; i--) {
10446                GrantUri grantUri = perms.keyAt(i);
10447                if (grantUri.sourceUserId == userId || !checkUser) {
10448                    if (matchesProvider(grantUri.uri, cpi)) {
10449                        return true;
10450                    }
10451                }
10452            }
10453        }
10454        return false;
10455    }
10456
10457    /**
10458     * Returns true if the uri authority is one of the authorities specified in the provider.
10459     */
10460    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10461        String uriAuth = uri.getAuthority();
10462        String cpiAuth = cpi.authority;
10463        if (cpiAuth.indexOf(';') == -1) {
10464            return cpiAuth.equals(uriAuth);
10465        }
10466        String[] cpiAuths = cpiAuth.split(";");
10467        int length = cpiAuths.length;
10468        for (int i = 0; i < length; i++) {
10469            if (cpiAuths[i].equals(uriAuth)) return true;
10470        }
10471        return false;
10472    }
10473
10474    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10475            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10476        if (r != null) {
10477            for (int i=0; i<r.conProviders.size(); i++) {
10478                ContentProviderConnection conn = r.conProviders.get(i);
10479                if (conn.provider == cpr) {
10480                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10481                            "Adding provider requested by "
10482                            + r.processName + " from process "
10483                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10484                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10485                    if (stable) {
10486                        conn.stableCount++;
10487                        conn.numStableIncs++;
10488                    } else {
10489                        conn.unstableCount++;
10490                        conn.numUnstableIncs++;
10491                    }
10492                    return conn;
10493                }
10494            }
10495            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10496            if (stable) {
10497                conn.stableCount = 1;
10498                conn.numStableIncs = 1;
10499            } else {
10500                conn.unstableCount = 1;
10501                conn.numUnstableIncs = 1;
10502            }
10503            cpr.connections.add(conn);
10504            r.conProviders.add(conn);
10505            startAssociationLocked(r.uid, r.processName, r.curProcState,
10506                    cpr.uid, cpr.name, cpr.info.processName);
10507            return conn;
10508        }
10509        cpr.addExternalProcessHandleLocked(externalProcessToken);
10510        return null;
10511    }
10512
10513    boolean decProviderCountLocked(ContentProviderConnection conn,
10514            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10515        if (conn != null) {
10516            cpr = conn.provider;
10517            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10518                    "Removing provider requested by "
10519                    + conn.client.processName + " from process "
10520                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10521                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10522            if (stable) {
10523                conn.stableCount--;
10524            } else {
10525                conn.unstableCount--;
10526            }
10527            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10528                cpr.connections.remove(conn);
10529                conn.client.conProviders.remove(conn);
10530                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10531                    // The client is more important than last activity -- note the time this
10532                    // is happening, so we keep the old provider process around a bit as last
10533                    // activity to avoid thrashing it.
10534                    if (cpr.proc != null) {
10535                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10536                    }
10537                }
10538                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10539                return true;
10540            }
10541            return false;
10542        }
10543        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10544        return false;
10545    }
10546
10547    private void checkTime(long startTime, String where) {
10548        long now = SystemClock.uptimeMillis();
10549        if ((now-startTime) > 50) {
10550            // If we are taking more than 50ms, log about it.
10551            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10552        }
10553    }
10554
10555    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10556            PROC_SPACE_TERM,
10557            PROC_SPACE_TERM|PROC_PARENS,
10558            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10559    };
10560
10561    private final long[] mProcessStateStatsLongs = new long[1];
10562
10563    boolean isProcessAliveLocked(ProcessRecord proc) {
10564        if (proc.procStatFile == null) {
10565            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10566        }
10567        mProcessStateStatsLongs[0] = 0;
10568        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10569                mProcessStateStatsLongs, null)) {
10570            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10571            return false;
10572        }
10573        final long state = mProcessStateStatsLongs[0];
10574        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10575                + (char)state);
10576        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10577    }
10578
10579    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10580            String name, IBinder token, boolean stable, int userId) {
10581        ContentProviderRecord cpr;
10582        ContentProviderConnection conn = null;
10583        ProviderInfo cpi = null;
10584
10585        synchronized(this) {
10586            long startTime = SystemClock.uptimeMillis();
10587
10588            ProcessRecord r = null;
10589            if (caller != null) {
10590                r = getRecordForAppLocked(caller);
10591                if (r == null) {
10592                    throw new SecurityException(
10593                            "Unable to find app for caller " + caller
10594                          + " (pid=" + Binder.getCallingPid()
10595                          + ") when getting content provider " + name);
10596                }
10597            }
10598
10599            boolean checkCrossUser = true;
10600
10601            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10602
10603            // First check if this content provider has been published...
10604            cpr = mProviderMap.getProviderByName(name, userId);
10605            // If that didn't work, check if it exists for user 0 and then
10606            // verify that it's a singleton provider before using it.
10607            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10608                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10609                if (cpr != null) {
10610                    cpi = cpr.info;
10611                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10612                            cpi.name, cpi.flags)
10613                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10614                        userId = UserHandle.USER_SYSTEM;
10615                        checkCrossUser = false;
10616                    } else {
10617                        cpr = null;
10618                        cpi = null;
10619                    }
10620                }
10621            }
10622
10623            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10624            if (providerRunning) {
10625                cpi = cpr.info;
10626                String msg;
10627                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10628                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10629                        != null) {
10630                    throw new SecurityException(msg);
10631                }
10632                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10633
10634                if (r != null && cpr.canRunHere(r)) {
10635                    // This provider has been published or is in the process
10636                    // of being published...  but it is also allowed to run
10637                    // in the caller's process, so don't make a connection
10638                    // and just let the caller instantiate its own instance.
10639                    ContentProviderHolder holder = cpr.newHolder(null);
10640                    // don't give caller the provider object, it needs
10641                    // to make its own.
10642                    holder.provider = null;
10643                    return holder;
10644                }
10645
10646                final long origId = Binder.clearCallingIdentity();
10647
10648                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10649
10650                // In this case the provider instance already exists, so we can
10651                // return it right away.
10652                conn = incProviderCountLocked(r, cpr, token, stable);
10653                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10654                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10655                        // If this is a perceptible app accessing the provider,
10656                        // make sure to count it as being accessed and thus
10657                        // back up on the LRU list.  This is good because
10658                        // content providers are often expensive to start.
10659                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10660                        updateLruProcessLocked(cpr.proc, false, null);
10661                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10662                    }
10663                }
10664
10665                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10666                final int verifiedAdj = cpr.proc.verifiedAdj;
10667                boolean success = updateOomAdjLocked(cpr.proc);
10668                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10669                // if the process has been successfully adjusted.  So to reduce races with
10670                // it, we will check whether the process still exists.  Note that this doesn't
10671                // completely get rid of races with LMK killing the process, but should make
10672                // them much smaller.
10673                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10674                    success = false;
10675                }
10676                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10677                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10678                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10679                // NOTE: there is still a race here where a signal could be
10680                // pending on the process even though we managed to update its
10681                // adj level.  Not sure what to do about this, but at least
10682                // the race is now smaller.
10683                if (!success) {
10684                    // Uh oh...  it looks like the provider's process
10685                    // has been killed on us.  We need to wait for a new
10686                    // process to be started, and make sure its death
10687                    // doesn't kill our process.
10688                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10689                            + " is crashing; detaching " + r);
10690                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10691                    checkTime(startTime, "getContentProviderImpl: before appDied");
10692                    appDiedLocked(cpr.proc);
10693                    checkTime(startTime, "getContentProviderImpl: after appDied");
10694                    if (!lastRef) {
10695                        // This wasn't the last ref our process had on
10696                        // the provider...  we have now been killed, bail.
10697                        return null;
10698                    }
10699                    providerRunning = false;
10700                    conn = null;
10701                } else {
10702                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10703                }
10704
10705                Binder.restoreCallingIdentity(origId);
10706            }
10707
10708            if (!providerRunning) {
10709                try {
10710                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10711                    cpi = AppGlobals.getPackageManager().
10712                        resolveContentProvider(name,
10713                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10714                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10715                } catch (RemoteException ex) {
10716                }
10717                if (cpi == null) {
10718                    return null;
10719                }
10720                // If the provider is a singleton AND
10721                // (it's a call within the same user || the provider is a
10722                // privileged app)
10723                // Then allow connecting to the singleton provider
10724                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10725                        cpi.name, cpi.flags)
10726                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10727                if (singleton) {
10728                    userId = UserHandle.USER_SYSTEM;
10729                }
10730                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10731                checkTime(startTime, "getContentProviderImpl: got app info for user");
10732
10733                String msg;
10734                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10735                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10736                        != null) {
10737                    throw new SecurityException(msg);
10738                }
10739                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10740
10741                if (!mProcessesReady
10742                        && !cpi.processName.equals("system")) {
10743                    // If this content provider does not run in the system
10744                    // process, and the system is not yet ready to run other
10745                    // processes, then fail fast instead of hanging.
10746                    throw new IllegalArgumentException(
10747                            "Attempt to launch content provider before system ready");
10748                }
10749
10750                // Make sure that the user who owns this provider is running.  If not,
10751                // we don't want to allow it to run.
10752                if (!mUserController.isUserRunningLocked(userId, 0)) {
10753                    Slog.w(TAG, "Unable to launch app "
10754                            + cpi.applicationInfo.packageName + "/"
10755                            + cpi.applicationInfo.uid + " for provider "
10756                            + name + ": user " + userId + " is stopped");
10757                    return null;
10758                }
10759
10760                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10761                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10762                cpr = mProviderMap.getProviderByClass(comp, userId);
10763                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10764                final boolean firstClass = cpr == null;
10765                if (firstClass) {
10766                    final long ident = Binder.clearCallingIdentity();
10767
10768                    // If permissions need a review before any of the app components can run,
10769                    // we return no provider and launch a review activity if the calling app
10770                    // is in the foreground.
10771                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10772                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10773                            return null;
10774                        }
10775                    }
10776
10777                    try {
10778                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10779                        ApplicationInfo ai =
10780                            AppGlobals.getPackageManager().
10781                                getApplicationInfo(
10782                                        cpi.applicationInfo.packageName,
10783                                        STOCK_PM_FLAGS, userId);
10784                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10785                        if (ai == null) {
10786                            Slog.w(TAG, "No package info for content provider "
10787                                    + cpi.name);
10788                            return null;
10789                        }
10790                        ai = getAppInfoForUser(ai, userId);
10791                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10792                    } catch (RemoteException ex) {
10793                        // pm is in same process, this will never happen.
10794                    } finally {
10795                        Binder.restoreCallingIdentity(ident);
10796                    }
10797                }
10798
10799                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10800
10801                if (r != null && cpr.canRunHere(r)) {
10802                    // If this is a multiprocess provider, then just return its
10803                    // info and allow the caller to instantiate it.  Only do
10804                    // this if the provider is the same user as the caller's
10805                    // process, or can run as root (so can be in any process).
10806                    return cpr.newHolder(null);
10807                }
10808
10809                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10810                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10811                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10812
10813                // This is single process, and our app is now connecting to it.
10814                // See if we are already in the process of launching this
10815                // provider.
10816                final int N = mLaunchingProviders.size();
10817                int i;
10818                for (i = 0; i < N; i++) {
10819                    if (mLaunchingProviders.get(i) == cpr) {
10820                        break;
10821                    }
10822                }
10823
10824                // If the provider is not already being launched, then get it
10825                // started.
10826                if (i >= N) {
10827                    final long origId = Binder.clearCallingIdentity();
10828
10829                    try {
10830                        // Content provider is now in use, its package can't be stopped.
10831                        try {
10832                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10833                            AppGlobals.getPackageManager().setPackageStoppedState(
10834                                    cpr.appInfo.packageName, false, userId);
10835                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10836                        } catch (RemoteException e) {
10837                        } catch (IllegalArgumentException e) {
10838                            Slog.w(TAG, "Failed trying to unstop package "
10839                                    + cpr.appInfo.packageName + ": " + e);
10840                        }
10841
10842                        // Use existing process if already started
10843                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10844                        ProcessRecord proc = getProcessRecordLocked(
10845                                cpi.processName, cpr.appInfo.uid, false);
10846                        if (proc != null && proc.thread != null && !proc.killed) {
10847                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10848                                    "Installing in existing process " + proc);
10849                            if (!proc.pubProviders.containsKey(cpi.name)) {
10850                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10851                                proc.pubProviders.put(cpi.name, cpr);
10852                                try {
10853                                    proc.thread.scheduleInstallProvider(cpi);
10854                                } catch (RemoteException e) {
10855                                }
10856                            }
10857                        } else {
10858                            checkTime(startTime, "getContentProviderImpl: before start process");
10859                            proc = startProcessLocked(cpi.processName,
10860                                    cpr.appInfo, false, 0, "content provider",
10861                                    new ComponentName(cpi.applicationInfo.packageName,
10862                                            cpi.name), false, false, false);
10863                            checkTime(startTime, "getContentProviderImpl: after start process");
10864                            if (proc == null) {
10865                                Slog.w(TAG, "Unable to launch app "
10866                                        + cpi.applicationInfo.packageName + "/"
10867                                        + cpi.applicationInfo.uid + " for provider "
10868                                        + name + ": process is bad");
10869                                return null;
10870                            }
10871                        }
10872                        cpr.launchingApp = proc;
10873                        mLaunchingProviders.add(cpr);
10874                    } finally {
10875                        Binder.restoreCallingIdentity(origId);
10876                    }
10877                }
10878
10879                checkTime(startTime, "getContentProviderImpl: updating data structures");
10880
10881                // Make sure the provider is published (the same provider class
10882                // may be published under multiple names).
10883                if (firstClass) {
10884                    mProviderMap.putProviderByClass(comp, cpr);
10885                }
10886
10887                mProviderMap.putProviderByName(name, cpr);
10888                conn = incProviderCountLocked(r, cpr, token, stable);
10889                if (conn != null) {
10890                    conn.waiting = true;
10891                }
10892            }
10893            checkTime(startTime, "getContentProviderImpl: done!");
10894        }
10895
10896        // Wait for the provider to be published...
10897        synchronized (cpr) {
10898            while (cpr.provider == null) {
10899                if (cpr.launchingApp == null) {
10900                    Slog.w(TAG, "Unable to launch app "
10901                            + cpi.applicationInfo.packageName + "/"
10902                            + cpi.applicationInfo.uid + " for provider "
10903                            + name + ": launching app became null");
10904                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10905                            UserHandle.getUserId(cpi.applicationInfo.uid),
10906                            cpi.applicationInfo.packageName,
10907                            cpi.applicationInfo.uid, name);
10908                    return null;
10909                }
10910                try {
10911                    if (DEBUG_MU) Slog.v(TAG_MU,
10912                            "Waiting to start provider " + cpr
10913                            + " launchingApp=" + cpr.launchingApp);
10914                    if (conn != null) {
10915                        conn.waiting = true;
10916                    }
10917                    cpr.wait();
10918                } catch (InterruptedException ex) {
10919                } finally {
10920                    if (conn != null) {
10921                        conn.waiting = false;
10922                    }
10923                }
10924            }
10925        }
10926        return cpr != null ? cpr.newHolder(conn) : null;
10927    }
10928
10929    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10930            ProcessRecord r, final int userId) {
10931        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10932                cpi.packageName, userId)) {
10933
10934            final boolean callerForeground = r == null || r.setSchedGroup
10935                    != ProcessList.SCHED_GROUP_BACKGROUND;
10936
10937            // Show a permission review UI only for starting from a foreground app
10938            if (!callerForeground) {
10939                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10940                        + cpi.packageName + " requires a permissions review");
10941                return false;
10942            }
10943
10944            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10945            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10946                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10947            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10948
10949            if (DEBUG_PERMISSIONS_REVIEW) {
10950                Slog.i(TAG, "u" + userId + " Launching permission review "
10951                        + "for package " + cpi.packageName);
10952            }
10953
10954            final UserHandle userHandle = new UserHandle(userId);
10955            mHandler.post(new Runnable() {
10956                @Override
10957                public void run() {
10958                    mContext.startActivityAsUser(intent, userHandle);
10959                }
10960            });
10961
10962            return false;
10963        }
10964
10965        return true;
10966    }
10967
10968    PackageManagerInternal getPackageManagerInternalLocked() {
10969        if (mPackageManagerInt == null) {
10970            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10971        }
10972        return mPackageManagerInt;
10973    }
10974
10975    @Override
10976    public final ContentProviderHolder getContentProvider(
10977            IApplicationThread caller, String name, int userId, boolean stable) {
10978        enforceNotIsolatedCaller("getContentProvider");
10979        if (caller == null) {
10980            String msg = "null IApplicationThread when getting content provider "
10981                    + name;
10982            Slog.w(TAG, msg);
10983            throw new SecurityException(msg);
10984        }
10985        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10986        // with cross-user grant.
10987        return getContentProviderImpl(caller, name, null, stable, userId);
10988    }
10989
10990    public ContentProviderHolder getContentProviderExternal(
10991            String name, int userId, IBinder token) {
10992        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10993            "Do not have permission in call getContentProviderExternal()");
10994        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10995                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10996        return getContentProviderExternalUnchecked(name, token, userId);
10997    }
10998
10999    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11000            IBinder token, int userId) {
11001        return getContentProviderImpl(null, name, token, true, userId);
11002    }
11003
11004    /**
11005     * Drop a content provider from a ProcessRecord's bookkeeping
11006     */
11007    public void removeContentProvider(IBinder connection, boolean stable) {
11008        enforceNotIsolatedCaller("removeContentProvider");
11009        long ident = Binder.clearCallingIdentity();
11010        try {
11011            synchronized (this) {
11012                ContentProviderConnection conn;
11013                try {
11014                    conn = (ContentProviderConnection)connection;
11015                } catch (ClassCastException e) {
11016                    String msg ="removeContentProvider: " + connection
11017                            + " not a ContentProviderConnection";
11018                    Slog.w(TAG, msg);
11019                    throw new IllegalArgumentException(msg);
11020                }
11021                if (conn == null) {
11022                    throw new NullPointerException("connection is null");
11023                }
11024                if (decProviderCountLocked(conn, null, null, stable)) {
11025                    updateOomAdjLocked();
11026                }
11027            }
11028        } finally {
11029            Binder.restoreCallingIdentity(ident);
11030        }
11031    }
11032
11033    public void removeContentProviderExternal(String name, IBinder token) {
11034        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11035            "Do not have permission in call removeContentProviderExternal()");
11036        int userId = UserHandle.getCallingUserId();
11037        long ident = Binder.clearCallingIdentity();
11038        try {
11039            removeContentProviderExternalUnchecked(name, token, userId);
11040        } finally {
11041            Binder.restoreCallingIdentity(ident);
11042        }
11043    }
11044
11045    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11046        synchronized (this) {
11047            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11048            if(cpr == null) {
11049                //remove from mProvidersByClass
11050                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11051                return;
11052            }
11053
11054            //update content provider record entry info
11055            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11056            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11057            if (localCpr.hasExternalProcessHandles()) {
11058                if (localCpr.removeExternalProcessHandleLocked(token)) {
11059                    updateOomAdjLocked();
11060                } else {
11061                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11062                            + " with no external reference for token: "
11063                            + token + ".");
11064                }
11065            } else {
11066                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11067                        + " with no external references.");
11068            }
11069        }
11070    }
11071
11072    public final void publishContentProviders(IApplicationThread caller,
11073            List<ContentProviderHolder> providers) {
11074        if (providers == null) {
11075            return;
11076        }
11077
11078        enforceNotIsolatedCaller("publishContentProviders");
11079        synchronized (this) {
11080            final ProcessRecord r = getRecordForAppLocked(caller);
11081            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11082            if (r == null) {
11083                throw new SecurityException(
11084                        "Unable to find app for caller " + caller
11085                      + " (pid=" + Binder.getCallingPid()
11086                      + ") when publishing content providers");
11087            }
11088
11089            final long origId = Binder.clearCallingIdentity();
11090
11091            final int N = providers.size();
11092            for (int i = 0; i < N; i++) {
11093                ContentProviderHolder src = providers.get(i);
11094                if (src == null || src.info == null || src.provider == null) {
11095                    continue;
11096                }
11097                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11098                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11099                if (dst != null) {
11100                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11101                    mProviderMap.putProviderByClass(comp, dst);
11102                    String names[] = dst.info.authority.split(";");
11103                    for (int j = 0; j < names.length; j++) {
11104                        mProviderMap.putProviderByName(names[j], dst);
11105                    }
11106
11107                    int launchingCount = mLaunchingProviders.size();
11108                    int j;
11109                    boolean wasInLaunchingProviders = false;
11110                    for (j = 0; j < launchingCount; j++) {
11111                        if (mLaunchingProviders.get(j) == dst) {
11112                            mLaunchingProviders.remove(j);
11113                            wasInLaunchingProviders = true;
11114                            j--;
11115                            launchingCount--;
11116                        }
11117                    }
11118                    if (wasInLaunchingProviders) {
11119                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11120                    }
11121                    synchronized (dst) {
11122                        dst.provider = src.provider;
11123                        dst.proc = r;
11124                        dst.notifyAll();
11125                    }
11126                    updateOomAdjLocked(r);
11127                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11128                            src.info.authority);
11129                }
11130            }
11131
11132            Binder.restoreCallingIdentity(origId);
11133        }
11134    }
11135
11136    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11137        ContentProviderConnection conn;
11138        try {
11139            conn = (ContentProviderConnection)connection;
11140        } catch (ClassCastException e) {
11141            String msg ="refContentProvider: " + connection
11142                    + " not a ContentProviderConnection";
11143            Slog.w(TAG, msg);
11144            throw new IllegalArgumentException(msg);
11145        }
11146        if (conn == null) {
11147            throw new NullPointerException("connection is null");
11148        }
11149
11150        synchronized (this) {
11151            if (stable > 0) {
11152                conn.numStableIncs += stable;
11153            }
11154            stable = conn.stableCount + stable;
11155            if (stable < 0) {
11156                throw new IllegalStateException("stableCount < 0: " + stable);
11157            }
11158
11159            if (unstable > 0) {
11160                conn.numUnstableIncs += unstable;
11161            }
11162            unstable = conn.unstableCount + unstable;
11163            if (unstable < 0) {
11164                throw new IllegalStateException("unstableCount < 0: " + unstable);
11165            }
11166
11167            if ((stable+unstable) <= 0) {
11168                throw new IllegalStateException("ref counts can't go to zero here: stable="
11169                        + stable + " unstable=" + unstable);
11170            }
11171            conn.stableCount = stable;
11172            conn.unstableCount = unstable;
11173            return !conn.dead;
11174        }
11175    }
11176
11177    public void unstableProviderDied(IBinder connection) {
11178        ContentProviderConnection conn;
11179        try {
11180            conn = (ContentProviderConnection)connection;
11181        } catch (ClassCastException e) {
11182            String msg ="refContentProvider: " + connection
11183                    + " not a ContentProviderConnection";
11184            Slog.w(TAG, msg);
11185            throw new IllegalArgumentException(msg);
11186        }
11187        if (conn == null) {
11188            throw new NullPointerException("connection is null");
11189        }
11190
11191        // Safely retrieve the content provider associated with the connection.
11192        IContentProvider provider;
11193        synchronized (this) {
11194            provider = conn.provider.provider;
11195        }
11196
11197        if (provider == null) {
11198            // Um, yeah, we're way ahead of you.
11199            return;
11200        }
11201
11202        // Make sure the caller is being honest with us.
11203        if (provider.asBinder().pingBinder()) {
11204            // Er, no, still looks good to us.
11205            synchronized (this) {
11206                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11207                        + " says " + conn + " died, but we don't agree");
11208                return;
11209            }
11210        }
11211
11212        // Well look at that!  It's dead!
11213        synchronized (this) {
11214            if (conn.provider.provider != provider) {
11215                // But something changed...  good enough.
11216                return;
11217            }
11218
11219            ProcessRecord proc = conn.provider.proc;
11220            if (proc == null || proc.thread == null) {
11221                // Seems like the process is already cleaned up.
11222                return;
11223            }
11224
11225            // As far as we're concerned, this is just like receiving a
11226            // death notification...  just a bit prematurely.
11227            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11228                    + ") early provider death");
11229            final long ident = Binder.clearCallingIdentity();
11230            try {
11231                appDiedLocked(proc);
11232            } finally {
11233                Binder.restoreCallingIdentity(ident);
11234            }
11235        }
11236    }
11237
11238    @Override
11239    public void appNotRespondingViaProvider(IBinder connection) {
11240        enforceCallingPermission(
11241                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11242
11243        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11244        if (conn == null) {
11245            Slog.w(TAG, "ContentProviderConnection is null");
11246            return;
11247        }
11248
11249        final ProcessRecord host = conn.provider.proc;
11250        if (host == null) {
11251            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11252            return;
11253        }
11254
11255        mHandler.post(new Runnable() {
11256            @Override
11257            public void run() {
11258                mAppErrors.appNotResponding(host, null, null, false,
11259                        "ContentProvider not responding");
11260            }
11261        });
11262    }
11263
11264    public final void installSystemProviders() {
11265        List<ProviderInfo> providers;
11266        synchronized (this) {
11267            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11268            providers = generateApplicationProvidersLocked(app);
11269            if (providers != null) {
11270                for (int i=providers.size()-1; i>=0; i--) {
11271                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11272                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11273                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11274                                + ": not system .apk");
11275                        providers.remove(i);
11276                    }
11277                }
11278            }
11279        }
11280        if (providers != null) {
11281            mSystemThread.installSystemProviders(providers);
11282        }
11283
11284        mCoreSettingsObserver = new CoreSettingsObserver(this);
11285        mFontScaleSettingObserver = new FontScaleSettingObserver();
11286
11287        //mUsageStatsService.monitorPackages();
11288    }
11289
11290    private void startPersistentApps(int matchFlags) {
11291        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11292
11293        synchronized (this) {
11294            try {
11295                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11296                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11297                for (ApplicationInfo app : apps) {
11298                    if (!"android".equals(app.packageName)) {
11299                        addAppLocked(app, false, null /* ABI override */);
11300                    }
11301                }
11302            } catch (RemoteException ex) {
11303            }
11304        }
11305    }
11306
11307    /**
11308     * When a user is unlocked, we need to install encryption-unaware providers
11309     * belonging to any running apps.
11310     */
11311    private void installEncryptionUnawareProviders(int userId) {
11312        // We're only interested in providers that are encryption unaware, and
11313        // we don't care about uninstalled apps, since there's no way they're
11314        // running at this point.
11315        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11316
11317        synchronized (this) {
11318            final int NP = mProcessNames.getMap().size();
11319            for (int ip = 0; ip < NP; ip++) {
11320                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11321                final int NA = apps.size();
11322                for (int ia = 0; ia < NA; ia++) {
11323                    final ProcessRecord app = apps.valueAt(ia);
11324                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11325
11326                    final int NG = app.pkgList.size();
11327                    for (int ig = 0; ig < NG; ig++) {
11328                        try {
11329                            final String pkgName = app.pkgList.keyAt(ig);
11330                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11331                                    .getPackageInfo(pkgName, matchFlags, userId);
11332                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11333                                for (ProviderInfo pi : pkgInfo.providers) {
11334                                    // TODO: keep in sync with generateApplicationProvidersLocked
11335                                    final boolean processMatch = Objects.equals(pi.processName,
11336                                            app.processName) || pi.multiprocess;
11337                                    final boolean userMatch = isSingleton(pi.processName,
11338                                            pi.applicationInfo, pi.name, pi.flags)
11339                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11340                                    if (processMatch && userMatch) {
11341                                        Log.v(TAG, "Installing " + pi);
11342                                        app.thread.scheduleInstallProvider(pi);
11343                                    } else {
11344                                        Log.v(TAG, "Skipping " + pi);
11345                                    }
11346                                }
11347                            }
11348                        } catch (RemoteException ignored) {
11349                        }
11350                    }
11351                }
11352            }
11353        }
11354    }
11355
11356    /**
11357     * Allows apps to retrieve the MIME type of a URI.
11358     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11359     * users, then it does not need permission to access the ContentProvider.
11360     * Either, it needs cross-user uri grants.
11361     *
11362     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11363     *
11364     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11365     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11366     */
11367    public String getProviderMimeType(Uri uri, int userId) {
11368        enforceNotIsolatedCaller("getProviderMimeType");
11369        final String name = uri.getAuthority();
11370        int callingUid = Binder.getCallingUid();
11371        int callingPid = Binder.getCallingPid();
11372        long ident = 0;
11373        boolean clearedIdentity = false;
11374        synchronized (this) {
11375            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11376        }
11377        if (canClearIdentity(callingPid, callingUid, userId)) {
11378            clearedIdentity = true;
11379            ident = Binder.clearCallingIdentity();
11380        }
11381        ContentProviderHolder holder = null;
11382        try {
11383            holder = getContentProviderExternalUnchecked(name, null, userId);
11384            if (holder != null) {
11385                return holder.provider.getType(uri);
11386            }
11387        } catch (RemoteException e) {
11388            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11389            return null;
11390        } catch (Exception e) {
11391            Log.w(TAG, "Exception while determining type of " + uri, e);
11392            return null;
11393        } finally {
11394            // We need to clear the identity to call removeContentProviderExternalUnchecked
11395            if (!clearedIdentity) {
11396                ident = Binder.clearCallingIdentity();
11397            }
11398            try {
11399                if (holder != null) {
11400                    removeContentProviderExternalUnchecked(name, null, userId);
11401                }
11402            } finally {
11403                Binder.restoreCallingIdentity(ident);
11404            }
11405        }
11406
11407        return null;
11408    }
11409
11410    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11411        if (UserHandle.getUserId(callingUid) == userId) {
11412            return true;
11413        }
11414        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11415                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11416                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11417                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11418                return true;
11419        }
11420        return false;
11421    }
11422
11423    // =========================================================
11424    // GLOBAL MANAGEMENT
11425    // =========================================================
11426
11427    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11428            boolean isolated, int isolatedUid) {
11429        String proc = customProcess != null ? customProcess : info.processName;
11430        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11431        final int userId = UserHandle.getUserId(info.uid);
11432        int uid = info.uid;
11433        if (isolated) {
11434            if (isolatedUid == 0) {
11435                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11436                while (true) {
11437                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11438                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11439                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11440                    }
11441                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11442                    mNextIsolatedProcessUid++;
11443                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11444                        // No process for this uid, use it.
11445                        break;
11446                    }
11447                    stepsLeft--;
11448                    if (stepsLeft <= 0) {
11449                        return null;
11450                    }
11451                }
11452            } else {
11453                // Special case for startIsolatedProcess (internal only), where
11454                // the uid of the isolated process is specified by the caller.
11455                uid = isolatedUid;
11456            }
11457
11458            // Register the isolated UID with this application so BatteryStats knows to
11459            // attribute resource usage to the application.
11460            //
11461            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11462            // about the process state of the isolated UID *before* it is registered with the
11463            // owning application.
11464            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11465        }
11466        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11467        if (!mBooted && !mBooting
11468                && userId == UserHandle.USER_SYSTEM
11469                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11470            r.persistent = true;
11471        }
11472        addProcessNameLocked(r);
11473        return r;
11474    }
11475
11476    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11477            String abiOverride) {
11478        ProcessRecord app;
11479        if (!isolated) {
11480            app = getProcessRecordLocked(info.processName, info.uid, true);
11481        } else {
11482            app = null;
11483        }
11484
11485        if (app == null) {
11486            app = newProcessRecordLocked(info, null, isolated, 0);
11487            updateLruProcessLocked(app, false, null);
11488            updateOomAdjLocked();
11489        }
11490
11491        // This package really, really can not be stopped.
11492        try {
11493            AppGlobals.getPackageManager().setPackageStoppedState(
11494                    info.packageName, false, UserHandle.getUserId(app.uid));
11495        } catch (RemoteException e) {
11496        } catch (IllegalArgumentException e) {
11497            Slog.w(TAG, "Failed trying to unstop package "
11498                    + info.packageName + ": " + e);
11499        }
11500
11501        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11502            app.persistent = true;
11503            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11504        }
11505        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11506            mPersistentStartingProcesses.add(app);
11507            startProcessLocked(app, "added application", app.processName, abiOverride,
11508                    null /* entryPoint */, null /* entryPointArgs */);
11509        }
11510
11511        return app;
11512    }
11513
11514    public void unhandledBack() {
11515        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11516                "unhandledBack()");
11517
11518        synchronized(this) {
11519            final long origId = Binder.clearCallingIdentity();
11520            try {
11521                getFocusedStack().unhandledBackLocked();
11522            } finally {
11523                Binder.restoreCallingIdentity(origId);
11524            }
11525        }
11526    }
11527
11528    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11529        enforceNotIsolatedCaller("openContentUri");
11530        final int userId = UserHandle.getCallingUserId();
11531        String name = uri.getAuthority();
11532        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11533        ParcelFileDescriptor pfd = null;
11534        if (cph != null) {
11535            // We record the binder invoker's uid in thread-local storage before
11536            // going to the content provider to open the file.  Later, in the code
11537            // that handles all permissions checks, we look for this uid and use
11538            // that rather than the Activity Manager's own uid.  The effect is that
11539            // we do the check against the caller's permissions even though it looks
11540            // to the content provider like the Activity Manager itself is making
11541            // the request.
11542            Binder token = new Binder();
11543            sCallerIdentity.set(new Identity(
11544                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11545            try {
11546                pfd = cph.provider.openFile(null, uri, "r", null, token);
11547            } catch (FileNotFoundException e) {
11548                // do nothing; pfd will be returned null
11549            } finally {
11550                // Ensure that whatever happens, we clean up the identity state
11551                sCallerIdentity.remove();
11552                // Ensure we're done with the provider.
11553                removeContentProviderExternalUnchecked(name, null, userId);
11554            }
11555        } else {
11556            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11557        }
11558        return pfd;
11559    }
11560
11561    // Actually is sleeping or shutting down or whatever else in the future
11562    // is an inactive state.
11563    boolean isSleepingOrShuttingDownLocked() {
11564        return isSleepingLocked() || mShuttingDown;
11565    }
11566
11567    boolean isShuttingDownLocked() {
11568        return mShuttingDown;
11569    }
11570
11571    boolean isSleepingLocked() {
11572        return mSleeping;
11573    }
11574
11575    void onWakefulnessChanged(int wakefulness) {
11576        synchronized(this) {
11577            mWakefulness = wakefulness;
11578            updateSleepIfNeededLocked();
11579        }
11580    }
11581
11582    void finishRunningVoiceLocked() {
11583        if (mRunningVoice != null) {
11584            mRunningVoice = null;
11585            mVoiceWakeLock.release();
11586            updateSleepIfNeededLocked();
11587        }
11588    }
11589
11590    void startTimeTrackingFocusedActivityLocked() {
11591        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11592            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11593        }
11594    }
11595
11596    void updateSleepIfNeededLocked() {
11597        if (mSleeping && !shouldSleepLocked()) {
11598            mSleeping = false;
11599            startTimeTrackingFocusedActivityLocked();
11600            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11601            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11602            updateOomAdjLocked();
11603        } else if (!mSleeping && shouldSleepLocked()) {
11604            mSleeping = true;
11605            if (mCurAppTimeTracker != null) {
11606                mCurAppTimeTracker.stop();
11607            }
11608            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11609            mStackSupervisor.goingToSleepLocked();
11610            updateOomAdjLocked();
11611
11612            // Initialize the wake times of all processes.
11613            checkExcessivePowerUsageLocked(false);
11614            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11615            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11616            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11617        }
11618    }
11619
11620    private boolean shouldSleepLocked() {
11621        // Resume applications while running a voice interactor.
11622        if (mRunningVoice != null) {
11623            return false;
11624        }
11625
11626        // TODO: Transform the lock screen state into a sleep token instead.
11627        switch (mWakefulness) {
11628            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11629            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11630            case PowerManagerInternal.WAKEFULNESS_DOZING:
11631                // Pause applications whenever the lock screen is shown or any sleep
11632                // tokens have been acquired.
11633                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11634            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11635            default:
11636                // If we're asleep then pause applications unconditionally.
11637                return true;
11638        }
11639    }
11640
11641    /** Pokes the task persister. */
11642    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11643        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11644    }
11645
11646    /** Notifies all listeners when the task stack has changed. */
11647    void notifyTaskStackChangedLocked() {
11648        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11649        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11650        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11651        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11652    }
11653
11654    /** Notifies all listeners when an Activity is pinned. */
11655    void notifyActivityPinnedLocked() {
11656        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11657        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11658    }
11659
11660    /**
11661     * Notifies all listeners when an attempt was made to start an an activity that is already
11662     * running in the pinned stack and the activity was not actually started, but the task is
11663     * either brought to the front or a new Intent is delivered to it.
11664     */
11665    void notifyPinnedActivityRestartAttemptLocked() {
11666        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11667        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11668    }
11669
11670    /** Notifies all listeners when the pinned stack animation ends. */
11671    @Override
11672    public void notifyPinnedStackAnimationEnded() {
11673        synchronized (this) {
11674            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11675            mHandler.obtainMessage(
11676                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11677        }
11678    }
11679
11680    @Override
11681    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11682        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11683    }
11684
11685    @Override
11686    public boolean shutdown(int timeout) {
11687        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11688                != PackageManager.PERMISSION_GRANTED) {
11689            throw new SecurityException("Requires permission "
11690                    + android.Manifest.permission.SHUTDOWN);
11691        }
11692
11693        boolean timedout = false;
11694
11695        synchronized(this) {
11696            mShuttingDown = true;
11697            updateEventDispatchingLocked();
11698            timedout = mStackSupervisor.shutdownLocked(timeout);
11699        }
11700
11701        mAppOpsService.shutdown();
11702        if (mUsageStatsService != null) {
11703            mUsageStatsService.prepareShutdown();
11704        }
11705        mBatteryStatsService.shutdown();
11706        synchronized (this) {
11707            mProcessStats.shutdownLocked();
11708            notifyTaskPersisterLocked(null, true);
11709        }
11710
11711        return timedout;
11712    }
11713
11714    public final void activitySlept(IBinder token) {
11715        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11716
11717        final long origId = Binder.clearCallingIdentity();
11718
11719        synchronized (this) {
11720            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11721            if (r != null) {
11722                mStackSupervisor.activitySleptLocked(r);
11723            }
11724        }
11725
11726        Binder.restoreCallingIdentity(origId);
11727    }
11728
11729    private String lockScreenShownToString() {
11730        switch (mLockScreenShown) {
11731            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11732            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11733            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11734            default: return "Unknown=" + mLockScreenShown;
11735        }
11736    }
11737
11738    void logLockScreen(String msg) {
11739        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11740                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11741                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11742                + " mSleeping=" + mSleeping);
11743    }
11744
11745    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11746        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11747        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11748        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11749            boolean wasRunningVoice = mRunningVoice != null;
11750            mRunningVoice = session;
11751            if (!wasRunningVoice) {
11752                mVoiceWakeLock.acquire();
11753                updateSleepIfNeededLocked();
11754            }
11755        }
11756    }
11757
11758    private void updateEventDispatchingLocked() {
11759        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11760    }
11761
11762    public void setLockScreenShown(boolean showing, boolean occluded) {
11763        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11764                != PackageManager.PERMISSION_GRANTED) {
11765            throw new SecurityException("Requires permission "
11766                    + android.Manifest.permission.DEVICE_POWER);
11767        }
11768
11769        synchronized(this) {
11770            long ident = Binder.clearCallingIdentity();
11771            try {
11772                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11773                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11774                if (showing && occluded) {
11775                    // The lock screen is currently showing, but is occluded by a window that can
11776                    // show on top of the lock screen. In this can we want to dismiss the docked
11777                    // stack since it will be complicated/risky to try to put the activity on top
11778                    // of the lock screen in the right fullscreen configuration.
11779                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11780                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11781                }
11782
11783                updateSleepIfNeededLocked();
11784            } finally {
11785                Binder.restoreCallingIdentity(ident);
11786            }
11787        }
11788    }
11789
11790    @Override
11791    public void notifyLockedProfile(@UserIdInt int userId) {
11792        try {
11793            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11794                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11795            }
11796        } catch (RemoteException ex) {
11797            throw new SecurityException("Fail to check is caller a privileged app", ex);
11798        }
11799
11800        synchronized (this) {
11801            if (mStackSupervisor.isUserLockedProfile(userId)) {
11802                final long ident = Binder.clearCallingIdentity();
11803                try {
11804                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11805                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11806                        // If there is no device lock, we will show the profile's credential page.
11807                        mActivityStarter.showConfirmDeviceCredential(userId);
11808                    } else {
11809                        // Showing launcher to avoid user entering credential twice.
11810                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11811                    }
11812                } finally {
11813                    Binder.restoreCallingIdentity(ident);
11814                }
11815            }
11816        }
11817    }
11818
11819    @Override
11820    public void startConfirmDeviceCredentialIntent(Intent intent) {
11821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11822        synchronized (this) {
11823            final long ident = Binder.clearCallingIdentity();
11824            try {
11825                mActivityStarter.startConfirmCredentialIntent(intent);
11826            } finally {
11827                Binder.restoreCallingIdentity(ident);
11828            }
11829        }
11830    }
11831
11832    @Override
11833    public void stopAppSwitches() {
11834        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11835                != PackageManager.PERMISSION_GRANTED) {
11836            throw new SecurityException("viewquires permission "
11837                    + android.Manifest.permission.STOP_APP_SWITCHES);
11838        }
11839
11840        synchronized(this) {
11841            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11842                    + APP_SWITCH_DELAY_TIME;
11843            mDidAppSwitch = false;
11844            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11845            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11846            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11847        }
11848    }
11849
11850    public void resumeAppSwitches() {
11851        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11852                != PackageManager.PERMISSION_GRANTED) {
11853            throw new SecurityException("Requires permission "
11854                    + android.Manifest.permission.STOP_APP_SWITCHES);
11855        }
11856
11857        synchronized(this) {
11858            // Note that we don't execute any pending app switches... we will
11859            // let those wait until either the timeout, or the next start
11860            // activity request.
11861            mAppSwitchesAllowedTime = 0;
11862        }
11863    }
11864
11865    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11866            int callingPid, int callingUid, String name) {
11867        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11868            return true;
11869        }
11870
11871        int perm = checkComponentPermission(
11872                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11873                sourceUid, -1, true);
11874        if (perm == PackageManager.PERMISSION_GRANTED) {
11875            return true;
11876        }
11877
11878        // If the actual IPC caller is different from the logical source, then
11879        // also see if they are allowed to control app switches.
11880        if (callingUid != -1 && callingUid != sourceUid) {
11881            perm = checkComponentPermission(
11882                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11883                    callingUid, -1, true);
11884            if (perm == PackageManager.PERMISSION_GRANTED) {
11885                return true;
11886            }
11887        }
11888
11889        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11890        return false;
11891    }
11892
11893    public void setDebugApp(String packageName, boolean waitForDebugger,
11894            boolean persistent) {
11895        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11896                "setDebugApp()");
11897
11898        long ident = Binder.clearCallingIdentity();
11899        try {
11900            // Note that this is not really thread safe if there are multiple
11901            // callers into it at the same time, but that's not a situation we
11902            // care about.
11903            if (persistent) {
11904                final ContentResolver resolver = mContext.getContentResolver();
11905                Settings.Global.putString(
11906                    resolver, Settings.Global.DEBUG_APP,
11907                    packageName);
11908                Settings.Global.putInt(
11909                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11910                    waitForDebugger ? 1 : 0);
11911            }
11912
11913            synchronized (this) {
11914                if (!persistent) {
11915                    mOrigDebugApp = mDebugApp;
11916                    mOrigWaitForDebugger = mWaitForDebugger;
11917                }
11918                mDebugApp = packageName;
11919                mWaitForDebugger = waitForDebugger;
11920                mDebugTransient = !persistent;
11921                if (packageName != null) {
11922                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11923                            false, UserHandle.USER_ALL, "set debug app");
11924                }
11925            }
11926        } finally {
11927            Binder.restoreCallingIdentity(ident);
11928        }
11929    }
11930
11931    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11932        synchronized (this) {
11933            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11934            if (!isDebuggable) {
11935                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11936                    throw new SecurityException("Process not debuggable: " + app.packageName);
11937                }
11938            }
11939
11940            mTrackAllocationApp = processName;
11941        }
11942    }
11943
11944    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11945        synchronized (this) {
11946            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11947            if (!isDebuggable) {
11948                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11949                    throw new SecurityException("Process not debuggable: " + app.packageName);
11950                }
11951            }
11952            mProfileApp = processName;
11953            mProfileFile = profilerInfo.profileFile;
11954            if (mProfileFd != null) {
11955                try {
11956                    mProfileFd.close();
11957                } catch (IOException e) {
11958                }
11959                mProfileFd = null;
11960            }
11961            mProfileFd = profilerInfo.profileFd;
11962            mSamplingInterval = profilerInfo.samplingInterval;
11963            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11964            mProfileType = 0;
11965        }
11966    }
11967
11968    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11969        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11970        if (!isDebuggable) {
11971            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11972                throw new SecurityException("Process not debuggable: " + app.packageName);
11973            }
11974        }
11975        mNativeDebuggingApp = processName;
11976    }
11977
11978    @Override
11979    public void setAlwaysFinish(boolean enabled) {
11980        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11981                "setAlwaysFinish()");
11982
11983        long ident = Binder.clearCallingIdentity();
11984        try {
11985            Settings.Global.putInt(
11986                    mContext.getContentResolver(),
11987                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11988
11989            synchronized (this) {
11990                mAlwaysFinishActivities = enabled;
11991            }
11992        } finally {
11993            Binder.restoreCallingIdentity(ident);
11994        }
11995    }
11996
11997    @Override
11998    public void setLenientBackgroundCheck(boolean enabled) {
11999        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12000                "setLenientBackgroundCheck()");
12001
12002        long ident = Binder.clearCallingIdentity();
12003        try {
12004            Settings.Global.putInt(
12005                    mContext.getContentResolver(),
12006                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12007
12008            synchronized (this) {
12009                mLenientBackgroundCheck = enabled;
12010            }
12011        } finally {
12012            Binder.restoreCallingIdentity(ident);
12013        }
12014    }
12015
12016    @Override
12017    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12018        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12019                "setActivityController()");
12020        synchronized (this) {
12021            mController = controller;
12022            mControllerIsAMonkey = imAMonkey;
12023            Watchdog.getInstance().setActivityController(controller);
12024        }
12025    }
12026
12027    @Override
12028    public void setUserIsMonkey(boolean userIsMonkey) {
12029        synchronized (this) {
12030            synchronized (mPidsSelfLocked) {
12031                final int callingPid = Binder.getCallingPid();
12032                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12033                if (precessRecord == null) {
12034                    throw new SecurityException("Unknown process: " + callingPid);
12035                }
12036                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12037                    throw new SecurityException("Only an instrumentation process "
12038                            + "with a UiAutomation can call setUserIsMonkey");
12039                }
12040            }
12041            mUserIsMonkey = userIsMonkey;
12042        }
12043    }
12044
12045    @Override
12046    public boolean isUserAMonkey() {
12047        synchronized (this) {
12048            // If there is a controller also implies the user is a monkey.
12049            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12050        }
12051    }
12052
12053    public void requestBugReport(int bugreportType) {
12054        String service = null;
12055        switch (bugreportType) {
12056            case ActivityManager.BUGREPORT_OPTION_FULL:
12057                service = "bugreport";
12058                break;
12059            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12060                service = "bugreportplus";
12061                break;
12062            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12063                service = "bugreportremote";
12064                break;
12065            case ActivityManager.BUGREPORT_OPTION_WEAR:
12066                service = "bugreportwear";
12067                break;
12068        }
12069        if (service == null) {
12070            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12071                    + bugreportType);
12072        }
12073        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12074        SystemProperties.set("ctl.start", service);
12075    }
12076
12077    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12078        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12079    }
12080
12081    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12082        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12083            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12084        }
12085        return KEY_DISPATCHING_TIMEOUT;
12086    }
12087
12088    @Override
12089    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12090        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12091                != PackageManager.PERMISSION_GRANTED) {
12092            throw new SecurityException("Requires permission "
12093                    + android.Manifest.permission.FILTER_EVENTS);
12094        }
12095        ProcessRecord proc;
12096        long timeout;
12097        synchronized (this) {
12098            synchronized (mPidsSelfLocked) {
12099                proc = mPidsSelfLocked.get(pid);
12100            }
12101            timeout = getInputDispatchingTimeoutLocked(proc);
12102        }
12103
12104        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12105            return -1;
12106        }
12107
12108        return timeout;
12109    }
12110
12111    /**
12112     * Handle input dispatching timeouts.
12113     * Returns whether input dispatching should be aborted or not.
12114     */
12115    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12116            final ActivityRecord activity, final ActivityRecord parent,
12117            final boolean aboveSystem, String reason) {
12118        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12119                != PackageManager.PERMISSION_GRANTED) {
12120            throw new SecurityException("Requires permission "
12121                    + android.Manifest.permission.FILTER_EVENTS);
12122        }
12123
12124        final String annotation;
12125        if (reason == null) {
12126            annotation = "Input dispatching timed out";
12127        } else {
12128            annotation = "Input dispatching timed out (" + reason + ")";
12129        }
12130
12131        if (proc != null) {
12132            synchronized (this) {
12133                if (proc.debugging) {
12134                    return false;
12135                }
12136
12137                if (mDidDexOpt) {
12138                    // Give more time since we were dexopting.
12139                    mDidDexOpt = false;
12140                    return false;
12141                }
12142
12143                if (proc.instrumentationClass != null) {
12144                    Bundle info = new Bundle();
12145                    info.putString("shortMsg", "keyDispatchingTimedOut");
12146                    info.putString("longMsg", annotation);
12147                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12148                    return true;
12149                }
12150            }
12151            mHandler.post(new Runnable() {
12152                @Override
12153                public void run() {
12154                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12155                }
12156            });
12157        }
12158
12159        return true;
12160    }
12161
12162    @Override
12163    public Bundle getAssistContextExtras(int requestType) {
12164        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12165                null, null, true /* focused */, true /* newSessionId */,
12166                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12167        if (pae == null) {
12168            return null;
12169        }
12170        synchronized (pae) {
12171            while (!pae.haveResult) {
12172                try {
12173                    pae.wait();
12174                } catch (InterruptedException e) {
12175                }
12176            }
12177        }
12178        synchronized (this) {
12179            buildAssistBundleLocked(pae, pae.result);
12180            mPendingAssistExtras.remove(pae);
12181            mUiHandler.removeCallbacks(pae);
12182        }
12183        return pae.extras;
12184    }
12185
12186    @Override
12187    public boolean isAssistDataAllowedOnCurrentActivity() {
12188        int userId;
12189        synchronized (this) {
12190            userId = mUserController.getCurrentUserIdLocked();
12191            ActivityRecord activity = getFocusedStack().topActivity();
12192            if (activity == null) {
12193                return false;
12194            }
12195            userId = activity.userId;
12196        }
12197        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12198                Context.DEVICE_POLICY_SERVICE);
12199        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12200    }
12201
12202    @Override
12203    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12204        long ident = Binder.clearCallingIdentity();
12205        try {
12206            synchronized (this) {
12207                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12208                ActivityRecord top = getFocusedStack().topActivity();
12209                if (top != caller) {
12210                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12211                            + " is not current top " + top);
12212                    return false;
12213                }
12214                if (!top.nowVisible) {
12215                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12216                            + " is not visible");
12217                    return false;
12218                }
12219            }
12220            AssistUtils utils = new AssistUtils(mContext);
12221            return utils.showSessionForActiveService(args,
12222                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12223        } finally {
12224            Binder.restoreCallingIdentity(ident);
12225        }
12226    }
12227
12228    @Override
12229    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12230            Bundle receiverExtras,
12231            IBinder activityToken, boolean focused, boolean newSessionId) {
12232        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12233                activityToken, focused, newSessionId,
12234                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12235                != null;
12236    }
12237
12238    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12239            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12240            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12241        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12242                "enqueueAssistContext()");
12243        synchronized (this) {
12244            ActivityRecord activity = getFocusedStack().topActivity();
12245            if (activity == null) {
12246                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12247                return null;
12248            }
12249            if (activity.app == null || activity.app.thread == null) {
12250                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12251                return null;
12252            }
12253            if (focused) {
12254                if (activityToken != null) {
12255                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12256                    if (activity != caller) {
12257                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12258                                + " is not current top " + activity);
12259                        return null;
12260                    }
12261                }
12262            } else {
12263                activity = ActivityRecord.forTokenLocked(activityToken);
12264                if (activity == null) {
12265                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12266                            + " couldn't be found");
12267                    return null;
12268                }
12269            }
12270
12271            PendingAssistExtras pae;
12272            Bundle extras = new Bundle();
12273            if (args != null) {
12274                extras.putAll(args);
12275            }
12276            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12277            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12278            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12279                    userHandle);
12280            // Increment the sessionId if necessary
12281            if (newSessionId) {
12282                mViSessionId++;
12283            }
12284            try {
12285                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12286                        requestType, mViSessionId);
12287                mPendingAssistExtras.add(pae);
12288                mUiHandler.postDelayed(pae, timeout);
12289            } catch (RemoteException e) {
12290                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12291                return null;
12292            }
12293            return pae;
12294        }
12295    }
12296
12297    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12298        IResultReceiver receiver;
12299        synchronized (this) {
12300            mPendingAssistExtras.remove(pae);
12301            receiver = pae.receiver;
12302        }
12303        if (receiver != null) {
12304            // Caller wants result sent back to them.
12305            Bundle sendBundle = new Bundle();
12306            // At least return the receiver extras
12307            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12308                    pae.receiverExtras);
12309            try {
12310                pae.receiver.send(0, sendBundle);
12311            } catch (RemoteException e) {
12312            }
12313        }
12314    }
12315
12316    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12317        if (result != null) {
12318            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12319        }
12320        if (pae.hint != null) {
12321            pae.extras.putBoolean(pae.hint, true);
12322        }
12323    }
12324
12325    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12326            AssistContent content, Uri referrer) {
12327        PendingAssistExtras pae = (PendingAssistExtras)token;
12328        synchronized (pae) {
12329            pae.result = extras;
12330            pae.structure = structure;
12331            pae.content = content;
12332            if (referrer != null) {
12333                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12334            }
12335            pae.haveResult = true;
12336            pae.notifyAll();
12337            if (pae.intent == null && pae.receiver == null) {
12338                // Caller is just waiting for the result.
12339                return;
12340            }
12341        }
12342
12343        // We are now ready to launch the assist activity.
12344        IResultReceiver sendReceiver = null;
12345        Bundle sendBundle = null;
12346        synchronized (this) {
12347            buildAssistBundleLocked(pae, extras);
12348            boolean exists = mPendingAssistExtras.remove(pae);
12349            mUiHandler.removeCallbacks(pae);
12350            if (!exists) {
12351                // Timed out.
12352                return;
12353            }
12354            if ((sendReceiver=pae.receiver) != null) {
12355                // Caller wants result sent back to them.
12356                sendBundle = new Bundle();
12357                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12358                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12359                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12360                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12361                        pae.receiverExtras);
12362            }
12363        }
12364        if (sendReceiver != null) {
12365            try {
12366                sendReceiver.send(0, sendBundle);
12367            } catch (RemoteException e) {
12368            }
12369            return;
12370        }
12371
12372        long ident = Binder.clearCallingIdentity();
12373        try {
12374            pae.intent.replaceExtras(pae.extras);
12375            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12376                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12377                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12378            closeSystemDialogs("assist");
12379            try {
12380                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12381            } catch (ActivityNotFoundException e) {
12382                Slog.w(TAG, "No activity to handle assist action.", e);
12383            }
12384        } finally {
12385            Binder.restoreCallingIdentity(ident);
12386        }
12387    }
12388
12389    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12390            Bundle args) {
12391        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12392                true /* focused */, true /* newSessionId */,
12393                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12394    }
12395
12396    public void registerProcessObserver(IProcessObserver observer) {
12397        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12398                "registerProcessObserver()");
12399        synchronized (this) {
12400            mProcessObservers.register(observer);
12401        }
12402    }
12403
12404    @Override
12405    public void unregisterProcessObserver(IProcessObserver observer) {
12406        synchronized (this) {
12407            mProcessObservers.unregister(observer);
12408        }
12409    }
12410
12411    @Override
12412    public void registerUidObserver(IUidObserver observer, int which) {
12413        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12414                "registerUidObserver()");
12415        synchronized (this) {
12416            mUidObservers.register(observer, which);
12417        }
12418    }
12419
12420    @Override
12421    public void unregisterUidObserver(IUidObserver observer) {
12422        synchronized (this) {
12423            mUidObservers.unregister(observer);
12424        }
12425    }
12426
12427    @Override
12428    public boolean convertFromTranslucent(IBinder token) {
12429        final long origId = Binder.clearCallingIdentity();
12430        try {
12431            synchronized (this) {
12432                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12433                if (r == null) {
12434                    return false;
12435                }
12436                final boolean translucentChanged = r.changeWindowTranslucency(true);
12437                if (translucentChanged) {
12438                    r.task.stack.releaseBackgroundResources(r);
12439                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12440                }
12441                mWindowManager.setAppFullscreen(token, true);
12442                return translucentChanged;
12443            }
12444        } finally {
12445            Binder.restoreCallingIdentity(origId);
12446        }
12447    }
12448
12449    @Override
12450    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12451        final long origId = Binder.clearCallingIdentity();
12452        try {
12453            synchronized (this) {
12454                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12455                if (r == null) {
12456                    return false;
12457                }
12458                int index = r.task.mActivities.lastIndexOf(r);
12459                if (index > 0) {
12460                    ActivityRecord under = r.task.mActivities.get(index - 1);
12461                    under.returningOptions = options;
12462                }
12463                final boolean translucentChanged = r.changeWindowTranslucency(false);
12464                if (translucentChanged) {
12465                    r.task.stack.convertActivityToTranslucent(r);
12466                }
12467                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12468                mWindowManager.setAppFullscreen(token, false);
12469                return translucentChanged;
12470            }
12471        } finally {
12472            Binder.restoreCallingIdentity(origId);
12473        }
12474    }
12475
12476    @Override
12477    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12478        final long origId = Binder.clearCallingIdentity();
12479        try {
12480            synchronized (this) {
12481                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12482                if (r != null) {
12483                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12484                }
12485            }
12486            return false;
12487        } finally {
12488            Binder.restoreCallingIdentity(origId);
12489        }
12490    }
12491
12492    @Override
12493    public boolean isBackgroundVisibleBehind(IBinder token) {
12494        final long origId = Binder.clearCallingIdentity();
12495        try {
12496            synchronized (this) {
12497                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12498                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12499                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12500                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12501                return visible;
12502            }
12503        } finally {
12504            Binder.restoreCallingIdentity(origId);
12505        }
12506    }
12507
12508    @Override
12509    public ActivityOptions getActivityOptions(IBinder token) {
12510        final long origId = Binder.clearCallingIdentity();
12511        try {
12512            synchronized (this) {
12513                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12514                if (r != null) {
12515                    final ActivityOptions activityOptions = r.pendingOptions;
12516                    r.pendingOptions = null;
12517                    return activityOptions;
12518                }
12519                return null;
12520            }
12521        } finally {
12522            Binder.restoreCallingIdentity(origId);
12523        }
12524    }
12525
12526    @Override
12527    public void setImmersive(IBinder token, boolean immersive) {
12528        synchronized(this) {
12529            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12530            if (r == null) {
12531                throw new IllegalArgumentException();
12532            }
12533            r.immersive = immersive;
12534
12535            // update associated state if we're frontmost
12536            if (r == mFocusedActivity) {
12537                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12538                applyUpdateLockStateLocked(r);
12539            }
12540        }
12541    }
12542
12543    @Override
12544    public boolean isImmersive(IBinder token) {
12545        synchronized (this) {
12546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12547            if (r == null) {
12548                throw new IllegalArgumentException();
12549            }
12550            return r.immersive;
12551        }
12552    }
12553
12554    public void setVrThread(int tid) {
12555        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12556            throw new UnsupportedOperationException("VR mode not supported on this device!");
12557        }
12558
12559        synchronized (this) {
12560            ProcessRecord proc;
12561            synchronized (mPidsSelfLocked) {
12562                final int pid = Binder.getCallingPid();
12563                proc = mPidsSelfLocked.get(pid);
12564                if (proc != null && mInVrMode && tid >= 0) {
12565                    // ensure the tid belongs to the process
12566                    if (!Process.isThreadInProcess(pid, tid)) {
12567                        throw new IllegalArgumentException("VR thread does not belong to process");
12568                    }
12569                    // reset existing VR thread to CFS
12570                    if (proc.vrThreadTid != 0) {
12571                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12572                    }
12573                    // add check to guarantee that tid belongs to pid?
12574                    proc.vrThreadTid = tid;
12575                    // promote to FIFO now if the tid is non-zero
12576                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12577                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12578                    }
12579                } else {
12580                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12581                }
12582            }
12583        }
12584    }
12585
12586    @Override
12587    public void setRenderThread(int tid) {
12588        synchronized (this) {
12589            ProcessRecord proc;
12590            synchronized (mPidsSelfLocked) {
12591                int pid = Binder.getCallingPid();
12592                proc = mPidsSelfLocked.get(pid);
12593                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12594                    // ensure the tid belongs to the process
12595                    if (!Process.isThreadInProcess(pid, tid)) {
12596                        throw new IllegalArgumentException(
12597                            "Render thread does not belong to process");
12598                    }
12599                    proc.renderThreadTid = tid;
12600                    if (DEBUG_OOM_ADJ) {
12601                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12602                    }
12603                    // promote to FIFO now
12604                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12605                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12606                        if (mUseFifoUiScheduling) {
12607                            Process.setThreadScheduler(proc.renderThreadTid,
12608                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12609                        } else {
12610                            Process.setThreadPriority(proc.renderThreadTid, -10);
12611                        }
12612                    }
12613                } else {
12614                    if (DEBUG_OOM_ADJ) {
12615                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12616                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12617                               mUseFifoUiScheduling);
12618                    }
12619                }
12620            }
12621        }
12622    }
12623
12624    @Override
12625    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12626        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12627            throw new UnsupportedOperationException("VR mode not supported on this device!");
12628        }
12629
12630        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12631
12632        ActivityRecord r;
12633        synchronized (this) {
12634            r = ActivityRecord.isInStackLocked(token);
12635        }
12636
12637        if (r == null) {
12638            throw new IllegalArgumentException();
12639        }
12640
12641        int err;
12642        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12643                VrManagerInternal.NO_ERROR) {
12644            return err;
12645        }
12646
12647        synchronized(this) {
12648            r.requestedVrComponent = (enabled) ? packageName : null;
12649
12650            // Update associated state if this activity is currently focused
12651            if (r == mFocusedActivity) {
12652                applyUpdateVrModeLocked(r);
12653            }
12654            return 0;
12655        }
12656    }
12657
12658    @Override
12659    public boolean isVrModePackageEnabled(ComponentName packageName) {
12660        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12661            throw new UnsupportedOperationException("VR mode not supported on this device!");
12662        }
12663
12664        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12665
12666        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12667                VrManagerInternal.NO_ERROR;
12668    }
12669
12670    public boolean isTopActivityImmersive() {
12671        enforceNotIsolatedCaller("startActivity");
12672        synchronized (this) {
12673            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12674            return (r != null) ? r.immersive : false;
12675        }
12676    }
12677
12678    @Override
12679    public boolean isTopOfTask(IBinder token) {
12680        synchronized (this) {
12681            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12682            if (r == null) {
12683                throw new IllegalArgumentException();
12684            }
12685            return r.task.getTopActivity() == r;
12686        }
12687    }
12688
12689    @Override
12690    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12691        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12692            String msg = "Permission Denial: setHasTopUi() from pid="
12693                    + Binder.getCallingPid()
12694                    + ", uid=" + Binder.getCallingUid()
12695                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12696            Slog.w(TAG, msg);
12697            throw new SecurityException(msg);
12698        }
12699        final int pid = Binder.getCallingPid();
12700        final long origId = Binder.clearCallingIdentity();
12701        try {
12702            synchronized (this) {
12703                boolean changed = false;
12704                ProcessRecord pr;
12705                synchronized (mPidsSelfLocked) {
12706                    pr = mPidsSelfLocked.get(pid);
12707                    if (pr == null) {
12708                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12709                        return;
12710                    }
12711                    if (pr.hasTopUi != hasTopUi) {
12712                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12713                        pr.hasTopUi = hasTopUi;
12714                        changed = true;
12715                    }
12716                }
12717                if (changed) {
12718                    updateOomAdjLocked(pr);
12719                }
12720            }
12721        } finally {
12722            Binder.restoreCallingIdentity(origId);
12723        }
12724    }
12725
12726    public final void enterSafeMode() {
12727        synchronized(this) {
12728            // It only makes sense to do this before the system is ready
12729            // and started launching other packages.
12730            if (!mSystemReady) {
12731                try {
12732                    AppGlobals.getPackageManager().enterSafeMode();
12733                } catch (RemoteException e) {
12734                }
12735            }
12736
12737            mSafeMode = true;
12738        }
12739    }
12740
12741    public final void showSafeModeOverlay() {
12742        View v = LayoutInflater.from(mContext).inflate(
12743                com.android.internal.R.layout.safe_mode, null);
12744        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12745        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12746        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12747        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12748        lp.gravity = Gravity.BOTTOM | Gravity.START;
12749        lp.format = v.getBackground().getOpacity();
12750        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12751                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12752        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12753        ((WindowManager)mContext.getSystemService(
12754                Context.WINDOW_SERVICE)).addView(v, lp);
12755    }
12756
12757    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12758        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12759            return;
12760        }
12761        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12762        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12763        synchronized (stats) {
12764            if (mBatteryStatsService.isOnBattery()) {
12765                mBatteryStatsService.enforceCallingPermission();
12766                int MY_UID = Binder.getCallingUid();
12767                final int uid;
12768                if (sender == null) {
12769                    uid = sourceUid;
12770                } else {
12771                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12772                }
12773                BatteryStatsImpl.Uid.Pkg pkg =
12774                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12775                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12776                pkg.noteWakeupAlarmLocked(tag);
12777            }
12778        }
12779    }
12780
12781    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12782        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12783            return;
12784        }
12785        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12786        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12787        synchronized (stats) {
12788            mBatteryStatsService.enforceCallingPermission();
12789            int MY_UID = Binder.getCallingUid();
12790            final int uid;
12791            if (sender == null) {
12792                uid = sourceUid;
12793            } else {
12794                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12795            }
12796            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12797        }
12798    }
12799
12800    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12801        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12802            return;
12803        }
12804        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12805        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12806        synchronized (stats) {
12807            mBatteryStatsService.enforceCallingPermission();
12808            int MY_UID = Binder.getCallingUid();
12809            final int uid;
12810            if (sender == null) {
12811                uid = sourceUid;
12812            } else {
12813                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12814            }
12815            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12816        }
12817    }
12818
12819    public boolean killPids(int[] pids, String pReason, boolean secure) {
12820        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12821            throw new SecurityException("killPids only available to the system");
12822        }
12823        String reason = (pReason == null) ? "Unknown" : pReason;
12824        // XXX Note: don't acquire main activity lock here, because the window
12825        // manager calls in with its locks held.
12826
12827        boolean killed = false;
12828        synchronized (mPidsSelfLocked) {
12829            int worstType = 0;
12830            for (int i=0; i<pids.length; i++) {
12831                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12832                if (proc != null) {
12833                    int type = proc.setAdj;
12834                    if (type > worstType) {
12835                        worstType = type;
12836                    }
12837                }
12838            }
12839
12840            // If the worst oom_adj is somewhere in the cached proc LRU range,
12841            // then constrain it so we will kill all cached procs.
12842            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12843                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12844                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12845            }
12846
12847            // If this is not a secure call, don't let it kill processes that
12848            // are important.
12849            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12850                worstType = ProcessList.SERVICE_ADJ;
12851            }
12852
12853            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12854            for (int i=0; i<pids.length; i++) {
12855                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12856                if (proc == null) {
12857                    continue;
12858                }
12859                int adj = proc.setAdj;
12860                if (adj >= worstType && !proc.killedByAm) {
12861                    proc.kill(reason, true);
12862                    killed = true;
12863                }
12864            }
12865        }
12866        return killed;
12867    }
12868
12869    @Override
12870    public void killUid(int appId, int userId, String reason) {
12871        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12872        synchronized (this) {
12873            final long identity = Binder.clearCallingIdentity();
12874            try {
12875                killPackageProcessesLocked(null, appId, userId,
12876                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12877                        reason != null ? reason : "kill uid");
12878            } finally {
12879                Binder.restoreCallingIdentity(identity);
12880            }
12881        }
12882    }
12883
12884    @Override
12885    public boolean killProcessesBelowForeground(String reason) {
12886        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12887            throw new SecurityException("killProcessesBelowForeground() only available to system");
12888        }
12889
12890        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12891    }
12892
12893    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12894        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12895            throw new SecurityException("killProcessesBelowAdj() only available to system");
12896        }
12897
12898        boolean killed = false;
12899        synchronized (mPidsSelfLocked) {
12900            final int size = mPidsSelfLocked.size();
12901            for (int i = 0; i < size; i++) {
12902                final int pid = mPidsSelfLocked.keyAt(i);
12903                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12904                if (proc == null) continue;
12905
12906                final int adj = proc.setAdj;
12907                if (adj > belowAdj && !proc.killedByAm) {
12908                    proc.kill(reason, true);
12909                    killed = true;
12910                }
12911            }
12912        }
12913        return killed;
12914    }
12915
12916    @Override
12917    public void hang(final IBinder who, boolean allowRestart) {
12918        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12919                != PackageManager.PERMISSION_GRANTED) {
12920            throw new SecurityException("Requires permission "
12921                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12922        }
12923
12924        final IBinder.DeathRecipient death = new DeathRecipient() {
12925            @Override
12926            public void binderDied() {
12927                synchronized (this) {
12928                    notifyAll();
12929                }
12930            }
12931        };
12932
12933        try {
12934            who.linkToDeath(death, 0);
12935        } catch (RemoteException e) {
12936            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12937            return;
12938        }
12939
12940        synchronized (this) {
12941            Watchdog.getInstance().setAllowRestart(allowRestart);
12942            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12943            synchronized (death) {
12944                while (who.isBinderAlive()) {
12945                    try {
12946                        death.wait();
12947                    } catch (InterruptedException e) {
12948                    }
12949                }
12950            }
12951            Watchdog.getInstance().setAllowRestart(true);
12952        }
12953    }
12954
12955    @Override
12956    public void restart() {
12957        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12958                != PackageManager.PERMISSION_GRANTED) {
12959            throw new SecurityException("Requires permission "
12960                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12961        }
12962
12963        Log.i(TAG, "Sending shutdown broadcast...");
12964
12965        BroadcastReceiver br = new BroadcastReceiver() {
12966            @Override public void onReceive(Context context, Intent intent) {
12967                // Now the broadcast is done, finish up the low-level shutdown.
12968                Log.i(TAG, "Shutting down activity manager...");
12969                shutdown(10000);
12970                Log.i(TAG, "Shutdown complete, restarting!");
12971                Process.killProcess(Process.myPid());
12972                System.exit(10);
12973            }
12974        };
12975
12976        // First send the high-level shut down broadcast.
12977        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12978        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12979        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12980        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12981        mContext.sendOrderedBroadcastAsUser(intent,
12982                UserHandle.ALL, null, br, mHandler, 0, null, null);
12983        */
12984        br.onReceive(mContext, intent);
12985    }
12986
12987    private long getLowRamTimeSinceIdle(long now) {
12988        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12989    }
12990
12991    @Override
12992    public void performIdleMaintenance() {
12993        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12994                != PackageManager.PERMISSION_GRANTED) {
12995            throw new SecurityException("Requires permission "
12996                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12997        }
12998
12999        synchronized (this) {
13000            final long now = SystemClock.uptimeMillis();
13001            final long timeSinceLastIdle = now - mLastIdleTime;
13002            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13003            mLastIdleTime = now;
13004            mLowRamTimeSinceLastIdle = 0;
13005            if (mLowRamStartTime != 0) {
13006                mLowRamStartTime = now;
13007            }
13008
13009            StringBuilder sb = new StringBuilder(128);
13010            sb.append("Idle maintenance over ");
13011            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13012            sb.append(" low RAM for ");
13013            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13014            Slog.i(TAG, sb.toString());
13015
13016            // If at least 1/3 of our time since the last idle period has been spent
13017            // with RAM low, then we want to kill processes.
13018            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13019
13020            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13021                ProcessRecord proc = mLruProcesses.get(i);
13022                if (proc.notCachedSinceIdle) {
13023                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13024                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13025                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13026                        if (doKilling && proc.initialIdlePss != 0
13027                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13028                            sb = new StringBuilder(128);
13029                            sb.append("Kill");
13030                            sb.append(proc.processName);
13031                            sb.append(" in idle maint: pss=");
13032                            sb.append(proc.lastPss);
13033                            sb.append(", swapPss=");
13034                            sb.append(proc.lastSwapPss);
13035                            sb.append(", initialPss=");
13036                            sb.append(proc.initialIdlePss);
13037                            sb.append(", period=");
13038                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13039                            sb.append(", lowRamPeriod=");
13040                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13041                            Slog.wtfQuiet(TAG, sb.toString());
13042                            proc.kill("idle maint (pss " + proc.lastPss
13043                                    + " from " + proc.initialIdlePss + ")", true);
13044                        }
13045                    }
13046                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13047                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13048                    proc.notCachedSinceIdle = true;
13049                    proc.initialIdlePss = 0;
13050                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13051                            mTestPssMode, isSleepingLocked(), now);
13052                }
13053            }
13054
13055            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13056            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13057        }
13058    }
13059
13060    @Override
13061    public void sendIdleJobTrigger() {
13062        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13063                != PackageManager.PERMISSION_GRANTED) {
13064            throw new SecurityException("Requires permission "
13065                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13066        }
13067
13068        final long ident = Binder.clearCallingIdentity();
13069        try {
13070            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13071                    .setPackage("android")
13072                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13073            broadcastIntent(null, intent, null, null, 0, null, null, null,
13074                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13075        } finally {
13076            Binder.restoreCallingIdentity(ident);
13077        }
13078    }
13079
13080    private void retrieveSettings() {
13081        final ContentResolver resolver = mContext.getContentResolver();
13082        final boolean freeformWindowManagement =
13083                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13084                        || Settings.Global.getInt(
13085                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13086        final boolean supportsPictureInPicture =
13087                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13088
13089        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13090        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13091        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13092        final boolean alwaysFinishActivities =
13093                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13094        final boolean lenientBackgroundCheck =
13095                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13096        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13097        final boolean forceResizable = Settings.Global.getInt(
13098                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13099        final boolean supportsLeanbackOnly =
13100                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13101
13102        // Transfer any global setting for forcing RTL layout, into a System Property
13103        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13104
13105        final Configuration configuration = new Configuration();
13106        Settings.System.getConfiguration(resolver, configuration);
13107        if (forceRtl) {
13108            // This will take care of setting the correct layout direction flags
13109            configuration.setLayoutDirection(configuration.locale);
13110        }
13111
13112        synchronized (this) {
13113            mDebugApp = mOrigDebugApp = debugApp;
13114            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13115            mAlwaysFinishActivities = alwaysFinishActivities;
13116            mLenientBackgroundCheck = lenientBackgroundCheck;
13117            mSupportsLeanbackOnly = supportsLeanbackOnly;
13118            mForceResizableActivities = forceResizable;
13119            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13120            if (supportsMultiWindow || forceResizable) {
13121                mSupportsMultiWindow = true;
13122                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13123                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13124            } else {
13125                mSupportsMultiWindow = false;
13126                mSupportsFreeformWindowManagement = false;
13127                mSupportsPictureInPicture = false;
13128            }
13129            // This happens before any activities are started, so we can
13130            // change mConfiguration in-place.
13131            updateConfigurationLocked(configuration, null, true);
13132            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13133                    "Initial config: " + mConfiguration);
13134
13135            // Load resources only after the current configuration has been set.
13136            final Resources res = mContext.getResources();
13137            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13138            mThumbnailWidth = res.getDimensionPixelSize(
13139                    com.android.internal.R.dimen.thumbnail_width);
13140            mThumbnailHeight = res.getDimensionPixelSize(
13141                    com.android.internal.R.dimen.thumbnail_height);
13142            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13143                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13144            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13145                    com.android.internal.R.string.config_appsNotReportingCrashes));
13146            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13147                mFullscreenThumbnailScale = (float) res
13148                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13149                    (float) mConfiguration.screenWidthDp;
13150            } else {
13151                mFullscreenThumbnailScale = res.getFraction(
13152                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13153            }
13154        }
13155    }
13156
13157    public boolean testIsSystemReady() {
13158        // no need to synchronize(this) just to read & return the value
13159        return mSystemReady;
13160    }
13161
13162    public void systemReady(final Runnable goingCallback) {
13163        synchronized(this) {
13164            if (mSystemReady) {
13165                // If we're done calling all the receivers, run the next "boot phase" passed in
13166                // by the SystemServer
13167                if (goingCallback != null) {
13168                    goingCallback.run();
13169                }
13170                return;
13171            }
13172
13173            mLocalDeviceIdleController
13174                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13175
13176            // Make sure we have the current profile info, since it is needed for security checks.
13177            mUserController.onSystemReady();
13178            mRecentTasks.onSystemReadyLocked();
13179            mAppOpsService.systemReady();
13180            mSystemReady = true;
13181        }
13182
13183        ArrayList<ProcessRecord> procsToKill = null;
13184        synchronized(mPidsSelfLocked) {
13185            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13186                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13187                if (!isAllowedWhileBooting(proc.info)){
13188                    if (procsToKill == null) {
13189                        procsToKill = new ArrayList<ProcessRecord>();
13190                    }
13191                    procsToKill.add(proc);
13192                }
13193            }
13194        }
13195
13196        synchronized(this) {
13197            if (procsToKill != null) {
13198                for (int i=procsToKill.size()-1; i>=0; i--) {
13199                    ProcessRecord proc = procsToKill.get(i);
13200                    Slog.i(TAG, "Removing system update proc: " + proc);
13201                    removeProcessLocked(proc, true, false, "system update done");
13202                }
13203            }
13204
13205            // Now that we have cleaned up any update processes, we
13206            // are ready to start launching real processes and know that
13207            // we won't trample on them any more.
13208            mProcessesReady = true;
13209        }
13210
13211        Slog.i(TAG, "System now ready");
13212        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13213            SystemClock.uptimeMillis());
13214
13215        synchronized(this) {
13216            // Make sure we have no pre-ready processes sitting around.
13217
13218            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13219                ResolveInfo ri = mContext.getPackageManager()
13220                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13221                                STOCK_PM_FLAGS);
13222                CharSequence errorMsg = null;
13223                if (ri != null) {
13224                    ActivityInfo ai = ri.activityInfo;
13225                    ApplicationInfo app = ai.applicationInfo;
13226                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13227                        mTopAction = Intent.ACTION_FACTORY_TEST;
13228                        mTopData = null;
13229                        mTopComponent = new ComponentName(app.packageName,
13230                                ai.name);
13231                    } else {
13232                        errorMsg = mContext.getResources().getText(
13233                                com.android.internal.R.string.factorytest_not_system);
13234                    }
13235                } else {
13236                    errorMsg = mContext.getResources().getText(
13237                            com.android.internal.R.string.factorytest_no_action);
13238                }
13239                if (errorMsg != null) {
13240                    mTopAction = null;
13241                    mTopData = null;
13242                    mTopComponent = null;
13243                    Message msg = Message.obtain();
13244                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13245                    msg.getData().putCharSequence("msg", errorMsg);
13246                    mUiHandler.sendMessage(msg);
13247                }
13248            }
13249        }
13250
13251        retrieveSettings();
13252        final int currentUserId;
13253        synchronized (this) {
13254            currentUserId = mUserController.getCurrentUserIdLocked();
13255            readGrantedUriPermissionsLocked();
13256        }
13257
13258        if (goingCallback != null) goingCallback.run();
13259
13260        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13261                Integer.toString(currentUserId), currentUserId);
13262        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13263                Integer.toString(currentUserId), currentUserId);
13264        mSystemServiceManager.startUser(currentUserId);
13265
13266        synchronized (this) {
13267            // Only start up encryption-aware persistent apps; once user is
13268            // unlocked we'll come back around and start unaware apps
13269            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13270
13271            // Start up initial activity.
13272            mBooting = true;
13273            // Enable home activity for system user, so that the system can always boot
13274            if (UserManager.isSplitSystemUser()) {
13275                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13276                try {
13277                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13278                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13279                            UserHandle.USER_SYSTEM);
13280                } catch (RemoteException e) {
13281                    throw e.rethrowAsRuntimeException();
13282                }
13283            }
13284            startHomeActivityLocked(currentUserId, "systemReady");
13285
13286            try {
13287                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13288                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13289                            + " data partition or your device will be unstable.");
13290                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13291                }
13292            } catch (RemoteException e) {
13293            }
13294
13295            if (!Build.isBuildConsistent()) {
13296                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13297                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13298            }
13299
13300            long ident = Binder.clearCallingIdentity();
13301            try {
13302                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13304                        | Intent.FLAG_RECEIVER_FOREGROUND);
13305                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13306                broadcastIntentLocked(null, null, intent,
13307                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13308                        null, false, false, MY_PID, Process.SYSTEM_UID,
13309                        currentUserId);
13310                intent = new Intent(Intent.ACTION_USER_STARTING);
13311                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13312                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13313                broadcastIntentLocked(null, null, intent,
13314                        null, new IIntentReceiver.Stub() {
13315                            @Override
13316                            public void performReceive(Intent intent, int resultCode, String data,
13317                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13318                                    throws RemoteException {
13319                            }
13320                        }, 0, null, null,
13321                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13322                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13323            } catch (Throwable t) {
13324                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13325            } finally {
13326                Binder.restoreCallingIdentity(ident);
13327            }
13328            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13329            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13330        }
13331    }
13332
13333    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13334        synchronized (this) {
13335            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13336        }
13337    }
13338
13339    void skipCurrentReceiverLocked(ProcessRecord app) {
13340        for (BroadcastQueue queue : mBroadcastQueues) {
13341            queue.skipCurrentReceiverLocked(app);
13342        }
13343    }
13344
13345    /**
13346     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13347     * The application process will exit immediately after this call returns.
13348     * @param app object of the crashing app, null for the system server
13349     * @param crashInfo describing the exception
13350     */
13351    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13352        ProcessRecord r = findAppProcess(app, "Crash");
13353        final String processName = app == null ? "system_server"
13354                : (r == null ? "unknown" : r.processName);
13355
13356        handleApplicationCrashInner("crash", r, processName, crashInfo);
13357    }
13358
13359    /* Native crash reporting uses this inner version because it needs to be somewhat
13360     * decoupled from the AM-managed cleanup lifecycle
13361     */
13362    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13363            ApplicationErrorReport.CrashInfo crashInfo) {
13364        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13365                UserHandle.getUserId(Binder.getCallingUid()), processName,
13366                r == null ? -1 : r.info.flags,
13367                crashInfo.exceptionClassName,
13368                crashInfo.exceptionMessage,
13369                crashInfo.throwFileName,
13370                crashInfo.throwLineNumber);
13371
13372        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13373
13374        mAppErrors.crashApplication(r, crashInfo);
13375    }
13376
13377    public void handleApplicationStrictModeViolation(
13378            IBinder app,
13379            int violationMask,
13380            StrictMode.ViolationInfo info) {
13381        ProcessRecord r = findAppProcess(app, "StrictMode");
13382        if (r == null) {
13383            return;
13384        }
13385
13386        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13387            Integer stackFingerprint = info.hashCode();
13388            boolean logIt = true;
13389            synchronized (mAlreadyLoggedViolatedStacks) {
13390                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13391                    logIt = false;
13392                    // TODO: sub-sample into EventLog for these, with
13393                    // the info.durationMillis?  Then we'd get
13394                    // the relative pain numbers, without logging all
13395                    // the stack traces repeatedly.  We'd want to do
13396                    // likewise in the client code, which also does
13397                    // dup suppression, before the Binder call.
13398                } else {
13399                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13400                        mAlreadyLoggedViolatedStacks.clear();
13401                    }
13402                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13403                }
13404            }
13405            if (logIt) {
13406                logStrictModeViolationToDropBox(r, info);
13407            }
13408        }
13409
13410        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13411            AppErrorResult result = new AppErrorResult();
13412            synchronized (this) {
13413                final long origId = Binder.clearCallingIdentity();
13414
13415                Message msg = Message.obtain();
13416                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13417                HashMap<String, Object> data = new HashMap<String, Object>();
13418                data.put("result", result);
13419                data.put("app", r);
13420                data.put("violationMask", violationMask);
13421                data.put("info", info);
13422                msg.obj = data;
13423                mUiHandler.sendMessage(msg);
13424
13425                Binder.restoreCallingIdentity(origId);
13426            }
13427            int res = result.get();
13428            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13429        }
13430    }
13431
13432    // Depending on the policy in effect, there could be a bunch of
13433    // these in quick succession so we try to batch these together to
13434    // minimize disk writes, number of dropbox entries, and maximize
13435    // compression, by having more fewer, larger records.
13436    private void logStrictModeViolationToDropBox(
13437            ProcessRecord process,
13438            StrictMode.ViolationInfo info) {
13439        if (info == null) {
13440            return;
13441        }
13442        final boolean isSystemApp = process == null ||
13443                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13444                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13445        final String processName = process == null ? "unknown" : process.processName;
13446        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13447        final DropBoxManager dbox = (DropBoxManager)
13448                mContext.getSystemService(Context.DROPBOX_SERVICE);
13449
13450        // Exit early if the dropbox isn't configured to accept this report type.
13451        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13452
13453        boolean bufferWasEmpty;
13454        boolean needsFlush;
13455        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13456        synchronized (sb) {
13457            bufferWasEmpty = sb.length() == 0;
13458            appendDropBoxProcessHeaders(process, processName, sb);
13459            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13460            sb.append("System-App: ").append(isSystemApp).append("\n");
13461            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13462            if (info.violationNumThisLoop != 0) {
13463                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13464            }
13465            if (info.numAnimationsRunning != 0) {
13466                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13467            }
13468            if (info.broadcastIntentAction != null) {
13469                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13470            }
13471            if (info.durationMillis != -1) {
13472                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13473            }
13474            if (info.numInstances != -1) {
13475                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13476            }
13477            if (info.tags != null) {
13478                for (String tag : info.tags) {
13479                    sb.append("Span-Tag: ").append(tag).append("\n");
13480                }
13481            }
13482            sb.append("\n");
13483            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13484                sb.append(info.crashInfo.stackTrace);
13485                sb.append("\n");
13486            }
13487            if (info.message != null) {
13488                sb.append(info.message);
13489                sb.append("\n");
13490            }
13491
13492            // Only buffer up to ~64k.  Various logging bits truncate
13493            // things at 128k.
13494            needsFlush = (sb.length() > 64 * 1024);
13495        }
13496
13497        // Flush immediately if the buffer's grown too large, or this
13498        // is a non-system app.  Non-system apps are isolated with a
13499        // different tag & policy and not batched.
13500        //
13501        // Batching is useful during internal testing with
13502        // StrictMode settings turned up high.  Without batching,
13503        // thousands of separate files could be created on boot.
13504        if (!isSystemApp || needsFlush) {
13505            new Thread("Error dump: " + dropboxTag) {
13506                @Override
13507                public void run() {
13508                    String report;
13509                    synchronized (sb) {
13510                        report = sb.toString();
13511                        sb.delete(0, sb.length());
13512                        sb.trimToSize();
13513                    }
13514                    if (report.length() != 0) {
13515                        dbox.addText(dropboxTag, report);
13516                    }
13517                }
13518            }.start();
13519            return;
13520        }
13521
13522        // System app batching:
13523        if (!bufferWasEmpty) {
13524            // An existing dropbox-writing thread is outstanding, so
13525            // we don't need to start it up.  The existing thread will
13526            // catch the buffer appends we just did.
13527            return;
13528        }
13529
13530        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13531        // (After this point, we shouldn't access AMS internal data structures.)
13532        new Thread("Error dump: " + dropboxTag) {
13533            @Override
13534            public void run() {
13535                // 5 second sleep to let stacks arrive and be batched together
13536                try {
13537                    Thread.sleep(5000);  // 5 seconds
13538                } catch (InterruptedException e) {}
13539
13540                String errorReport;
13541                synchronized (mStrictModeBuffer) {
13542                    errorReport = mStrictModeBuffer.toString();
13543                    if (errorReport.length() == 0) {
13544                        return;
13545                    }
13546                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13547                    mStrictModeBuffer.trimToSize();
13548                }
13549                dbox.addText(dropboxTag, errorReport);
13550            }
13551        }.start();
13552    }
13553
13554    /**
13555     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13556     * @param app object of the crashing app, null for the system server
13557     * @param tag reported by the caller
13558     * @param system whether this wtf is coming from the system
13559     * @param crashInfo describing the context of the error
13560     * @return true if the process should exit immediately (WTF is fatal)
13561     */
13562    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13563            final ApplicationErrorReport.CrashInfo crashInfo) {
13564        final int callingUid = Binder.getCallingUid();
13565        final int callingPid = Binder.getCallingPid();
13566
13567        if (system) {
13568            // If this is coming from the system, we could very well have low-level
13569            // system locks held, so we want to do this all asynchronously.  And we
13570            // never want this to become fatal, so there is that too.
13571            mHandler.post(new Runnable() {
13572                @Override public void run() {
13573                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13574                }
13575            });
13576            return false;
13577        }
13578
13579        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13580                crashInfo);
13581
13582        if (r != null && r.pid != Process.myPid() &&
13583                Settings.Global.getInt(mContext.getContentResolver(),
13584                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13585            mAppErrors.crashApplication(r, crashInfo);
13586            return true;
13587        } else {
13588            return false;
13589        }
13590    }
13591
13592    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13593            final ApplicationErrorReport.CrashInfo crashInfo) {
13594        final ProcessRecord r = findAppProcess(app, "WTF");
13595        final String processName = app == null ? "system_server"
13596                : (r == null ? "unknown" : r.processName);
13597
13598        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13599                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13600
13601        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13602
13603        return r;
13604    }
13605
13606    /**
13607     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13608     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13609     */
13610    private ProcessRecord findAppProcess(IBinder app, String reason) {
13611        if (app == null) {
13612            return null;
13613        }
13614
13615        synchronized (this) {
13616            final int NP = mProcessNames.getMap().size();
13617            for (int ip=0; ip<NP; ip++) {
13618                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13619                final int NA = apps.size();
13620                for (int ia=0; ia<NA; ia++) {
13621                    ProcessRecord p = apps.valueAt(ia);
13622                    if (p.thread != null && p.thread.asBinder() == app) {
13623                        return p;
13624                    }
13625                }
13626            }
13627
13628            Slog.w(TAG, "Can't find mystery application for " + reason
13629                    + " from pid=" + Binder.getCallingPid()
13630                    + " uid=" + Binder.getCallingUid() + ": " + app);
13631            return null;
13632        }
13633    }
13634
13635    /**
13636     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13637     * to append various headers to the dropbox log text.
13638     */
13639    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13640            StringBuilder sb) {
13641        // Watchdog thread ends up invoking this function (with
13642        // a null ProcessRecord) to add the stack file to dropbox.
13643        // Do not acquire a lock on this (am) in such cases, as it
13644        // could cause a potential deadlock, if and when watchdog
13645        // is invoked due to unavailability of lock on am and it
13646        // would prevent watchdog from killing system_server.
13647        if (process == null) {
13648            sb.append("Process: ").append(processName).append("\n");
13649            return;
13650        }
13651        // Note: ProcessRecord 'process' is guarded by the service
13652        // instance.  (notably process.pkgList, which could otherwise change
13653        // concurrently during execution of this method)
13654        synchronized (this) {
13655            sb.append("Process: ").append(processName).append("\n");
13656            int flags = process.info.flags;
13657            IPackageManager pm = AppGlobals.getPackageManager();
13658            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13659            for (int ip=0; ip<process.pkgList.size(); ip++) {
13660                String pkg = process.pkgList.keyAt(ip);
13661                sb.append("Package: ").append(pkg);
13662                try {
13663                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13664                    if (pi != null) {
13665                        sb.append(" v").append(pi.versionCode);
13666                        if (pi.versionName != null) {
13667                            sb.append(" (").append(pi.versionName).append(")");
13668                        }
13669                    }
13670                } catch (RemoteException e) {
13671                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13672                }
13673                sb.append("\n");
13674            }
13675        }
13676    }
13677
13678    private static String processClass(ProcessRecord process) {
13679        if (process == null || process.pid == MY_PID) {
13680            return "system_server";
13681        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13682            return "system_app";
13683        } else {
13684            return "data_app";
13685        }
13686    }
13687
13688    private volatile long mWtfClusterStart;
13689    private volatile int mWtfClusterCount;
13690
13691    /**
13692     * Write a description of an error (crash, WTF, ANR) to the drop box.
13693     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13694     * @param process which caused the error, null means the system server
13695     * @param activity which triggered the error, null if unknown
13696     * @param parent activity related to the error, null if unknown
13697     * @param subject line related to the error, null if absent
13698     * @param report in long form describing the error, null if absent
13699     * @param dataFile text file to include in the report, null if none
13700     * @param crashInfo giving an application stack trace, null if absent
13701     */
13702    public void addErrorToDropBox(String eventType,
13703            ProcessRecord process, String processName, ActivityRecord activity,
13704            ActivityRecord parent, String subject,
13705            final String report, final File dataFile,
13706            final ApplicationErrorReport.CrashInfo crashInfo) {
13707        // NOTE -- this must never acquire the ActivityManagerService lock,
13708        // otherwise the watchdog may be prevented from resetting the system.
13709
13710        final String dropboxTag = processClass(process) + "_" + eventType;
13711        final DropBoxManager dbox = (DropBoxManager)
13712                mContext.getSystemService(Context.DROPBOX_SERVICE);
13713
13714        // Exit early if the dropbox isn't configured to accept this report type.
13715        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13716
13717        // Rate-limit how often we're willing to do the heavy lifting below to
13718        // collect and record logs; currently 5 logs per 10 second period.
13719        final long now = SystemClock.elapsedRealtime();
13720        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13721            mWtfClusterStart = now;
13722            mWtfClusterCount = 1;
13723        } else {
13724            if (mWtfClusterCount++ >= 5) return;
13725        }
13726
13727        final StringBuilder sb = new StringBuilder(1024);
13728        appendDropBoxProcessHeaders(process, processName, sb);
13729        if (process != null) {
13730            sb.append("Foreground: ")
13731                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13732                    .append("\n");
13733        }
13734        if (activity != null) {
13735            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13736        }
13737        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13738            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13739        }
13740        if (parent != null && parent != activity) {
13741            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13742        }
13743        if (subject != null) {
13744            sb.append("Subject: ").append(subject).append("\n");
13745        }
13746        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13747        if (Debug.isDebuggerConnected()) {
13748            sb.append("Debugger: Connected\n");
13749        }
13750        sb.append("\n");
13751
13752        // Do the rest in a worker thread to avoid blocking the caller on I/O
13753        // (After this point, we shouldn't access AMS internal data structures.)
13754        Thread worker = new Thread("Error dump: " + dropboxTag) {
13755            @Override
13756            public void run() {
13757                if (report != null) {
13758                    sb.append(report);
13759                }
13760
13761                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13762                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13763                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13764                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13765
13766                if (dataFile != null && maxDataFileSize > 0) {
13767                    try {
13768                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13769                                    "\n\n[[TRUNCATED]]"));
13770                    } catch (IOException e) {
13771                        Slog.e(TAG, "Error reading " + dataFile, e);
13772                    }
13773                }
13774                if (crashInfo != null && crashInfo.stackTrace != null) {
13775                    sb.append(crashInfo.stackTrace);
13776                }
13777
13778                if (lines > 0) {
13779                    sb.append("\n");
13780
13781                    // Merge several logcat streams, and take the last N lines
13782                    InputStreamReader input = null;
13783                    try {
13784                        java.lang.Process logcat = new ProcessBuilder(
13785                                "/system/bin/timeout", "-k", "15s", "10s",
13786                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13787                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13788                                        .redirectErrorStream(true).start();
13789
13790                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13791                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13792                        input = new InputStreamReader(logcat.getInputStream());
13793
13794                        int num;
13795                        char[] buf = new char[8192];
13796                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13797                    } catch (IOException e) {
13798                        Slog.e(TAG, "Error running logcat", e);
13799                    } finally {
13800                        if (input != null) try { input.close(); } catch (IOException e) {}
13801                    }
13802                }
13803
13804                dbox.addText(dropboxTag, sb.toString());
13805            }
13806        };
13807
13808        if (process == null) {
13809            // If process is null, we are being called from some internal code
13810            // and may be about to die -- run this synchronously.
13811            worker.run();
13812        } else {
13813            worker.start();
13814        }
13815    }
13816
13817    @Override
13818    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13819        enforceNotIsolatedCaller("getProcessesInErrorState");
13820        // assume our apps are happy - lazy create the list
13821        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13822
13823        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13824                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13825        int userId = UserHandle.getUserId(Binder.getCallingUid());
13826
13827        synchronized (this) {
13828
13829            // iterate across all processes
13830            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13831                ProcessRecord app = mLruProcesses.get(i);
13832                if (!allUsers && app.userId != userId) {
13833                    continue;
13834                }
13835                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13836                    // This one's in trouble, so we'll generate a report for it
13837                    // crashes are higher priority (in case there's a crash *and* an anr)
13838                    ActivityManager.ProcessErrorStateInfo report = null;
13839                    if (app.crashing) {
13840                        report = app.crashingReport;
13841                    } else if (app.notResponding) {
13842                        report = app.notRespondingReport;
13843                    }
13844
13845                    if (report != null) {
13846                        if (errList == null) {
13847                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13848                        }
13849                        errList.add(report);
13850                    } else {
13851                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13852                                " crashing = " + app.crashing +
13853                                " notResponding = " + app.notResponding);
13854                    }
13855                }
13856            }
13857        }
13858
13859        return errList;
13860    }
13861
13862    static int procStateToImportance(int procState, int memAdj,
13863            ActivityManager.RunningAppProcessInfo currApp) {
13864        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13865        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13866            currApp.lru = memAdj;
13867        } else {
13868            currApp.lru = 0;
13869        }
13870        return imp;
13871    }
13872
13873    private void fillInProcMemInfo(ProcessRecord app,
13874            ActivityManager.RunningAppProcessInfo outInfo) {
13875        outInfo.pid = app.pid;
13876        outInfo.uid = app.info.uid;
13877        if (mHeavyWeightProcess == app) {
13878            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13879        }
13880        if (app.persistent) {
13881            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13882        }
13883        if (app.activities.size() > 0) {
13884            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13885        }
13886        outInfo.lastTrimLevel = app.trimMemoryLevel;
13887        int adj = app.curAdj;
13888        int procState = app.curProcState;
13889        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13890        outInfo.importanceReasonCode = app.adjTypeCode;
13891        outInfo.processState = app.curProcState;
13892    }
13893
13894    @Override
13895    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13896        enforceNotIsolatedCaller("getRunningAppProcesses");
13897
13898        final int callingUid = Binder.getCallingUid();
13899
13900        // Lazy instantiation of list
13901        List<ActivityManager.RunningAppProcessInfo> runList = null;
13902        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13903                callingUid) == PackageManager.PERMISSION_GRANTED;
13904        final int userId = UserHandle.getUserId(callingUid);
13905        final boolean allUids = isGetTasksAllowed(
13906                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13907
13908        synchronized (this) {
13909            // Iterate across all processes
13910            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13911                ProcessRecord app = mLruProcesses.get(i);
13912                if ((!allUsers && app.userId != userId)
13913                        || (!allUids && app.uid != callingUid)) {
13914                    continue;
13915                }
13916                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13917                    // Generate process state info for running application
13918                    ActivityManager.RunningAppProcessInfo currApp =
13919                        new ActivityManager.RunningAppProcessInfo(app.processName,
13920                                app.pid, app.getPackageList());
13921                    fillInProcMemInfo(app, currApp);
13922                    if (app.adjSource instanceof ProcessRecord) {
13923                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13924                        currApp.importanceReasonImportance =
13925                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13926                                        app.adjSourceProcState);
13927                    } else if (app.adjSource instanceof ActivityRecord) {
13928                        ActivityRecord r = (ActivityRecord)app.adjSource;
13929                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13930                    }
13931                    if (app.adjTarget instanceof ComponentName) {
13932                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13933                    }
13934                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13935                    //        + " lru=" + currApp.lru);
13936                    if (runList == null) {
13937                        runList = new ArrayList<>();
13938                    }
13939                    runList.add(currApp);
13940                }
13941            }
13942        }
13943        return runList;
13944    }
13945
13946    @Override
13947    public List<ApplicationInfo> getRunningExternalApplications() {
13948        enforceNotIsolatedCaller("getRunningExternalApplications");
13949        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13950        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13951        if (runningApps != null && runningApps.size() > 0) {
13952            Set<String> extList = new HashSet<String>();
13953            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13954                if (app.pkgList != null) {
13955                    for (String pkg : app.pkgList) {
13956                        extList.add(pkg);
13957                    }
13958                }
13959            }
13960            IPackageManager pm = AppGlobals.getPackageManager();
13961            for (String pkg : extList) {
13962                try {
13963                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13964                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13965                        retList.add(info);
13966                    }
13967                } catch (RemoteException e) {
13968                }
13969            }
13970        }
13971        return retList;
13972    }
13973
13974    @Override
13975    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13976        enforceNotIsolatedCaller("getMyMemoryState");
13977        synchronized (this) {
13978            ProcessRecord proc;
13979            synchronized (mPidsSelfLocked) {
13980                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13981            }
13982            fillInProcMemInfo(proc, outInfo);
13983        }
13984    }
13985
13986    @Override
13987    public int getMemoryTrimLevel() {
13988        enforceNotIsolatedCaller("getMyMemoryState");
13989        synchronized (this) {
13990            return mLastMemoryLevel;
13991        }
13992    }
13993
13994    @Override
13995    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13996            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13997        (new ActivityManagerShellCommand(this, false)).exec(
13998                this, in, out, err, args, resultReceiver);
13999    }
14000
14001    @Override
14002    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14003        if (checkCallingPermission(android.Manifest.permission.DUMP)
14004                != PackageManager.PERMISSION_GRANTED) {
14005            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14006                    + Binder.getCallingPid()
14007                    + ", uid=" + Binder.getCallingUid()
14008                    + " without permission "
14009                    + android.Manifest.permission.DUMP);
14010            return;
14011        }
14012
14013        boolean dumpAll = false;
14014        boolean dumpClient = false;
14015        boolean dumpCheckin = false;
14016        boolean dumpCheckinFormat = false;
14017        String dumpPackage = null;
14018
14019        int opti = 0;
14020        while (opti < args.length) {
14021            String opt = args[opti];
14022            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14023                break;
14024            }
14025            opti++;
14026            if ("-a".equals(opt)) {
14027                dumpAll = true;
14028            } else if ("-c".equals(opt)) {
14029                dumpClient = true;
14030            } else if ("-p".equals(opt)) {
14031                if (opti < args.length) {
14032                    dumpPackage = args[opti];
14033                    opti++;
14034                } else {
14035                    pw.println("Error: -p option requires package argument");
14036                    return;
14037                }
14038                dumpClient = true;
14039            } else if ("--checkin".equals(opt)) {
14040                dumpCheckin = dumpCheckinFormat = true;
14041            } else if ("-C".equals(opt)) {
14042                dumpCheckinFormat = true;
14043            } else if ("-h".equals(opt)) {
14044                ActivityManagerShellCommand.dumpHelp(pw, true);
14045                return;
14046            } else {
14047                pw.println("Unknown argument: " + opt + "; use -h for help");
14048            }
14049        }
14050
14051        long origId = Binder.clearCallingIdentity();
14052        boolean more = false;
14053        // Is the caller requesting to dump a particular piece of data?
14054        if (opti < args.length) {
14055            String cmd = args[opti];
14056            opti++;
14057            if ("activities".equals(cmd) || "a".equals(cmd)) {
14058                synchronized (this) {
14059                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14060                }
14061            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14062                synchronized (this) {
14063                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14064                }
14065            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14066                String[] newArgs;
14067                String name;
14068                if (opti >= args.length) {
14069                    name = null;
14070                    newArgs = EMPTY_STRING_ARRAY;
14071                } else {
14072                    dumpPackage = args[opti];
14073                    opti++;
14074                    newArgs = new String[args.length - opti];
14075                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14076                            args.length - opti);
14077                }
14078                synchronized (this) {
14079                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14080                }
14081            } else if ("broadcast-stats".equals(cmd)) {
14082                String[] newArgs;
14083                String name;
14084                if (opti >= args.length) {
14085                    name = null;
14086                    newArgs = EMPTY_STRING_ARRAY;
14087                } else {
14088                    dumpPackage = args[opti];
14089                    opti++;
14090                    newArgs = new String[args.length - opti];
14091                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14092                            args.length - opti);
14093                }
14094                synchronized (this) {
14095                    if (dumpCheckinFormat) {
14096                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14097                                dumpPackage);
14098                    } else {
14099                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14100                    }
14101                }
14102            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14103                String[] newArgs;
14104                String name;
14105                if (opti >= args.length) {
14106                    name = null;
14107                    newArgs = EMPTY_STRING_ARRAY;
14108                } else {
14109                    dumpPackage = args[opti];
14110                    opti++;
14111                    newArgs = new String[args.length - opti];
14112                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14113                            args.length - opti);
14114                }
14115                synchronized (this) {
14116                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14117                }
14118            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14119                String[] newArgs;
14120                String name;
14121                if (opti >= args.length) {
14122                    name = null;
14123                    newArgs = EMPTY_STRING_ARRAY;
14124                } else {
14125                    dumpPackage = args[opti];
14126                    opti++;
14127                    newArgs = new String[args.length - opti];
14128                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14129                            args.length - opti);
14130                }
14131                synchronized (this) {
14132                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14133                }
14134            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14135                synchronized (this) {
14136                    dumpOomLocked(fd, pw, args, opti, true);
14137                }
14138            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14139                synchronized (this) {
14140                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14141                }
14142            } else if ("provider".equals(cmd)) {
14143                String[] newArgs;
14144                String name;
14145                if (opti >= args.length) {
14146                    name = null;
14147                    newArgs = EMPTY_STRING_ARRAY;
14148                } else {
14149                    name = args[opti];
14150                    opti++;
14151                    newArgs = new String[args.length - opti];
14152                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14153                }
14154                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14155                    pw.println("No providers match: " + name);
14156                    pw.println("Use -h for help.");
14157                }
14158            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14159                synchronized (this) {
14160                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14161                }
14162            } else if ("service".equals(cmd)) {
14163                String[] newArgs;
14164                String name;
14165                if (opti >= args.length) {
14166                    name = null;
14167                    newArgs = EMPTY_STRING_ARRAY;
14168                } else {
14169                    name = args[opti];
14170                    opti++;
14171                    newArgs = new String[args.length - opti];
14172                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14173                            args.length - opti);
14174                }
14175                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14176                    pw.println("No services match: " + name);
14177                    pw.println("Use -h for help.");
14178                }
14179            } else if ("package".equals(cmd)) {
14180                String[] newArgs;
14181                if (opti >= args.length) {
14182                    pw.println("package: no package name specified");
14183                    pw.println("Use -h for help.");
14184                } else {
14185                    dumpPackage = args[opti];
14186                    opti++;
14187                    newArgs = new String[args.length - opti];
14188                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14189                            args.length - opti);
14190                    args = newArgs;
14191                    opti = 0;
14192                    more = true;
14193                }
14194            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14195                synchronized (this) {
14196                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14197                }
14198            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14199                if (dumpClient) {
14200                    ActiveServices.ServiceDumper dumper;
14201                    synchronized (this) {
14202                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14203                                dumpPackage);
14204                    }
14205                    dumper.dumpWithClient();
14206                } else {
14207                    synchronized (this) {
14208                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14209                                dumpPackage).dumpLocked();
14210                    }
14211                }
14212            } else if ("locks".equals(cmd)) {
14213                LockGuard.dump(fd, pw, args);
14214            } else {
14215                // Dumping a single activity?
14216                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14217                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14218                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14219                    if (res < 0) {
14220                        pw.println("Bad activity command, or no activities match: " + cmd);
14221                        pw.println("Use -h for help.");
14222                    }
14223                }
14224            }
14225            if (!more) {
14226                Binder.restoreCallingIdentity(origId);
14227                return;
14228            }
14229        }
14230
14231        // No piece of data specified, dump everything.
14232        if (dumpCheckinFormat) {
14233            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14234        } else if (dumpClient) {
14235            ActiveServices.ServiceDumper sdumper;
14236            synchronized (this) {
14237                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14238                pw.println();
14239                if (dumpAll) {
14240                    pw.println("-------------------------------------------------------------------------------");
14241                }
14242                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14243                pw.println();
14244                if (dumpAll) {
14245                    pw.println("-------------------------------------------------------------------------------");
14246                }
14247                if (dumpAll || dumpPackage != null) {
14248                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14249                    pw.println();
14250                    if (dumpAll) {
14251                        pw.println("-------------------------------------------------------------------------------");
14252                    }
14253                }
14254                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14255                pw.println();
14256                if (dumpAll) {
14257                    pw.println("-------------------------------------------------------------------------------");
14258                }
14259                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14260                pw.println();
14261                if (dumpAll) {
14262                    pw.println("-------------------------------------------------------------------------------");
14263                }
14264                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14265                        dumpPackage);
14266            }
14267            sdumper.dumpWithClient();
14268            pw.println();
14269            synchronized (this) {
14270                if (dumpAll) {
14271                    pw.println("-------------------------------------------------------------------------------");
14272                }
14273                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14274                pw.println();
14275                if (dumpAll) {
14276                    pw.println("-------------------------------------------------------------------------------");
14277                }
14278                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14279                if (mAssociations.size() > 0) {
14280                    pw.println();
14281                    if (dumpAll) {
14282                        pw.println("-------------------------------------------------------------------------------");
14283                    }
14284                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14285                }
14286                pw.println();
14287                if (dumpAll) {
14288                    pw.println("-------------------------------------------------------------------------------");
14289                }
14290                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14291            }
14292
14293        } else {
14294            synchronized (this) {
14295                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14296                pw.println();
14297                if (dumpAll) {
14298                    pw.println("-------------------------------------------------------------------------------");
14299                }
14300                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14301                pw.println();
14302                if (dumpAll) {
14303                    pw.println("-------------------------------------------------------------------------------");
14304                }
14305                if (dumpAll || dumpPackage != null) {
14306                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14307                    pw.println();
14308                    if (dumpAll) {
14309                        pw.println("-------------------------------------------------------------------------------");
14310                    }
14311                }
14312                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14313                pw.println();
14314                if (dumpAll) {
14315                    pw.println("-------------------------------------------------------------------------------");
14316                }
14317                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14318                pw.println();
14319                if (dumpAll) {
14320                    pw.println("-------------------------------------------------------------------------------");
14321                }
14322                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14323                        .dumpLocked();
14324                pw.println();
14325                if (dumpAll) {
14326                    pw.println("-------------------------------------------------------------------------------");
14327                }
14328                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14329                pw.println();
14330                if (dumpAll) {
14331                    pw.println("-------------------------------------------------------------------------------");
14332                }
14333                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14334                if (mAssociations.size() > 0) {
14335                    pw.println();
14336                    if (dumpAll) {
14337                        pw.println("-------------------------------------------------------------------------------");
14338                    }
14339                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14340                }
14341                pw.println();
14342                if (dumpAll) {
14343                    pw.println("-------------------------------------------------------------------------------");
14344                }
14345                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14346            }
14347        }
14348        Binder.restoreCallingIdentity(origId);
14349    }
14350
14351    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14352            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14353        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14354
14355        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14356                dumpPackage);
14357        boolean needSep = printedAnything;
14358
14359        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14360                dumpPackage, needSep, "  mFocusedActivity: ");
14361        if (printed) {
14362            printedAnything = true;
14363            needSep = false;
14364        }
14365
14366        if (dumpPackage == null) {
14367            if (needSep) {
14368                pw.println();
14369            }
14370            needSep = true;
14371            printedAnything = true;
14372            mStackSupervisor.dump(pw, "  ");
14373        }
14374
14375        if (!printedAnything) {
14376            pw.println("  (nothing)");
14377        }
14378    }
14379
14380    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14381            int opti, boolean dumpAll, String dumpPackage) {
14382        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14383
14384        boolean printedAnything = false;
14385
14386        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14387            boolean printedHeader = false;
14388
14389            final int N = mRecentTasks.size();
14390            for (int i=0; i<N; i++) {
14391                TaskRecord tr = mRecentTasks.get(i);
14392                if (dumpPackage != null) {
14393                    if (tr.realActivity == null ||
14394                            !dumpPackage.equals(tr.realActivity)) {
14395                        continue;
14396                    }
14397                }
14398                if (!printedHeader) {
14399                    pw.println("  Recent tasks:");
14400                    printedHeader = true;
14401                    printedAnything = true;
14402                }
14403                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14404                        pw.println(tr);
14405                if (dumpAll) {
14406                    mRecentTasks.get(i).dump(pw, "    ");
14407                }
14408            }
14409        }
14410
14411        if (!printedAnything) {
14412            pw.println("  (nothing)");
14413        }
14414    }
14415
14416    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14417            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14418        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14419
14420        int dumpUid = 0;
14421        if (dumpPackage != null) {
14422            IPackageManager pm = AppGlobals.getPackageManager();
14423            try {
14424                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14425            } catch (RemoteException e) {
14426            }
14427        }
14428
14429        boolean printedAnything = false;
14430
14431        final long now = SystemClock.uptimeMillis();
14432
14433        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14434            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14435                    = mAssociations.valueAt(i1);
14436            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14437                SparseArray<ArrayMap<String, Association>> sourceUids
14438                        = targetComponents.valueAt(i2);
14439                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14440                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14441                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14442                        Association ass = sourceProcesses.valueAt(i4);
14443                        if (dumpPackage != null) {
14444                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14445                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14446                                continue;
14447                            }
14448                        }
14449                        printedAnything = true;
14450                        pw.print("  ");
14451                        pw.print(ass.mTargetProcess);
14452                        pw.print("/");
14453                        UserHandle.formatUid(pw, ass.mTargetUid);
14454                        pw.print(" <- ");
14455                        pw.print(ass.mSourceProcess);
14456                        pw.print("/");
14457                        UserHandle.formatUid(pw, ass.mSourceUid);
14458                        pw.println();
14459                        pw.print("    via ");
14460                        pw.print(ass.mTargetComponent.flattenToShortString());
14461                        pw.println();
14462                        pw.print("    ");
14463                        long dur = ass.mTime;
14464                        if (ass.mNesting > 0) {
14465                            dur += now - ass.mStartTime;
14466                        }
14467                        TimeUtils.formatDuration(dur, pw);
14468                        pw.print(" (");
14469                        pw.print(ass.mCount);
14470                        pw.print(" times)");
14471                        pw.print("  ");
14472                        for (int i=0; i<ass.mStateTimes.length; i++) {
14473                            long amt = ass.mStateTimes[i];
14474                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14475                                amt += now - ass.mLastStateUptime;
14476                            }
14477                            if (amt != 0) {
14478                                pw.print(" ");
14479                                pw.print(ProcessList.makeProcStateString(
14480                                            i + ActivityManager.MIN_PROCESS_STATE));
14481                                pw.print("=");
14482                                TimeUtils.formatDuration(amt, pw);
14483                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14484                                    pw.print("*");
14485                                }
14486                            }
14487                        }
14488                        pw.println();
14489                        if (ass.mNesting > 0) {
14490                            pw.print("    Currently active: ");
14491                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14492                            pw.println();
14493                        }
14494                    }
14495                }
14496            }
14497
14498        }
14499
14500        if (!printedAnything) {
14501            pw.println("  (nothing)");
14502        }
14503    }
14504
14505    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14506            String header, boolean needSep) {
14507        boolean printed = false;
14508        int whichAppId = -1;
14509        if (dumpPackage != null) {
14510            try {
14511                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14512                        dumpPackage, 0);
14513                whichAppId = UserHandle.getAppId(info.uid);
14514            } catch (NameNotFoundException e) {
14515                e.printStackTrace();
14516            }
14517        }
14518        for (int i=0; i<uids.size(); i++) {
14519            UidRecord uidRec = uids.valueAt(i);
14520            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14521                continue;
14522            }
14523            if (!printed) {
14524                printed = true;
14525                if (needSep) {
14526                    pw.println();
14527                }
14528                pw.print("  ");
14529                pw.println(header);
14530                needSep = true;
14531            }
14532            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14533            pw.print(": "); pw.println(uidRec);
14534        }
14535        return printed;
14536    }
14537
14538    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14539            int opti, boolean dumpAll, String dumpPackage) {
14540        boolean needSep = false;
14541        boolean printedAnything = false;
14542        int numPers = 0;
14543
14544        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14545
14546        if (dumpAll) {
14547            final int NP = mProcessNames.getMap().size();
14548            for (int ip=0; ip<NP; ip++) {
14549                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14550                final int NA = procs.size();
14551                for (int ia=0; ia<NA; ia++) {
14552                    ProcessRecord r = procs.valueAt(ia);
14553                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14554                        continue;
14555                    }
14556                    if (!needSep) {
14557                        pw.println("  All known processes:");
14558                        needSep = true;
14559                        printedAnything = true;
14560                    }
14561                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14562                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14563                        pw.print(" "); pw.println(r);
14564                    r.dump(pw, "    ");
14565                    if (r.persistent) {
14566                        numPers++;
14567                    }
14568                }
14569            }
14570        }
14571
14572        if (mIsolatedProcesses.size() > 0) {
14573            boolean printed = false;
14574            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14575                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14576                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14577                    continue;
14578                }
14579                if (!printed) {
14580                    if (needSep) {
14581                        pw.println();
14582                    }
14583                    pw.println("  Isolated process list (sorted by uid):");
14584                    printedAnything = true;
14585                    printed = true;
14586                    needSep = true;
14587                }
14588                pw.println(String.format("%sIsolated #%2d: %s",
14589                        "    ", i, r.toString()));
14590            }
14591        }
14592
14593        if (mActiveUids.size() > 0) {
14594            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14595                printedAnything = needSep = true;
14596            }
14597        }
14598        if (mValidateUids.size() > 0) {
14599            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14600                printedAnything = needSep = true;
14601            }
14602        }
14603
14604        if (mLruProcesses.size() > 0) {
14605            if (needSep) {
14606                pw.println();
14607            }
14608            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14609                    pw.print(" total, non-act at ");
14610                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14611                    pw.print(", non-svc at ");
14612                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14613                    pw.println("):");
14614            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14615            needSep = true;
14616            printedAnything = true;
14617        }
14618
14619        if (dumpAll || dumpPackage != null) {
14620            synchronized (mPidsSelfLocked) {
14621                boolean printed = false;
14622                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14623                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14624                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14625                        continue;
14626                    }
14627                    if (!printed) {
14628                        if (needSep) pw.println();
14629                        needSep = true;
14630                        pw.println("  PID mappings:");
14631                        printed = true;
14632                        printedAnything = true;
14633                    }
14634                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14635                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14636                }
14637            }
14638        }
14639
14640        if (mForegroundProcesses.size() > 0) {
14641            synchronized (mPidsSelfLocked) {
14642                boolean printed = false;
14643                for (int i=0; i<mForegroundProcesses.size(); i++) {
14644                    ProcessRecord r = mPidsSelfLocked.get(
14645                            mForegroundProcesses.valueAt(i).pid);
14646                    if (dumpPackage != null && (r == null
14647                            || !r.pkgList.containsKey(dumpPackage))) {
14648                        continue;
14649                    }
14650                    if (!printed) {
14651                        if (needSep) pw.println();
14652                        needSep = true;
14653                        pw.println("  Foreground Processes:");
14654                        printed = true;
14655                        printedAnything = true;
14656                    }
14657                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14658                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14659                }
14660            }
14661        }
14662
14663        if (mPersistentStartingProcesses.size() > 0) {
14664            if (needSep) pw.println();
14665            needSep = true;
14666            printedAnything = true;
14667            pw.println("  Persisent processes that are starting:");
14668            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14669                    "Starting Norm", "Restarting PERS", dumpPackage);
14670        }
14671
14672        if (mRemovedProcesses.size() > 0) {
14673            if (needSep) pw.println();
14674            needSep = true;
14675            printedAnything = true;
14676            pw.println("  Processes that are being removed:");
14677            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14678                    "Removed Norm", "Removed PERS", dumpPackage);
14679        }
14680
14681        if (mProcessesOnHold.size() > 0) {
14682            if (needSep) pw.println();
14683            needSep = true;
14684            printedAnything = true;
14685            pw.println("  Processes that are on old until the system is ready:");
14686            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14687                    "OnHold Norm", "OnHold PERS", dumpPackage);
14688        }
14689
14690        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14691
14692        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14693        if (needSep) {
14694            printedAnything = true;
14695        }
14696
14697        if (dumpPackage == null) {
14698            pw.println();
14699            needSep = false;
14700            mUserController.dump(pw, dumpAll);
14701        }
14702        if (mHomeProcess != null && (dumpPackage == null
14703                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14704            if (needSep) {
14705                pw.println();
14706                needSep = false;
14707            }
14708            pw.println("  mHomeProcess: " + mHomeProcess);
14709        }
14710        if (mPreviousProcess != null && (dumpPackage == null
14711                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14712            if (needSep) {
14713                pw.println();
14714                needSep = false;
14715            }
14716            pw.println("  mPreviousProcess: " + mPreviousProcess);
14717        }
14718        if (dumpAll) {
14719            StringBuilder sb = new StringBuilder(128);
14720            sb.append("  mPreviousProcessVisibleTime: ");
14721            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14722            pw.println(sb);
14723        }
14724        if (mHeavyWeightProcess != null && (dumpPackage == null
14725                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14726            if (needSep) {
14727                pw.println();
14728                needSep = false;
14729            }
14730            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14731        }
14732        if (dumpPackage == null) {
14733            pw.println("  mConfiguration: " + mConfiguration);
14734        }
14735        if (dumpAll) {
14736            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14737            if (mCompatModePackages.getPackages().size() > 0) {
14738                boolean printed = false;
14739                for (Map.Entry<String, Integer> entry
14740                        : mCompatModePackages.getPackages().entrySet()) {
14741                    String pkg = entry.getKey();
14742                    int mode = entry.getValue();
14743                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14744                        continue;
14745                    }
14746                    if (!printed) {
14747                        pw.println("  mScreenCompatPackages:");
14748                        printed = true;
14749                    }
14750                    pw.print("    "); pw.print(pkg); pw.print(": ");
14751                            pw.print(mode); pw.println();
14752                }
14753            }
14754        }
14755        if (dumpPackage == null) {
14756            pw.println("  mWakefulness="
14757                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14758            pw.println("  mSleepTokens=" + mSleepTokens);
14759            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14760                    + lockScreenShownToString());
14761            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14762            if (mRunningVoice != null) {
14763                pw.println("  mRunningVoice=" + mRunningVoice);
14764                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14765            }
14766        }
14767        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14768                || mOrigWaitForDebugger) {
14769            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14770                    || dumpPackage.equals(mOrigDebugApp)) {
14771                if (needSep) {
14772                    pw.println();
14773                    needSep = false;
14774                }
14775                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14776                        + " mDebugTransient=" + mDebugTransient
14777                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14778            }
14779        }
14780        if (mCurAppTimeTracker != null) {
14781            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14782        }
14783        if (mMemWatchProcesses.getMap().size() > 0) {
14784            pw.println("  Mem watch processes:");
14785            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14786                    = mMemWatchProcesses.getMap();
14787            for (int i=0; i<procs.size(); i++) {
14788                final String proc = procs.keyAt(i);
14789                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14790                for (int j=0; j<uids.size(); j++) {
14791                    if (needSep) {
14792                        pw.println();
14793                        needSep = false;
14794                    }
14795                    StringBuilder sb = new StringBuilder();
14796                    sb.append("    ").append(proc).append('/');
14797                    UserHandle.formatUid(sb, uids.keyAt(j));
14798                    Pair<Long, String> val = uids.valueAt(j);
14799                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14800                    if (val.second != null) {
14801                        sb.append(", report to ").append(val.second);
14802                    }
14803                    pw.println(sb.toString());
14804                }
14805            }
14806            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14807            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14808            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14809                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14810        }
14811        if (mTrackAllocationApp != null) {
14812            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14813                if (needSep) {
14814                    pw.println();
14815                    needSep = false;
14816                }
14817                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14818            }
14819        }
14820        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14821                || mProfileFd != null) {
14822            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14823                if (needSep) {
14824                    pw.println();
14825                    needSep = false;
14826                }
14827                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14828                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14829                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14830                        + mAutoStopProfiler);
14831                pw.println("  mProfileType=" + mProfileType);
14832            }
14833        }
14834        if (mNativeDebuggingApp != null) {
14835            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14836                if (needSep) {
14837                    pw.println();
14838                    needSep = false;
14839                }
14840                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14841            }
14842        }
14843        if (dumpPackage == null) {
14844            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14845                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14846                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14847            }
14848            if (mController != null) {
14849                pw.println("  mController=" + mController
14850                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14851            }
14852            if (dumpAll) {
14853                pw.println("  Total persistent processes: " + numPers);
14854                pw.println("  mProcessesReady=" + mProcessesReady
14855                        + " mSystemReady=" + mSystemReady
14856                        + " mBooted=" + mBooted
14857                        + " mFactoryTest=" + mFactoryTest);
14858                pw.println("  mBooting=" + mBooting
14859                        + " mCallFinishBooting=" + mCallFinishBooting
14860                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14861                pw.print("  mLastPowerCheckRealtime=");
14862                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14863                        pw.println("");
14864                pw.print("  mLastPowerCheckUptime=");
14865                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14866                        pw.println("");
14867                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14868                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14869                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14870                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14871                        + " (" + mLruProcesses.size() + " total)"
14872                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14873                        + " mNumServiceProcs=" + mNumServiceProcs
14874                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14875                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14876                        + " mLastMemoryLevel=" + mLastMemoryLevel
14877                        + " mLastNumProcesses=" + mLastNumProcesses);
14878                long now = SystemClock.uptimeMillis();
14879                pw.print("  mLastIdleTime=");
14880                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14881                        pw.print(" mLowRamSinceLastIdle=");
14882                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14883                        pw.println();
14884            }
14885        }
14886
14887        if (!printedAnything) {
14888            pw.println("  (nothing)");
14889        }
14890    }
14891
14892    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14893            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14894        if (mProcessesToGc.size() > 0) {
14895            boolean printed = false;
14896            long now = SystemClock.uptimeMillis();
14897            for (int i=0; i<mProcessesToGc.size(); i++) {
14898                ProcessRecord proc = mProcessesToGc.get(i);
14899                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14900                    continue;
14901                }
14902                if (!printed) {
14903                    if (needSep) pw.println();
14904                    needSep = true;
14905                    pw.println("  Processes that are waiting to GC:");
14906                    printed = true;
14907                }
14908                pw.print("    Process "); pw.println(proc);
14909                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14910                        pw.print(", last gced=");
14911                        pw.print(now-proc.lastRequestedGc);
14912                        pw.print(" ms ago, last lowMem=");
14913                        pw.print(now-proc.lastLowMemory);
14914                        pw.println(" ms ago");
14915
14916            }
14917        }
14918        return needSep;
14919    }
14920
14921    void printOomLevel(PrintWriter pw, String name, int adj) {
14922        pw.print("    ");
14923        if (adj >= 0) {
14924            pw.print(' ');
14925            if (adj < 10) pw.print(' ');
14926        } else {
14927            if (adj > -10) pw.print(' ');
14928        }
14929        pw.print(adj);
14930        pw.print(": ");
14931        pw.print(name);
14932        pw.print(" (");
14933        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14934        pw.println(")");
14935    }
14936
14937    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14938            int opti, boolean dumpAll) {
14939        boolean needSep = false;
14940
14941        if (mLruProcesses.size() > 0) {
14942            if (needSep) pw.println();
14943            needSep = true;
14944            pw.println("  OOM levels:");
14945            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14946            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14947            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14948            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14949            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14950            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14951            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14952            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14953            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14954            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14955            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14956            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14957            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14958            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14959
14960            if (needSep) pw.println();
14961            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14962                    pw.print(" total, non-act at ");
14963                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14964                    pw.print(", non-svc at ");
14965                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14966                    pw.println("):");
14967            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14968            needSep = true;
14969        }
14970
14971        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14972
14973        pw.println();
14974        pw.println("  mHomeProcess: " + mHomeProcess);
14975        pw.println("  mPreviousProcess: " + mPreviousProcess);
14976        if (mHeavyWeightProcess != null) {
14977            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14978        }
14979
14980        return true;
14981    }
14982
14983    /**
14984     * There are three ways to call this:
14985     *  - no provider specified: dump all the providers
14986     *  - a flattened component name that matched an existing provider was specified as the
14987     *    first arg: dump that one provider
14988     *  - the first arg isn't the flattened component name of an existing provider:
14989     *    dump all providers whose component contains the first arg as a substring
14990     */
14991    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14992            int opti, boolean dumpAll) {
14993        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14994    }
14995
14996    static class ItemMatcher {
14997        ArrayList<ComponentName> components;
14998        ArrayList<String> strings;
14999        ArrayList<Integer> objects;
15000        boolean all;
15001
15002        ItemMatcher() {
15003            all = true;
15004        }
15005
15006        void build(String name) {
15007            ComponentName componentName = ComponentName.unflattenFromString(name);
15008            if (componentName != null) {
15009                if (components == null) {
15010                    components = new ArrayList<ComponentName>();
15011                }
15012                components.add(componentName);
15013                all = false;
15014            } else {
15015                int objectId = 0;
15016                // Not a '/' separated full component name; maybe an object ID?
15017                try {
15018                    objectId = Integer.parseInt(name, 16);
15019                    if (objects == null) {
15020                        objects = new ArrayList<Integer>();
15021                    }
15022                    objects.add(objectId);
15023                    all = false;
15024                } catch (RuntimeException e) {
15025                    // Not an integer; just do string match.
15026                    if (strings == null) {
15027                        strings = new ArrayList<String>();
15028                    }
15029                    strings.add(name);
15030                    all = false;
15031                }
15032            }
15033        }
15034
15035        int build(String[] args, int opti) {
15036            for (; opti<args.length; opti++) {
15037                String name = args[opti];
15038                if ("--".equals(name)) {
15039                    return opti+1;
15040                }
15041                build(name);
15042            }
15043            return opti;
15044        }
15045
15046        boolean match(Object object, ComponentName comp) {
15047            if (all) {
15048                return true;
15049            }
15050            if (components != null) {
15051                for (int i=0; i<components.size(); i++) {
15052                    if (components.get(i).equals(comp)) {
15053                        return true;
15054                    }
15055                }
15056            }
15057            if (objects != null) {
15058                for (int i=0; i<objects.size(); i++) {
15059                    if (System.identityHashCode(object) == objects.get(i)) {
15060                        return true;
15061                    }
15062                }
15063            }
15064            if (strings != null) {
15065                String flat = comp.flattenToString();
15066                for (int i=0; i<strings.size(); i++) {
15067                    if (flat.contains(strings.get(i))) {
15068                        return true;
15069                    }
15070                }
15071            }
15072            return false;
15073        }
15074    }
15075
15076    /**
15077     * There are three things that cmd can be:
15078     *  - a flattened component name that matches an existing activity
15079     *  - the cmd arg isn't the flattened component name of an existing activity:
15080     *    dump all activity whose component contains the cmd as a substring
15081     *  - A hex number of the ActivityRecord object instance.
15082     */
15083    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15084            int opti, boolean dumpAll) {
15085        ArrayList<ActivityRecord> activities;
15086
15087        synchronized (this) {
15088            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15089        }
15090
15091        if (activities.size() <= 0) {
15092            return false;
15093        }
15094
15095        String[] newArgs = new String[args.length - opti];
15096        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15097
15098        TaskRecord lastTask = null;
15099        boolean needSep = false;
15100        for (int i=activities.size()-1; i>=0; i--) {
15101            ActivityRecord r = activities.get(i);
15102            if (needSep) {
15103                pw.println();
15104            }
15105            needSep = true;
15106            synchronized (this) {
15107                if (lastTask != r.task) {
15108                    lastTask = r.task;
15109                    pw.print("TASK "); pw.print(lastTask.affinity);
15110                            pw.print(" id="); pw.println(lastTask.taskId);
15111                    if (dumpAll) {
15112                        lastTask.dump(pw, "  ");
15113                    }
15114                }
15115            }
15116            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15117        }
15118        return true;
15119    }
15120
15121    /**
15122     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15123     * there is a thread associated with the activity.
15124     */
15125    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15126            final ActivityRecord r, String[] args, boolean dumpAll) {
15127        String innerPrefix = prefix + "  ";
15128        synchronized (this) {
15129            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15130                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15131                    pw.print(" pid=");
15132                    if (r.app != null) pw.println(r.app.pid);
15133                    else pw.println("(not running)");
15134            if (dumpAll) {
15135                r.dump(pw, innerPrefix);
15136            }
15137        }
15138        if (r.app != null && r.app.thread != null) {
15139            // flush anything that is already in the PrintWriter since the thread is going
15140            // to write to the file descriptor directly
15141            pw.flush();
15142            try {
15143                TransferPipe tp = new TransferPipe();
15144                try {
15145                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15146                            r.appToken, innerPrefix, args);
15147                    tp.go(fd);
15148                } finally {
15149                    tp.kill();
15150                }
15151            } catch (IOException e) {
15152                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15153            } catch (RemoteException e) {
15154                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15155            }
15156        }
15157    }
15158
15159    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15160            int opti, boolean dumpAll, String dumpPackage) {
15161        boolean needSep = false;
15162        boolean onlyHistory = false;
15163        boolean printedAnything = false;
15164
15165        if ("history".equals(dumpPackage)) {
15166            if (opti < args.length && "-s".equals(args[opti])) {
15167                dumpAll = false;
15168            }
15169            onlyHistory = true;
15170            dumpPackage = null;
15171        }
15172
15173        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15174        if (!onlyHistory && dumpAll) {
15175            if (mRegisteredReceivers.size() > 0) {
15176                boolean printed = false;
15177                Iterator it = mRegisteredReceivers.values().iterator();
15178                while (it.hasNext()) {
15179                    ReceiverList r = (ReceiverList)it.next();
15180                    if (dumpPackage != null && (r.app == null ||
15181                            !dumpPackage.equals(r.app.info.packageName))) {
15182                        continue;
15183                    }
15184                    if (!printed) {
15185                        pw.println("  Registered Receivers:");
15186                        needSep = true;
15187                        printed = true;
15188                        printedAnything = true;
15189                    }
15190                    pw.print("  * "); pw.println(r);
15191                    r.dump(pw, "    ");
15192                }
15193            }
15194
15195            if (mReceiverResolver.dump(pw, needSep ?
15196                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15197                    "    ", dumpPackage, false, false)) {
15198                needSep = true;
15199                printedAnything = true;
15200            }
15201        }
15202
15203        for (BroadcastQueue q : mBroadcastQueues) {
15204            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15205            printedAnything |= needSep;
15206        }
15207
15208        needSep = true;
15209
15210        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15211            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15212                if (needSep) {
15213                    pw.println();
15214                }
15215                needSep = true;
15216                printedAnything = true;
15217                pw.print("  Sticky broadcasts for user ");
15218                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15219                StringBuilder sb = new StringBuilder(128);
15220                for (Map.Entry<String, ArrayList<Intent>> ent
15221                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15222                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15223                    if (dumpAll) {
15224                        pw.println(":");
15225                        ArrayList<Intent> intents = ent.getValue();
15226                        final int N = intents.size();
15227                        for (int i=0; i<N; i++) {
15228                            sb.setLength(0);
15229                            sb.append("    Intent: ");
15230                            intents.get(i).toShortString(sb, false, true, false, false);
15231                            pw.println(sb.toString());
15232                            Bundle bundle = intents.get(i).getExtras();
15233                            if (bundle != null) {
15234                                pw.print("      ");
15235                                pw.println(bundle.toString());
15236                            }
15237                        }
15238                    } else {
15239                        pw.println("");
15240                    }
15241                }
15242            }
15243        }
15244
15245        if (!onlyHistory && dumpAll) {
15246            pw.println();
15247            for (BroadcastQueue queue : mBroadcastQueues) {
15248                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15249                        + queue.mBroadcastsScheduled);
15250            }
15251            pw.println("  mHandler:");
15252            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15253            needSep = true;
15254            printedAnything = true;
15255        }
15256
15257        if (!printedAnything) {
15258            pw.println("  (nothing)");
15259        }
15260    }
15261
15262    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15263            int opti, boolean dumpAll, String dumpPackage) {
15264        if (mCurBroadcastStats == null) {
15265            return;
15266        }
15267
15268        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15269        final long now = SystemClock.elapsedRealtime();
15270        if (mLastBroadcastStats != null) {
15271            pw.print("  Last stats (from ");
15272            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15273            pw.print(" to ");
15274            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15275            pw.print(", ");
15276            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15277                    - mLastBroadcastStats.mStartUptime, pw);
15278            pw.println(" uptime):");
15279            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15280                pw.println("    (nothing)");
15281            }
15282            pw.println();
15283        }
15284        pw.print("  Current stats (from ");
15285        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15286        pw.print(" to now, ");
15287        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15288                - mCurBroadcastStats.mStartUptime, pw);
15289        pw.println(" uptime):");
15290        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15291            pw.println("    (nothing)");
15292        }
15293    }
15294
15295    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15296            int opti, boolean fullCheckin, String dumpPackage) {
15297        if (mCurBroadcastStats == null) {
15298            return;
15299        }
15300
15301        if (mLastBroadcastStats != null) {
15302            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15303            if (fullCheckin) {
15304                mLastBroadcastStats = null;
15305                return;
15306            }
15307        }
15308        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15309        if (fullCheckin) {
15310            mCurBroadcastStats = null;
15311        }
15312    }
15313
15314    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15315            int opti, boolean dumpAll, String dumpPackage) {
15316        boolean needSep;
15317        boolean printedAnything = false;
15318
15319        ItemMatcher matcher = new ItemMatcher();
15320        matcher.build(args, opti);
15321
15322        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15323
15324        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15325        printedAnything |= needSep;
15326
15327        if (mLaunchingProviders.size() > 0) {
15328            boolean printed = false;
15329            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15330                ContentProviderRecord r = mLaunchingProviders.get(i);
15331                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15332                    continue;
15333                }
15334                if (!printed) {
15335                    if (needSep) pw.println();
15336                    needSep = true;
15337                    pw.println("  Launching content providers:");
15338                    printed = true;
15339                    printedAnything = true;
15340                }
15341                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15342                        pw.println(r);
15343            }
15344        }
15345
15346        if (!printedAnything) {
15347            pw.println("  (nothing)");
15348        }
15349    }
15350
15351    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15352            int opti, boolean dumpAll, String dumpPackage) {
15353        boolean needSep = false;
15354        boolean printedAnything = false;
15355
15356        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15357
15358        if (mGrantedUriPermissions.size() > 0) {
15359            boolean printed = false;
15360            int dumpUid = -2;
15361            if (dumpPackage != null) {
15362                try {
15363                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15364                            MATCH_UNINSTALLED_PACKAGES, 0);
15365                } catch (NameNotFoundException e) {
15366                    dumpUid = -1;
15367                }
15368            }
15369            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15370                int uid = mGrantedUriPermissions.keyAt(i);
15371                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15372                    continue;
15373                }
15374                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15375                if (!printed) {
15376                    if (needSep) pw.println();
15377                    needSep = true;
15378                    pw.println("  Granted Uri Permissions:");
15379                    printed = true;
15380                    printedAnything = true;
15381                }
15382                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15383                for (UriPermission perm : perms.values()) {
15384                    pw.print("    "); pw.println(perm);
15385                    if (dumpAll) {
15386                        perm.dump(pw, "      ");
15387                    }
15388                }
15389            }
15390        }
15391
15392        if (!printedAnything) {
15393            pw.println("  (nothing)");
15394        }
15395    }
15396
15397    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15398            int opti, boolean dumpAll, String dumpPackage) {
15399        boolean printed = false;
15400
15401        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15402
15403        if (mIntentSenderRecords.size() > 0) {
15404            Iterator<WeakReference<PendingIntentRecord>> it
15405                    = mIntentSenderRecords.values().iterator();
15406            while (it.hasNext()) {
15407                WeakReference<PendingIntentRecord> ref = it.next();
15408                PendingIntentRecord rec = ref != null ? ref.get(): null;
15409                if (dumpPackage != null && (rec == null
15410                        || !dumpPackage.equals(rec.key.packageName))) {
15411                    continue;
15412                }
15413                printed = true;
15414                if (rec != null) {
15415                    pw.print("  * "); pw.println(rec);
15416                    if (dumpAll) {
15417                        rec.dump(pw, "    ");
15418                    }
15419                } else {
15420                    pw.print("  * "); pw.println(ref);
15421                }
15422            }
15423        }
15424
15425        if (!printed) {
15426            pw.println("  (nothing)");
15427        }
15428    }
15429
15430    private static final int dumpProcessList(PrintWriter pw,
15431            ActivityManagerService service, List list,
15432            String prefix, String normalLabel, String persistentLabel,
15433            String dumpPackage) {
15434        int numPers = 0;
15435        final int N = list.size()-1;
15436        for (int i=N; i>=0; i--) {
15437            ProcessRecord r = (ProcessRecord)list.get(i);
15438            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15439                continue;
15440            }
15441            pw.println(String.format("%s%s #%2d: %s",
15442                    prefix, (r.persistent ? persistentLabel : normalLabel),
15443                    i, r.toString()));
15444            if (r.persistent) {
15445                numPers++;
15446            }
15447        }
15448        return numPers;
15449    }
15450
15451    private static final boolean dumpProcessOomList(PrintWriter pw,
15452            ActivityManagerService service, List<ProcessRecord> origList,
15453            String prefix, String normalLabel, String persistentLabel,
15454            boolean inclDetails, String dumpPackage) {
15455
15456        ArrayList<Pair<ProcessRecord, Integer>> list
15457                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15458        for (int i=0; i<origList.size(); i++) {
15459            ProcessRecord r = origList.get(i);
15460            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15461                continue;
15462            }
15463            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15464        }
15465
15466        if (list.size() <= 0) {
15467            return false;
15468        }
15469
15470        Comparator<Pair<ProcessRecord, Integer>> comparator
15471                = new Comparator<Pair<ProcessRecord, Integer>>() {
15472            @Override
15473            public int compare(Pair<ProcessRecord, Integer> object1,
15474                    Pair<ProcessRecord, Integer> object2) {
15475                if (object1.first.setAdj != object2.first.setAdj) {
15476                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15477                }
15478                if (object1.first.setProcState != object2.first.setProcState) {
15479                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15480                }
15481                if (object1.second.intValue() != object2.second.intValue()) {
15482                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15483                }
15484                return 0;
15485            }
15486        };
15487
15488        Collections.sort(list, comparator);
15489
15490        final long curRealtime = SystemClock.elapsedRealtime();
15491        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15492        final long curUptime = SystemClock.uptimeMillis();
15493        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15494
15495        for (int i=list.size()-1; i>=0; i--) {
15496            ProcessRecord r = list.get(i).first;
15497            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15498            char schedGroup;
15499            switch (r.setSchedGroup) {
15500                case ProcessList.SCHED_GROUP_BACKGROUND:
15501                    schedGroup = 'B';
15502                    break;
15503                case ProcessList.SCHED_GROUP_DEFAULT:
15504                    schedGroup = 'F';
15505                    break;
15506                case ProcessList.SCHED_GROUP_TOP_APP:
15507                    schedGroup = 'T';
15508                    break;
15509                default:
15510                    schedGroup = '?';
15511                    break;
15512            }
15513            char foreground;
15514            if (r.foregroundActivities) {
15515                foreground = 'A';
15516            } else if (r.foregroundServices) {
15517                foreground = 'S';
15518            } else {
15519                foreground = ' ';
15520            }
15521            String procState = ProcessList.makeProcStateString(r.curProcState);
15522            pw.print(prefix);
15523            pw.print(r.persistent ? persistentLabel : normalLabel);
15524            pw.print(" #");
15525            int num = (origList.size()-1)-list.get(i).second;
15526            if (num < 10) pw.print(' ');
15527            pw.print(num);
15528            pw.print(": ");
15529            pw.print(oomAdj);
15530            pw.print(' ');
15531            pw.print(schedGroup);
15532            pw.print('/');
15533            pw.print(foreground);
15534            pw.print('/');
15535            pw.print(procState);
15536            pw.print(" trm:");
15537            if (r.trimMemoryLevel < 10) pw.print(' ');
15538            pw.print(r.trimMemoryLevel);
15539            pw.print(' ');
15540            pw.print(r.toShortString());
15541            pw.print(" (");
15542            pw.print(r.adjType);
15543            pw.println(')');
15544            if (r.adjSource != null || r.adjTarget != null) {
15545                pw.print(prefix);
15546                pw.print("    ");
15547                if (r.adjTarget instanceof ComponentName) {
15548                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15549                } else if (r.adjTarget != null) {
15550                    pw.print(r.adjTarget.toString());
15551                } else {
15552                    pw.print("{null}");
15553                }
15554                pw.print("<=");
15555                if (r.adjSource instanceof ProcessRecord) {
15556                    pw.print("Proc{");
15557                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15558                    pw.println("}");
15559                } else if (r.adjSource != null) {
15560                    pw.println(r.adjSource.toString());
15561                } else {
15562                    pw.println("{null}");
15563                }
15564            }
15565            if (inclDetails) {
15566                pw.print(prefix);
15567                pw.print("    ");
15568                pw.print("oom: max="); pw.print(r.maxAdj);
15569                pw.print(" curRaw="); pw.print(r.curRawAdj);
15570                pw.print(" setRaw="); pw.print(r.setRawAdj);
15571                pw.print(" cur="); pw.print(r.curAdj);
15572                pw.print(" set="); pw.println(r.setAdj);
15573                pw.print(prefix);
15574                pw.print("    ");
15575                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15576                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15577                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15578                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15579                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15580                pw.println();
15581                pw.print(prefix);
15582                pw.print("    ");
15583                pw.print("cached="); pw.print(r.cached);
15584                pw.print(" empty="); pw.print(r.empty);
15585                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15586
15587                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15588                    if (r.lastWakeTime != 0) {
15589                        long wtime;
15590                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15591                        synchronized (stats) {
15592                            wtime = stats.getProcessWakeTime(r.info.uid,
15593                                    r.pid, curRealtime);
15594                        }
15595                        long timeUsed = wtime - r.lastWakeTime;
15596                        pw.print(prefix);
15597                        pw.print("    ");
15598                        pw.print("keep awake over ");
15599                        TimeUtils.formatDuration(realtimeSince, pw);
15600                        pw.print(" used ");
15601                        TimeUtils.formatDuration(timeUsed, pw);
15602                        pw.print(" (");
15603                        pw.print((timeUsed*100)/realtimeSince);
15604                        pw.println("%)");
15605                    }
15606                    if (r.lastCpuTime != 0) {
15607                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15608                        pw.print(prefix);
15609                        pw.print("    ");
15610                        pw.print("run cpu over ");
15611                        TimeUtils.formatDuration(uptimeSince, pw);
15612                        pw.print(" used ");
15613                        TimeUtils.formatDuration(timeUsed, pw);
15614                        pw.print(" (");
15615                        pw.print((timeUsed*100)/uptimeSince);
15616                        pw.println("%)");
15617                    }
15618                }
15619            }
15620        }
15621        return true;
15622    }
15623
15624    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15625            String[] args) {
15626        ArrayList<ProcessRecord> procs;
15627        synchronized (this) {
15628            if (args != null && args.length > start
15629                    && args[start].charAt(0) != '-') {
15630                procs = new ArrayList<ProcessRecord>();
15631                int pid = -1;
15632                try {
15633                    pid = Integer.parseInt(args[start]);
15634                } catch (NumberFormatException e) {
15635                }
15636                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15637                    ProcessRecord proc = mLruProcesses.get(i);
15638                    if (proc.pid == pid) {
15639                        procs.add(proc);
15640                    } else if (allPkgs && proc.pkgList != null
15641                            && proc.pkgList.containsKey(args[start])) {
15642                        procs.add(proc);
15643                    } else if (proc.processName.equals(args[start])) {
15644                        procs.add(proc);
15645                    }
15646                }
15647                if (procs.size() <= 0) {
15648                    return null;
15649                }
15650            } else {
15651                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15652            }
15653        }
15654        return procs;
15655    }
15656
15657    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15658            PrintWriter pw, String[] args) {
15659        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15660        if (procs == null) {
15661            pw.println("No process found for: " + args[0]);
15662            return;
15663        }
15664
15665        long uptime = SystemClock.uptimeMillis();
15666        long realtime = SystemClock.elapsedRealtime();
15667        pw.println("Applications Graphics Acceleration Info:");
15668        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15669
15670        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15671            ProcessRecord r = procs.get(i);
15672            if (r.thread != null) {
15673                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15674                pw.flush();
15675                try {
15676                    TransferPipe tp = new TransferPipe();
15677                    try {
15678                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15679                        tp.go(fd);
15680                    } finally {
15681                        tp.kill();
15682                    }
15683                } catch (IOException e) {
15684                    pw.println("Failure while dumping the app: " + r);
15685                    pw.flush();
15686                } catch (RemoteException e) {
15687                    pw.println("Got a RemoteException while dumping the app " + r);
15688                    pw.flush();
15689                }
15690            }
15691        }
15692    }
15693
15694    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15695        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15696        if (procs == null) {
15697            pw.println("No process found for: " + args[0]);
15698            return;
15699        }
15700
15701        pw.println("Applications Database Info:");
15702
15703        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15704            ProcessRecord r = procs.get(i);
15705            if (r.thread != null) {
15706                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15707                pw.flush();
15708                try {
15709                    TransferPipe tp = new TransferPipe();
15710                    try {
15711                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15712                        tp.go(fd);
15713                    } finally {
15714                        tp.kill();
15715                    }
15716                } catch (IOException e) {
15717                    pw.println("Failure while dumping the app: " + r);
15718                    pw.flush();
15719                } catch (RemoteException e) {
15720                    pw.println("Got a RemoteException while dumping the app " + r);
15721                    pw.flush();
15722                }
15723            }
15724        }
15725    }
15726
15727    final static class MemItem {
15728        final boolean isProc;
15729        final String label;
15730        final String shortLabel;
15731        final long pss;
15732        final long swapPss;
15733        final int id;
15734        final boolean hasActivities;
15735        ArrayList<MemItem> subitems;
15736
15737        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15738                boolean _hasActivities) {
15739            isProc = true;
15740            label = _label;
15741            shortLabel = _shortLabel;
15742            pss = _pss;
15743            swapPss = _swapPss;
15744            id = _id;
15745            hasActivities = _hasActivities;
15746        }
15747
15748        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15749            isProc = false;
15750            label = _label;
15751            shortLabel = _shortLabel;
15752            pss = _pss;
15753            swapPss = _swapPss;
15754            id = _id;
15755            hasActivities = false;
15756        }
15757    }
15758
15759    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15760            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15761        if (sort && !isCompact) {
15762            Collections.sort(items, new Comparator<MemItem>() {
15763                @Override
15764                public int compare(MemItem lhs, MemItem rhs) {
15765                    if (lhs.pss < rhs.pss) {
15766                        return 1;
15767                    } else if (lhs.pss > rhs.pss) {
15768                        return -1;
15769                    }
15770                    return 0;
15771                }
15772            });
15773        }
15774
15775        for (int i=0; i<items.size(); i++) {
15776            MemItem mi = items.get(i);
15777            if (!isCompact) {
15778                if (dumpSwapPss) {
15779                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15780                            mi.label, stringifyKBSize(mi.swapPss));
15781                } else {
15782                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15783                }
15784            } else if (mi.isProc) {
15785                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15786                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15787                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15788                pw.println(mi.hasActivities ? ",a" : ",e");
15789            } else {
15790                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15791                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15792            }
15793            if (mi.subitems != null) {
15794                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15795                        true, isCompact, dumpSwapPss);
15796            }
15797        }
15798    }
15799
15800    // These are in KB.
15801    static final long[] DUMP_MEM_BUCKETS = new long[] {
15802        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15803        120*1024, 160*1024, 200*1024,
15804        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15805        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15806    };
15807
15808    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15809            boolean stackLike) {
15810        int start = label.lastIndexOf('.');
15811        if (start >= 0) start++;
15812        else start = 0;
15813        int end = label.length();
15814        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15815            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15816                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15817                out.append(bucket);
15818                out.append(stackLike ? "MB." : "MB ");
15819                out.append(label, start, end);
15820                return;
15821            }
15822        }
15823        out.append(memKB/1024);
15824        out.append(stackLike ? "MB." : "MB ");
15825        out.append(label, start, end);
15826    }
15827
15828    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15829            ProcessList.NATIVE_ADJ,
15830            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15831            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15832            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15833            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15834            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15835            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15836    };
15837    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15838            "Native",
15839            "System", "Persistent", "Persistent Service", "Foreground",
15840            "Visible", "Perceptible",
15841            "Heavy Weight", "Backup",
15842            "A Services", "Home",
15843            "Previous", "B Services", "Cached"
15844    };
15845    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15846            "native",
15847            "sys", "pers", "persvc", "fore",
15848            "vis", "percept",
15849            "heavy", "backup",
15850            "servicea", "home",
15851            "prev", "serviceb", "cached"
15852    };
15853
15854    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15855            long realtime, boolean isCheckinRequest, boolean isCompact) {
15856        if (isCompact) {
15857            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15858        }
15859        if (isCheckinRequest || isCompact) {
15860            // short checkin version
15861            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15862        } else {
15863            pw.println("Applications Memory Usage (in Kilobytes):");
15864            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15865        }
15866    }
15867
15868    private static final int KSM_SHARED = 0;
15869    private static final int KSM_SHARING = 1;
15870    private static final int KSM_UNSHARED = 2;
15871    private static final int KSM_VOLATILE = 3;
15872
15873    private final long[] getKsmInfo() {
15874        long[] longOut = new long[4];
15875        final int[] SINGLE_LONG_FORMAT = new int[] {
15876            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15877        };
15878        long[] longTmp = new long[1];
15879        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15880                SINGLE_LONG_FORMAT, null, longTmp, null);
15881        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15882        longTmp[0] = 0;
15883        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15884                SINGLE_LONG_FORMAT, null, longTmp, null);
15885        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15886        longTmp[0] = 0;
15887        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15888                SINGLE_LONG_FORMAT, null, longTmp, null);
15889        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15890        longTmp[0] = 0;
15891        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15892                SINGLE_LONG_FORMAT, null, longTmp, null);
15893        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15894        return longOut;
15895    }
15896
15897    private static String stringifySize(long size, int order) {
15898        Locale locale = Locale.US;
15899        switch (order) {
15900            case 1:
15901                return String.format(locale, "%,13d", size);
15902            case 1024:
15903                return String.format(locale, "%,9dK", size / 1024);
15904            case 1024 * 1024:
15905                return String.format(locale, "%,5dM", size / 1024 / 1024);
15906            case 1024 * 1024 * 1024:
15907                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15908            default:
15909                throw new IllegalArgumentException("Invalid size order");
15910        }
15911    }
15912
15913    private static String stringifyKBSize(long size) {
15914        return stringifySize(size * 1024, 1024);
15915    }
15916
15917    // Update this version number in case you change the 'compact' format
15918    private static final int MEMINFO_COMPACT_VERSION = 1;
15919
15920    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15921            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15922        boolean dumpDetails = false;
15923        boolean dumpFullDetails = false;
15924        boolean dumpDalvik = false;
15925        boolean dumpSummaryOnly = false;
15926        boolean dumpUnreachable = false;
15927        boolean oomOnly = false;
15928        boolean isCompact = false;
15929        boolean localOnly = false;
15930        boolean packages = false;
15931        boolean isCheckinRequest = false;
15932        boolean dumpSwapPss = false;
15933
15934        int opti = 0;
15935        while (opti < args.length) {
15936            String opt = args[opti];
15937            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15938                break;
15939            }
15940            opti++;
15941            if ("-a".equals(opt)) {
15942                dumpDetails = true;
15943                dumpFullDetails = true;
15944                dumpDalvik = true;
15945                dumpSwapPss = true;
15946            } else if ("-d".equals(opt)) {
15947                dumpDalvik = true;
15948            } else if ("-c".equals(opt)) {
15949                isCompact = true;
15950            } else if ("-s".equals(opt)) {
15951                dumpDetails = true;
15952                dumpSummaryOnly = true;
15953            } else if ("-S".equals(opt)) {
15954                dumpSwapPss = true;
15955            } else if ("--unreachable".equals(opt)) {
15956                dumpUnreachable = true;
15957            } else if ("--oom".equals(opt)) {
15958                oomOnly = true;
15959            } else if ("--local".equals(opt)) {
15960                localOnly = true;
15961            } else if ("--package".equals(opt)) {
15962                packages = true;
15963            } else if ("--checkin".equals(opt)) {
15964                isCheckinRequest = true;
15965
15966            } else if ("-h".equals(opt)) {
15967                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15968                pw.println("  -a: include all available information for each process.");
15969                pw.println("  -d: include dalvik details.");
15970                pw.println("  -c: dump in a compact machine-parseable representation.");
15971                pw.println("  -s: dump only summary of application memory usage.");
15972                pw.println("  -S: dump also SwapPss.");
15973                pw.println("  --oom: only show processes organized by oom adj.");
15974                pw.println("  --local: only collect details locally, don't call process.");
15975                pw.println("  --package: interpret process arg as package, dumping all");
15976                pw.println("             processes that have loaded that package.");
15977                pw.println("  --checkin: dump data for a checkin");
15978                pw.println("If [process] is specified it can be the name or ");
15979                pw.println("pid of a specific process to dump.");
15980                return;
15981            } else {
15982                pw.println("Unknown argument: " + opt + "; use -h for help");
15983            }
15984        }
15985
15986        long uptime = SystemClock.uptimeMillis();
15987        long realtime = SystemClock.elapsedRealtime();
15988        final long[] tmpLong = new long[1];
15989
15990        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15991        if (procs == null) {
15992            // No Java processes.  Maybe they want to print a native process.
15993            if (args != null && args.length > opti
15994                    && args[opti].charAt(0) != '-') {
15995                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15996                        = new ArrayList<ProcessCpuTracker.Stats>();
15997                updateCpuStatsNow();
15998                int findPid = -1;
15999                try {
16000                    findPid = Integer.parseInt(args[opti]);
16001                } catch (NumberFormatException e) {
16002                }
16003                synchronized (mProcessCpuTracker) {
16004                    final int N = mProcessCpuTracker.countStats();
16005                    for (int i=0; i<N; i++) {
16006                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16007                        if (st.pid == findPid || (st.baseName != null
16008                                && st.baseName.equals(args[opti]))) {
16009                            nativeProcs.add(st);
16010                        }
16011                    }
16012                }
16013                if (nativeProcs.size() > 0) {
16014                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16015                            isCompact);
16016                    Debug.MemoryInfo mi = null;
16017                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16018                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16019                        final int pid = r.pid;
16020                        if (!isCheckinRequest && dumpDetails) {
16021                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16022                        }
16023                        if (mi == null) {
16024                            mi = new Debug.MemoryInfo();
16025                        }
16026                        if (dumpDetails || (!brief && !oomOnly)) {
16027                            Debug.getMemoryInfo(pid, mi);
16028                        } else {
16029                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16030                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16031                        }
16032                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16033                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16034                        if (isCheckinRequest) {
16035                            pw.println();
16036                        }
16037                    }
16038                    return;
16039                }
16040            }
16041            pw.println("No process found for: " + args[opti]);
16042            return;
16043        }
16044
16045        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16046            dumpDetails = true;
16047        }
16048
16049        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16050
16051        String[] innerArgs = new String[args.length-opti];
16052        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16053
16054        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16055        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16056        long nativePss = 0;
16057        long nativeSwapPss = 0;
16058        long dalvikPss = 0;
16059        long dalvikSwapPss = 0;
16060        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16061                EmptyArray.LONG;
16062        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16063                EmptyArray.LONG;
16064        long otherPss = 0;
16065        long otherSwapPss = 0;
16066        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16067        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16068
16069        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16070        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16071        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16072                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16073
16074        long totalPss = 0;
16075        long totalSwapPss = 0;
16076        long cachedPss = 0;
16077        long cachedSwapPss = 0;
16078        boolean hasSwapPss = false;
16079
16080        Debug.MemoryInfo mi = null;
16081        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16082            final ProcessRecord r = procs.get(i);
16083            final IApplicationThread thread;
16084            final int pid;
16085            final int oomAdj;
16086            final boolean hasActivities;
16087            synchronized (this) {
16088                thread = r.thread;
16089                pid = r.pid;
16090                oomAdj = r.getSetAdjWithServices();
16091                hasActivities = r.activities.size() > 0;
16092            }
16093            if (thread != null) {
16094                if (!isCheckinRequest && dumpDetails) {
16095                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16096                }
16097                if (mi == null) {
16098                    mi = new Debug.MemoryInfo();
16099                }
16100                if (dumpDetails || (!brief && !oomOnly)) {
16101                    Debug.getMemoryInfo(pid, mi);
16102                    hasSwapPss = mi.hasSwappedOutPss;
16103                } else {
16104                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16105                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16106                }
16107                if (dumpDetails) {
16108                    if (localOnly) {
16109                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16110                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16111                        if (isCheckinRequest) {
16112                            pw.println();
16113                        }
16114                    } else {
16115                        try {
16116                            pw.flush();
16117                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16118                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16119                        } catch (RemoteException e) {
16120                            if (!isCheckinRequest) {
16121                                pw.println("Got RemoteException!");
16122                                pw.flush();
16123                            }
16124                        }
16125                    }
16126                }
16127
16128                final long myTotalPss = mi.getTotalPss();
16129                final long myTotalUss = mi.getTotalUss();
16130                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16131
16132                synchronized (this) {
16133                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16134                        // Record this for posterity if the process has been stable.
16135                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16136                    }
16137                }
16138
16139                if (!isCheckinRequest && mi != null) {
16140                    totalPss += myTotalPss;
16141                    totalSwapPss += myTotalSwapPss;
16142                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16143                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16144                            myTotalSwapPss, pid, hasActivities);
16145                    procMems.add(pssItem);
16146                    procMemsMap.put(pid, pssItem);
16147
16148                    nativePss += mi.nativePss;
16149                    nativeSwapPss += mi.nativeSwappedOutPss;
16150                    dalvikPss += mi.dalvikPss;
16151                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16152                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16153                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16154                        dalvikSubitemSwapPss[j] +=
16155                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16156                    }
16157                    otherPss += mi.otherPss;
16158                    otherSwapPss += mi.otherSwappedOutPss;
16159                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16160                        long mem = mi.getOtherPss(j);
16161                        miscPss[j] += mem;
16162                        otherPss -= mem;
16163                        mem = mi.getOtherSwappedOutPss(j);
16164                        miscSwapPss[j] += mem;
16165                        otherSwapPss -= mem;
16166                    }
16167
16168                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16169                        cachedPss += myTotalPss;
16170                        cachedSwapPss += myTotalSwapPss;
16171                    }
16172
16173                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16174                        if (oomIndex == (oomPss.length - 1)
16175                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16176                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16177                            oomPss[oomIndex] += myTotalPss;
16178                            oomSwapPss[oomIndex] += myTotalSwapPss;
16179                            if (oomProcs[oomIndex] == null) {
16180                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16181                            }
16182                            oomProcs[oomIndex].add(pssItem);
16183                            break;
16184                        }
16185                    }
16186                }
16187            }
16188        }
16189
16190        long nativeProcTotalPss = 0;
16191
16192        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16193            // If we are showing aggregations, also look for native processes to
16194            // include so that our aggregations are more accurate.
16195            updateCpuStatsNow();
16196            mi = null;
16197            synchronized (mProcessCpuTracker) {
16198                final int N = mProcessCpuTracker.countStats();
16199                for (int i=0; i<N; i++) {
16200                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16201                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16202                        if (mi == null) {
16203                            mi = new Debug.MemoryInfo();
16204                        }
16205                        if (!brief && !oomOnly) {
16206                            Debug.getMemoryInfo(st.pid, mi);
16207                        } else {
16208                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16209                            mi.nativePrivateDirty = (int)tmpLong[0];
16210                        }
16211
16212                        final long myTotalPss = mi.getTotalPss();
16213                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16214                        totalPss += myTotalPss;
16215                        nativeProcTotalPss += myTotalPss;
16216
16217                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16218                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16219                        procMems.add(pssItem);
16220
16221                        nativePss += mi.nativePss;
16222                        nativeSwapPss += mi.nativeSwappedOutPss;
16223                        dalvikPss += mi.dalvikPss;
16224                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16225                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16226                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16227                            dalvikSubitemSwapPss[j] +=
16228                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16229                        }
16230                        otherPss += mi.otherPss;
16231                        otherSwapPss += mi.otherSwappedOutPss;
16232                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16233                            long mem = mi.getOtherPss(j);
16234                            miscPss[j] += mem;
16235                            otherPss -= mem;
16236                            mem = mi.getOtherSwappedOutPss(j);
16237                            miscSwapPss[j] += mem;
16238                            otherSwapPss -= mem;
16239                        }
16240                        oomPss[0] += myTotalPss;
16241                        oomSwapPss[0] += myTotalSwapPss;
16242                        if (oomProcs[0] == null) {
16243                            oomProcs[0] = new ArrayList<MemItem>();
16244                        }
16245                        oomProcs[0].add(pssItem);
16246                    }
16247                }
16248            }
16249
16250            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16251
16252            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16253            final MemItem dalvikItem =
16254                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16255            if (dalvikSubitemPss.length > 0) {
16256                dalvikItem.subitems = new ArrayList<MemItem>();
16257                for (int j=0; j<dalvikSubitemPss.length; j++) {
16258                    final String name = Debug.MemoryInfo.getOtherLabel(
16259                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16260                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16261                                    dalvikSubitemSwapPss[j], j));
16262                }
16263            }
16264            catMems.add(dalvikItem);
16265            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16266            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16267                String label = Debug.MemoryInfo.getOtherLabel(j);
16268                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16269            }
16270
16271            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16272            for (int j=0; j<oomPss.length; j++) {
16273                if (oomPss[j] != 0) {
16274                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16275                            : DUMP_MEM_OOM_LABEL[j];
16276                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16277                            DUMP_MEM_OOM_ADJ[j]);
16278                    item.subitems = oomProcs[j];
16279                    oomMems.add(item);
16280                }
16281            }
16282
16283            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16284            if (!brief && !oomOnly && !isCompact) {
16285                pw.println();
16286                pw.println("Total PSS by process:");
16287                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16288                pw.println();
16289            }
16290            if (!isCompact) {
16291                pw.println("Total PSS by OOM adjustment:");
16292            }
16293            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16294            if (!brief && !oomOnly) {
16295                PrintWriter out = categoryPw != null ? categoryPw : pw;
16296                if (!isCompact) {
16297                    out.println();
16298                    out.println("Total PSS by category:");
16299                }
16300                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16301            }
16302            if (!isCompact) {
16303                pw.println();
16304            }
16305            MemInfoReader memInfo = new MemInfoReader();
16306            memInfo.readMemInfo();
16307            if (nativeProcTotalPss > 0) {
16308                synchronized (this) {
16309                    final long cachedKb = memInfo.getCachedSizeKb();
16310                    final long freeKb = memInfo.getFreeSizeKb();
16311                    final long zramKb = memInfo.getZramTotalSizeKb();
16312                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16313                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16314                            kernelKb*1024, nativeProcTotalPss*1024);
16315                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16316                            nativeProcTotalPss);
16317                }
16318            }
16319            if (!brief) {
16320                if (!isCompact) {
16321                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16322                    pw.print(" (status ");
16323                    switch (mLastMemoryLevel) {
16324                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16325                            pw.println("normal)");
16326                            break;
16327                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16328                            pw.println("moderate)");
16329                            break;
16330                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16331                            pw.println("low)");
16332                            break;
16333                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16334                            pw.println("critical)");
16335                            break;
16336                        default:
16337                            pw.print(mLastMemoryLevel);
16338                            pw.println(")");
16339                            break;
16340                    }
16341                    pw.print(" Free RAM: ");
16342                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16343                            + memInfo.getFreeSizeKb()));
16344                    pw.print(" (");
16345                    pw.print(stringifyKBSize(cachedPss));
16346                    pw.print(" cached pss + ");
16347                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16348                    pw.print(" cached kernel + ");
16349                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16350                    pw.println(" free)");
16351                } else {
16352                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16353                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16354                            + memInfo.getFreeSizeKb()); pw.print(",");
16355                    pw.println(totalPss - cachedPss);
16356                }
16357            }
16358            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16359                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16360                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16361            if (!isCompact) {
16362                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16363                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16364                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16365                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16366                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16367            } else {
16368                pw.print("lostram,"); pw.println(lostRAM);
16369            }
16370            if (!brief) {
16371                if (memInfo.getZramTotalSizeKb() != 0) {
16372                    if (!isCompact) {
16373                        pw.print("     ZRAM: ");
16374                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16375                                pw.print(" physical used for ");
16376                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16377                                        - memInfo.getSwapFreeSizeKb()));
16378                                pw.print(" in swap (");
16379                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16380                                pw.println(" total swap)");
16381                    } else {
16382                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16383                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16384                                pw.println(memInfo.getSwapFreeSizeKb());
16385                    }
16386                }
16387                final long[] ksm = getKsmInfo();
16388                if (!isCompact) {
16389                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16390                            || ksm[KSM_VOLATILE] != 0) {
16391                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16392                                pw.print(" saved from shared ");
16393                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16394                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16395                                pw.print(" unshared; ");
16396                                pw.print(stringifyKBSize(
16397                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16398                    }
16399                    pw.print("   Tuning: ");
16400                    pw.print(ActivityManager.staticGetMemoryClass());
16401                    pw.print(" (large ");
16402                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16403                    pw.print("), oom ");
16404                    pw.print(stringifySize(
16405                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16406                    pw.print(", restore limit ");
16407                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16408                    if (ActivityManager.isLowRamDeviceStatic()) {
16409                        pw.print(" (low-ram)");
16410                    }
16411                    if (ActivityManager.isHighEndGfx()) {
16412                        pw.print(" (high-end-gfx)");
16413                    }
16414                    pw.println();
16415                } else {
16416                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16417                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16418                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16419                    pw.print("tuning,");
16420                    pw.print(ActivityManager.staticGetMemoryClass());
16421                    pw.print(',');
16422                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16423                    pw.print(',');
16424                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16425                    if (ActivityManager.isLowRamDeviceStatic()) {
16426                        pw.print(",low-ram");
16427                    }
16428                    if (ActivityManager.isHighEndGfx()) {
16429                        pw.print(",high-end-gfx");
16430                    }
16431                    pw.println();
16432                }
16433            }
16434        }
16435    }
16436
16437    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16438            long memtrack, String name) {
16439        sb.append("  ");
16440        sb.append(ProcessList.makeOomAdjString(oomAdj));
16441        sb.append(' ');
16442        sb.append(ProcessList.makeProcStateString(procState));
16443        sb.append(' ');
16444        ProcessList.appendRamKb(sb, pss);
16445        sb.append(": ");
16446        sb.append(name);
16447        if (memtrack > 0) {
16448            sb.append(" (");
16449            sb.append(stringifyKBSize(memtrack));
16450            sb.append(" memtrack)");
16451        }
16452    }
16453
16454    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16455        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16456        sb.append(" (pid ");
16457        sb.append(mi.pid);
16458        sb.append(") ");
16459        sb.append(mi.adjType);
16460        sb.append('\n');
16461        if (mi.adjReason != null) {
16462            sb.append("                      ");
16463            sb.append(mi.adjReason);
16464            sb.append('\n');
16465        }
16466    }
16467
16468    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16469        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16470        for (int i=0, N=memInfos.size(); i<N; i++) {
16471            ProcessMemInfo mi = memInfos.get(i);
16472            infoMap.put(mi.pid, mi);
16473        }
16474        updateCpuStatsNow();
16475        long[] memtrackTmp = new long[1];
16476        synchronized (mProcessCpuTracker) {
16477            final int N = mProcessCpuTracker.countStats();
16478            for (int i=0; i<N; i++) {
16479                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16480                if (st.vsize > 0) {
16481                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16482                    if (pss > 0) {
16483                        if (infoMap.indexOfKey(st.pid) < 0) {
16484                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16485                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16486                            mi.pss = pss;
16487                            mi.memtrack = memtrackTmp[0];
16488                            memInfos.add(mi);
16489                        }
16490                    }
16491                }
16492            }
16493        }
16494
16495        long totalPss = 0;
16496        long totalMemtrack = 0;
16497        for (int i=0, N=memInfos.size(); i<N; i++) {
16498            ProcessMemInfo mi = memInfos.get(i);
16499            if (mi.pss == 0) {
16500                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16501                mi.memtrack = memtrackTmp[0];
16502            }
16503            totalPss += mi.pss;
16504            totalMemtrack += mi.memtrack;
16505        }
16506        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16507            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16508                if (lhs.oomAdj != rhs.oomAdj) {
16509                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16510                }
16511                if (lhs.pss != rhs.pss) {
16512                    return lhs.pss < rhs.pss ? 1 : -1;
16513                }
16514                return 0;
16515            }
16516        });
16517
16518        StringBuilder tag = new StringBuilder(128);
16519        StringBuilder stack = new StringBuilder(128);
16520        tag.append("Low on memory -- ");
16521        appendMemBucket(tag, totalPss, "total", false);
16522        appendMemBucket(stack, totalPss, "total", true);
16523
16524        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16525        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16526        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16527
16528        boolean firstLine = true;
16529        int lastOomAdj = Integer.MIN_VALUE;
16530        long extraNativeRam = 0;
16531        long extraNativeMemtrack = 0;
16532        long cachedPss = 0;
16533        for (int i=0, N=memInfos.size(); i<N; i++) {
16534            ProcessMemInfo mi = memInfos.get(i);
16535
16536            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16537                cachedPss += mi.pss;
16538            }
16539
16540            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16541                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16542                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16543                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16544                if (lastOomAdj != mi.oomAdj) {
16545                    lastOomAdj = mi.oomAdj;
16546                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16547                        tag.append(" / ");
16548                    }
16549                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16550                        if (firstLine) {
16551                            stack.append(":");
16552                            firstLine = false;
16553                        }
16554                        stack.append("\n\t at ");
16555                    } else {
16556                        stack.append("$");
16557                    }
16558                } else {
16559                    tag.append(" ");
16560                    stack.append("$");
16561                }
16562                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16563                    appendMemBucket(tag, mi.pss, mi.name, false);
16564                }
16565                appendMemBucket(stack, mi.pss, mi.name, true);
16566                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16567                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16568                    stack.append("(");
16569                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16570                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16571                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16572                            stack.append(":");
16573                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16574                        }
16575                    }
16576                    stack.append(")");
16577                }
16578            }
16579
16580            appendMemInfo(fullNativeBuilder, mi);
16581            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16582                // The short form only has native processes that are >= 512K.
16583                if (mi.pss >= 512) {
16584                    appendMemInfo(shortNativeBuilder, mi);
16585                } else {
16586                    extraNativeRam += mi.pss;
16587                    extraNativeMemtrack += mi.memtrack;
16588                }
16589            } else {
16590                // Short form has all other details, but if we have collected RAM
16591                // from smaller native processes let's dump a summary of that.
16592                if (extraNativeRam > 0) {
16593                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16594                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16595                    shortNativeBuilder.append('\n');
16596                    extraNativeRam = 0;
16597                }
16598                appendMemInfo(fullJavaBuilder, mi);
16599            }
16600        }
16601
16602        fullJavaBuilder.append("           ");
16603        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16604        fullJavaBuilder.append(": TOTAL");
16605        if (totalMemtrack > 0) {
16606            fullJavaBuilder.append(" (");
16607            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16608            fullJavaBuilder.append(" memtrack)");
16609        } else {
16610        }
16611        fullJavaBuilder.append("\n");
16612
16613        MemInfoReader memInfo = new MemInfoReader();
16614        memInfo.readMemInfo();
16615        final long[] infos = memInfo.getRawInfo();
16616
16617        StringBuilder memInfoBuilder = new StringBuilder(1024);
16618        Debug.getMemInfo(infos);
16619        memInfoBuilder.append("  MemInfo: ");
16620        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16621        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16622        memInfoBuilder.append(stringifyKBSize(
16623                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16624        memInfoBuilder.append(stringifyKBSize(
16625                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16626        memInfoBuilder.append(stringifyKBSize(
16627                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16628        memInfoBuilder.append("           ");
16629        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16630        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16631        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16632        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16633        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16634            memInfoBuilder.append("  ZRAM: ");
16635            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16636            memInfoBuilder.append(" RAM, ");
16637            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16638            memInfoBuilder.append(" swap total, ");
16639            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16640            memInfoBuilder.append(" swap free\n");
16641        }
16642        final long[] ksm = getKsmInfo();
16643        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16644                || ksm[KSM_VOLATILE] != 0) {
16645            memInfoBuilder.append("  KSM: ");
16646            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16647            memInfoBuilder.append(" saved from shared ");
16648            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16649            memInfoBuilder.append("\n       ");
16650            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16651            memInfoBuilder.append(" unshared; ");
16652            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16653            memInfoBuilder.append(" volatile\n");
16654        }
16655        memInfoBuilder.append("  Free RAM: ");
16656        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16657                + memInfo.getFreeSizeKb()));
16658        memInfoBuilder.append("\n");
16659        memInfoBuilder.append("  Used RAM: ");
16660        memInfoBuilder.append(stringifyKBSize(
16661                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16662        memInfoBuilder.append("\n");
16663        memInfoBuilder.append("  Lost RAM: ");
16664        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16665                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16666                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16667        memInfoBuilder.append("\n");
16668        Slog.i(TAG, "Low on memory:");
16669        Slog.i(TAG, shortNativeBuilder.toString());
16670        Slog.i(TAG, fullJavaBuilder.toString());
16671        Slog.i(TAG, memInfoBuilder.toString());
16672
16673        StringBuilder dropBuilder = new StringBuilder(1024);
16674        /*
16675        StringWriter oomSw = new StringWriter();
16676        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16677        StringWriter catSw = new StringWriter();
16678        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16679        String[] emptyArgs = new String[] { };
16680        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16681        oomPw.flush();
16682        String oomString = oomSw.toString();
16683        */
16684        dropBuilder.append("Low on memory:");
16685        dropBuilder.append(stack);
16686        dropBuilder.append('\n');
16687        dropBuilder.append(fullNativeBuilder);
16688        dropBuilder.append(fullJavaBuilder);
16689        dropBuilder.append('\n');
16690        dropBuilder.append(memInfoBuilder);
16691        dropBuilder.append('\n');
16692        /*
16693        dropBuilder.append(oomString);
16694        dropBuilder.append('\n');
16695        */
16696        StringWriter catSw = new StringWriter();
16697        synchronized (ActivityManagerService.this) {
16698            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16699            String[] emptyArgs = new String[] { };
16700            catPw.println();
16701            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16702            catPw.println();
16703            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16704                    false, null).dumpLocked();
16705            catPw.println();
16706            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16707            catPw.flush();
16708        }
16709        dropBuilder.append(catSw.toString());
16710        addErrorToDropBox("lowmem", null, "system_server", null,
16711                null, tag.toString(), dropBuilder.toString(), null, null);
16712        //Slog.i(TAG, "Sent to dropbox:");
16713        //Slog.i(TAG, dropBuilder.toString());
16714        synchronized (ActivityManagerService.this) {
16715            long now = SystemClock.uptimeMillis();
16716            if (mLastMemUsageReportTime < now) {
16717                mLastMemUsageReportTime = now;
16718            }
16719        }
16720    }
16721
16722    /**
16723     * Searches array of arguments for the specified string
16724     * @param args array of argument strings
16725     * @param value value to search for
16726     * @return true if the value is contained in the array
16727     */
16728    private static boolean scanArgs(String[] args, String value) {
16729        if (args != null) {
16730            for (String arg : args) {
16731                if (value.equals(arg)) {
16732                    return true;
16733                }
16734            }
16735        }
16736        return false;
16737    }
16738
16739    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16740            ContentProviderRecord cpr, boolean always) {
16741        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16742
16743        if (!inLaunching || always) {
16744            synchronized (cpr) {
16745                cpr.launchingApp = null;
16746                cpr.notifyAll();
16747            }
16748            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16749            String names[] = cpr.info.authority.split(";");
16750            for (int j = 0; j < names.length; j++) {
16751                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16752            }
16753        }
16754
16755        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16756            ContentProviderConnection conn = cpr.connections.get(i);
16757            if (conn.waiting) {
16758                // If this connection is waiting for the provider, then we don't
16759                // need to mess with its process unless we are always removing
16760                // or for some reason the provider is not currently launching.
16761                if (inLaunching && !always) {
16762                    continue;
16763                }
16764            }
16765            ProcessRecord capp = conn.client;
16766            conn.dead = true;
16767            if (conn.stableCount > 0) {
16768                if (!capp.persistent && capp.thread != null
16769                        && capp.pid != 0
16770                        && capp.pid != MY_PID) {
16771                    capp.kill("depends on provider "
16772                            + cpr.name.flattenToShortString()
16773                            + " in dying proc " + (proc != null ? proc.processName : "??")
16774                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16775                }
16776            } else if (capp.thread != null && conn.provider.provider != null) {
16777                try {
16778                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16779                } catch (RemoteException e) {
16780                }
16781                // In the protocol here, we don't expect the client to correctly
16782                // clean up this connection, we'll just remove it.
16783                cpr.connections.remove(i);
16784                if (conn.client.conProviders.remove(conn)) {
16785                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16786                }
16787            }
16788        }
16789
16790        if (inLaunching && always) {
16791            mLaunchingProviders.remove(cpr);
16792        }
16793        return inLaunching;
16794    }
16795
16796    /**
16797     * Main code for cleaning up a process when it has gone away.  This is
16798     * called both as a result of the process dying, or directly when stopping
16799     * a process when running in single process mode.
16800     *
16801     * @return Returns true if the given process has been restarted, so the
16802     * app that was passed in must remain on the process lists.
16803     */
16804    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16805            boolean restarting, boolean allowRestart, int index) {
16806        if (index >= 0) {
16807            removeLruProcessLocked(app);
16808            ProcessList.remove(app.pid);
16809        }
16810
16811        mProcessesToGc.remove(app);
16812        mPendingPssProcesses.remove(app);
16813
16814        // Dismiss any open dialogs.
16815        if (app.crashDialog != null && !app.forceCrashReport) {
16816            app.crashDialog.dismiss();
16817            app.crashDialog = null;
16818        }
16819        if (app.anrDialog != null) {
16820            app.anrDialog.dismiss();
16821            app.anrDialog = null;
16822        }
16823        if (app.waitDialog != null) {
16824            app.waitDialog.dismiss();
16825            app.waitDialog = null;
16826        }
16827
16828        app.crashing = false;
16829        app.notResponding = false;
16830
16831        app.resetPackageList(mProcessStats);
16832        app.unlinkDeathRecipient();
16833        app.makeInactive(mProcessStats);
16834        app.waitingToKill = null;
16835        app.forcingToForeground = null;
16836        updateProcessForegroundLocked(app, false, false);
16837        app.foregroundActivities = false;
16838        app.hasShownUi = false;
16839        app.treatLikeActivity = false;
16840        app.hasAboveClient = false;
16841        app.hasClientActivities = false;
16842
16843        mServices.killServicesLocked(app, allowRestart);
16844
16845        boolean restart = false;
16846
16847        // Remove published content providers.
16848        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16849            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16850            final boolean always = app.bad || !allowRestart;
16851            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16852            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16853                // We left the provider in the launching list, need to
16854                // restart it.
16855                restart = true;
16856            }
16857
16858            cpr.provider = null;
16859            cpr.proc = null;
16860        }
16861        app.pubProviders.clear();
16862
16863        // Take care of any launching providers waiting for this process.
16864        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16865            restart = true;
16866        }
16867
16868        // Unregister from connected content providers.
16869        if (!app.conProviders.isEmpty()) {
16870            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16871                ContentProviderConnection conn = app.conProviders.get(i);
16872                conn.provider.connections.remove(conn);
16873                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16874                        conn.provider.name);
16875            }
16876            app.conProviders.clear();
16877        }
16878
16879        // At this point there may be remaining entries in mLaunchingProviders
16880        // where we were the only one waiting, so they are no longer of use.
16881        // Look for these and clean up if found.
16882        // XXX Commented out for now.  Trying to figure out a way to reproduce
16883        // the actual situation to identify what is actually going on.
16884        if (false) {
16885            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16886                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16887                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16888                    synchronized (cpr) {
16889                        cpr.launchingApp = null;
16890                        cpr.notifyAll();
16891                    }
16892                }
16893            }
16894        }
16895
16896        skipCurrentReceiverLocked(app);
16897
16898        // Unregister any receivers.
16899        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16900            removeReceiverLocked(app.receivers.valueAt(i));
16901        }
16902        app.receivers.clear();
16903
16904        // If the app is undergoing backup, tell the backup manager about it
16905        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16906            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16907                    + mBackupTarget.appInfo + " died during backup");
16908            try {
16909                IBackupManager bm = IBackupManager.Stub.asInterface(
16910                        ServiceManager.getService(Context.BACKUP_SERVICE));
16911                bm.agentDisconnected(app.info.packageName);
16912            } catch (RemoteException e) {
16913                // can't happen; backup manager is local
16914            }
16915        }
16916
16917        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16918            ProcessChangeItem item = mPendingProcessChanges.get(i);
16919            if (item.pid == app.pid) {
16920                mPendingProcessChanges.remove(i);
16921                mAvailProcessChanges.add(item);
16922            }
16923        }
16924        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16925                null).sendToTarget();
16926
16927        // If the caller is restarting this app, then leave it in its
16928        // current lists and let the caller take care of it.
16929        if (restarting) {
16930            return false;
16931        }
16932
16933        if (!app.persistent || app.isolated) {
16934            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16935                    "Removing non-persistent process during cleanup: " + app);
16936            removeProcessNameLocked(app.processName, app.uid);
16937            if (mHeavyWeightProcess == app) {
16938                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16939                        mHeavyWeightProcess.userId, 0));
16940                mHeavyWeightProcess = null;
16941            }
16942        } else if (!app.removed) {
16943            // This app is persistent, so we need to keep its record around.
16944            // If it is not already on the pending app list, add it there
16945            // and start a new process for it.
16946            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16947                mPersistentStartingProcesses.add(app);
16948                restart = true;
16949            }
16950        }
16951        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16952                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16953        mProcessesOnHold.remove(app);
16954
16955        if (app == mHomeProcess) {
16956            mHomeProcess = null;
16957        }
16958        if (app == mPreviousProcess) {
16959            mPreviousProcess = null;
16960        }
16961
16962        if (restart && !app.isolated) {
16963            // We have components that still need to be running in the
16964            // process, so re-launch it.
16965            if (index < 0) {
16966                ProcessList.remove(app.pid);
16967            }
16968            addProcessNameLocked(app);
16969            startProcessLocked(app, "restart", app.processName);
16970            return true;
16971        } else if (app.pid > 0 && app.pid != MY_PID) {
16972            // Goodbye!
16973            boolean removed;
16974            synchronized (mPidsSelfLocked) {
16975                mPidsSelfLocked.remove(app.pid);
16976                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16977            }
16978            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16979            if (app.isolated) {
16980                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16981            }
16982            app.setPid(0);
16983        }
16984        return false;
16985    }
16986
16987    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16988        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16989            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16990            if (cpr.launchingApp == app) {
16991                return true;
16992            }
16993        }
16994        return false;
16995    }
16996
16997    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16998        // Look through the content providers we are waiting to have launched,
16999        // and if any run in this process then either schedule a restart of
17000        // the process or kill the client waiting for it if this process has
17001        // gone bad.
17002        boolean restart = false;
17003        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17004            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17005            if (cpr.launchingApp == app) {
17006                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17007                    restart = true;
17008                } else {
17009                    removeDyingProviderLocked(app, cpr, true);
17010                }
17011            }
17012        }
17013        return restart;
17014    }
17015
17016    // =========================================================
17017    // SERVICES
17018    // =========================================================
17019
17020    @Override
17021    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17022            int flags) {
17023        enforceNotIsolatedCaller("getServices");
17024        synchronized (this) {
17025            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17026        }
17027    }
17028
17029    @Override
17030    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17031        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17032        synchronized (this) {
17033            return mServices.getRunningServiceControlPanelLocked(name);
17034        }
17035    }
17036
17037    @Override
17038    public ComponentName startService(IApplicationThread caller, Intent service,
17039            String resolvedType, String callingPackage, int userId)
17040            throws TransactionTooLargeException {
17041        enforceNotIsolatedCaller("startService");
17042        // Refuse possible leaked file descriptors
17043        if (service != null && service.hasFileDescriptors() == true) {
17044            throw new IllegalArgumentException("File descriptors passed in Intent");
17045        }
17046
17047        if (callingPackage == null) {
17048            throw new IllegalArgumentException("callingPackage cannot be null");
17049        }
17050
17051        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17052                "startService: " + service + " type=" + resolvedType);
17053        synchronized(this) {
17054            final int callingPid = Binder.getCallingPid();
17055            final int callingUid = Binder.getCallingUid();
17056            final long origId = Binder.clearCallingIdentity();
17057            ComponentName res = mServices.startServiceLocked(caller, service,
17058                    resolvedType, callingPid, callingUid, callingPackage, userId);
17059            Binder.restoreCallingIdentity(origId);
17060            return res;
17061        }
17062    }
17063
17064    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17065            String callingPackage, int userId)
17066            throws TransactionTooLargeException {
17067        synchronized(this) {
17068            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17069                    "startServiceInPackage: " + service + " type=" + resolvedType);
17070            final long origId = Binder.clearCallingIdentity();
17071            ComponentName res = mServices.startServiceLocked(null, service,
17072                    resolvedType, -1, uid, callingPackage, userId);
17073            Binder.restoreCallingIdentity(origId);
17074            return res;
17075        }
17076    }
17077
17078    @Override
17079    public int stopService(IApplicationThread caller, Intent service,
17080            String resolvedType, int userId) {
17081        enforceNotIsolatedCaller("stopService");
17082        // Refuse possible leaked file descriptors
17083        if (service != null && service.hasFileDescriptors() == true) {
17084            throw new IllegalArgumentException("File descriptors passed in Intent");
17085        }
17086
17087        synchronized(this) {
17088            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17089        }
17090    }
17091
17092    @Override
17093    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17094        enforceNotIsolatedCaller("peekService");
17095        // Refuse possible leaked file descriptors
17096        if (service != null && service.hasFileDescriptors() == true) {
17097            throw new IllegalArgumentException("File descriptors passed in Intent");
17098        }
17099
17100        if (callingPackage == null) {
17101            throw new IllegalArgumentException("callingPackage cannot be null");
17102        }
17103
17104        synchronized(this) {
17105            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17106        }
17107    }
17108
17109    @Override
17110    public boolean stopServiceToken(ComponentName className, IBinder token,
17111            int startId) {
17112        synchronized(this) {
17113            return mServices.stopServiceTokenLocked(className, token, startId);
17114        }
17115    }
17116
17117    @Override
17118    public void setServiceForeground(ComponentName className, IBinder token,
17119            int id, Notification notification, int flags) {
17120        synchronized(this) {
17121            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17122        }
17123    }
17124
17125    @Override
17126    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17127            boolean requireFull, String name, String callerPackage) {
17128        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17129                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17130    }
17131
17132    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17133            String className, int flags) {
17134        boolean result = false;
17135        // For apps that don't have pre-defined UIDs, check for permission
17136        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17137            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17138                if (ActivityManager.checkUidPermission(
17139                        INTERACT_ACROSS_USERS,
17140                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17141                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17142                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17143                            + " requests FLAG_SINGLE_USER, but app does not hold "
17144                            + INTERACT_ACROSS_USERS;
17145                    Slog.w(TAG, msg);
17146                    throw new SecurityException(msg);
17147                }
17148                // Permission passed
17149                result = true;
17150            }
17151        } else if ("system".equals(componentProcessName)) {
17152            result = true;
17153        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17154            // Phone app and persistent apps are allowed to export singleuser providers.
17155            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17156                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17157        }
17158        if (DEBUG_MU) Slog.v(TAG_MU,
17159                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17160                + Integer.toHexString(flags) + ") = " + result);
17161        return result;
17162    }
17163
17164    /**
17165     * Checks to see if the caller is in the same app as the singleton
17166     * component, or the component is in a special app. It allows special apps
17167     * to export singleton components but prevents exporting singleton
17168     * components for regular apps.
17169     */
17170    boolean isValidSingletonCall(int callingUid, int componentUid) {
17171        int componentAppId = UserHandle.getAppId(componentUid);
17172        return UserHandle.isSameApp(callingUid, componentUid)
17173                || componentAppId == Process.SYSTEM_UID
17174                || componentAppId == Process.PHONE_UID
17175                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17176                        == PackageManager.PERMISSION_GRANTED;
17177    }
17178
17179    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17180            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17181            int userId) throws TransactionTooLargeException {
17182        enforceNotIsolatedCaller("bindService");
17183
17184        // Refuse possible leaked file descriptors
17185        if (service != null && service.hasFileDescriptors() == true) {
17186            throw new IllegalArgumentException("File descriptors passed in Intent");
17187        }
17188
17189        if (callingPackage == null) {
17190            throw new IllegalArgumentException("callingPackage cannot be null");
17191        }
17192
17193        synchronized(this) {
17194            return mServices.bindServiceLocked(caller, token, service,
17195                    resolvedType, connection, flags, callingPackage, userId);
17196        }
17197    }
17198
17199    public boolean unbindService(IServiceConnection connection) {
17200        synchronized (this) {
17201            return mServices.unbindServiceLocked(connection);
17202        }
17203    }
17204
17205    public void publishService(IBinder token, Intent intent, IBinder service) {
17206        // Refuse possible leaked file descriptors
17207        if (intent != null && intent.hasFileDescriptors() == true) {
17208            throw new IllegalArgumentException("File descriptors passed in Intent");
17209        }
17210
17211        synchronized(this) {
17212            if (!(token instanceof ServiceRecord)) {
17213                throw new IllegalArgumentException("Invalid service token");
17214            }
17215            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17216        }
17217    }
17218
17219    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17220        // Refuse possible leaked file descriptors
17221        if (intent != null && intent.hasFileDescriptors() == true) {
17222            throw new IllegalArgumentException("File descriptors passed in Intent");
17223        }
17224
17225        synchronized(this) {
17226            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17227        }
17228    }
17229
17230    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17231        synchronized(this) {
17232            if (!(token instanceof ServiceRecord)) {
17233                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17234                throw new IllegalArgumentException("Invalid service token");
17235            }
17236            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17237        }
17238    }
17239
17240    // =========================================================
17241    // BACKUP AND RESTORE
17242    // =========================================================
17243
17244    // Cause the target app to be launched if necessary and its backup agent
17245    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17246    // activity manager to announce its creation.
17247    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17248        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17249        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17250
17251        IPackageManager pm = AppGlobals.getPackageManager();
17252        ApplicationInfo app = null;
17253        try {
17254            app = pm.getApplicationInfo(packageName, 0, userId);
17255        } catch (RemoteException e) {
17256            // can't happen; package manager is process-local
17257        }
17258        if (app == null) {
17259            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17260            return false;
17261        }
17262
17263        synchronized(this) {
17264            // !!! TODO: currently no check here that we're already bound
17265            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17266            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17267            synchronized (stats) {
17268                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17269            }
17270
17271            // Backup agent is now in use, its package can't be stopped.
17272            try {
17273                AppGlobals.getPackageManager().setPackageStoppedState(
17274                        app.packageName, false, UserHandle.getUserId(app.uid));
17275            } catch (RemoteException e) {
17276            } catch (IllegalArgumentException e) {
17277                Slog.w(TAG, "Failed trying to unstop package "
17278                        + app.packageName + ": " + e);
17279            }
17280
17281            BackupRecord r = new BackupRecord(ss, app, backupMode);
17282            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17283                    ? new ComponentName(app.packageName, app.backupAgentName)
17284                    : new ComponentName("android", "FullBackupAgent");
17285            // startProcessLocked() returns existing proc's record if it's already running
17286            ProcessRecord proc = startProcessLocked(app.processName, app,
17287                    false, 0, "backup", hostingName, false, false, false);
17288            if (proc == null) {
17289                Slog.e(TAG, "Unable to start backup agent process " + r);
17290                return false;
17291            }
17292
17293            // If the app is a regular app (uid >= 10000) and not the system server or phone
17294            // process, etc, then mark it as being in full backup so that certain calls to the
17295            // process can be blocked. This is not reset to false anywhere because we kill the
17296            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17297            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17298                proc.inFullBackup = true;
17299            }
17300            r.app = proc;
17301            mBackupTarget = r;
17302            mBackupAppName = app.packageName;
17303
17304            // Try not to kill the process during backup
17305            updateOomAdjLocked(proc);
17306
17307            // If the process is already attached, schedule the creation of the backup agent now.
17308            // If it is not yet live, this will be done when it attaches to the framework.
17309            if (proc.thread != null) {
17310                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17311                try {
17312                    proc.thread.scheduleCreateBackupAgent(app,
17313                            compatibilityInfoForPackageLocked(app), backupMode);
17314                } catch (RemoteException e) {
17315                    // Will time out on the backup manager side
17316                }
17317            } else {
17318                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17319            }
17320            // Invariants: at this point, the target app process exists and the application
17321            // is either already running or in the process of coming up.  mBackupTarget and
17322            // mBackupAppName describe the app, so that when it binds back to the AM we
17323            // know that it's scheduled for a backup-agent operation.
17324        }
17325
17326        return true;
17327    }
17328
17329    @Override
17330    public void clearPendingBackup() {
17331        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17332        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17333
17334        synchronized (this) {
17335            mBackupTarget = null;
17336            mBackupAppName = null;
17337        }
17338    }
17339
17340    // A backup agent has just come up
17341    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17342        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17343                + " = " + agent);
17344
17345        synchronized(this) {
17346            if (!agentPackageName.equals(mBackupAppName)) {
17347                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17348                return;
17349            }
17350        }
17351
17352        long oldIdent = Binder.clearCallingIdentity();
17353        try {
17354            IBackupManager bm = IBackupManager.Stub.asInterface(
17355                    ServiceManager.getService(Context.BACKUP_SERVICE));
17356            bm.agentConnected(agentPackageName, agent);
17357        } catch (RemoteException e) {
17358            // can't happen; the backup manager service is local
17359        } catch (Exception e) {
17360            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17361            e.printStackTrace();
17362        } finally {
17363            Binder.restoreCallingIdentity(oldIdent);
17364        }
17365    }
17366
17367    // done with this agent
17368    public void unbindBackupAgent(ApplicationInfo appInfo) {
17369        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17370        if (appInfo == null) {
17371            Slog.w(TAG, "unbind backup agent for null app");
17372            return;
17373        }
17374
17375        synchronized(this) {
17376            try {
17377                if (mBackupAppName == null) {
17378                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17379                    return;
17380                }
17381
17382                if (!mBackupAppName.equals(appInfo.packageName)) {
17383                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17384                    return;
17385                }
17386
17387                // Not backing this app up any more; reset its OOM adjustment
17388                final ProcessRecord proc = mBackupTarget.app;
17389                updateOomAdjLocked(proc);
17390
17391                // If the app crashed during backup, 'thread' will be null here
17392                if (proc.thread != null) {
17393                    try {
17394                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17395                                compatibilityInfoForPackageLocked(appInfo));
17396                    } catch (Exception e) {
17397                        Slog.e(TAG, "Exception when unbinding backup agent:");
17398                        e.printStackTrace();
17399                    }
17400                }
17401            } finally {
17402                mBackupTarget = null;
17403                mBackupAppName = null;
17404            }
17405        }
17406    }
17407    // =========================================================
17408    // BROADCASTS
17409    // =========================================================
17410
17411    boolean isPendingBroadcastProcessLocked(int pid) {
17412        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17413                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17414    }
17415
17416    void skipPendingBroadcastLocked(int pid) {
17417            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17418            for (BroadcastQueue queue : mBroadcastQueues) {
17419                queue.skipPendingBroadcastLocked(pid);
17420            }
17421    }
17422
17423    // The app just attached; send any pending broadcasts that it should receive
17424    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17425        boolean didSomething = false;
17426        for (BroadcastQueue queue : mBroadcastQueues) {
17427            didSomething |= queue.sendPendingBroadcastsLocked(app);
17428        }
17429        return didSomething;
17430    }
17431
17432    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17433            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17434        enforceNotIsolatedCaller("registerReceiver");
17435        ArrayList<Intent> stickyIntents = null;
17436        ProcessRecord callerApp = null;
17437        int callingUid;
17438        int callingPid;
17439        synchronized(this) {
17440            if (caller != null) {
17441                callerApp = getRecordForAppLocked(caller);
17442                if (callerApp == null) {
17443                    throw new SecurityException(
17444                            "Unable to find app for caller " + caller
17445                            + " (pid=" + Binder.getCallingPid()
17446                            + ") when registering receiver " + receiver);
17447                }
17448                if (callerApp.info.uid != Process.SYSTEM_UID &&
17449                        !callerApp.pkgList.containsKey(callerPackage) &&
17450                        !"android".equals(callerPackage)) {
17451                    throw new SecurityException("Given caller package " + callerPackage
17452                            + " is not running in process " + callerApp);
17453                }
17454                callingUid = callerApp.info.uid;
17455                callingPid = callerApp.pid;
17456            } else {
17457                callerPackage = null;
17458                callingUid = Binder.getCallingUid();
17459                callingPid = Binder.getCallingPid();
17460            }
17461
17462            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17463                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17464
17465            Iterator<String> actions = filter.actionsIterator();
17466            if (actions == null) {
17467                ArrayList<String> noAction = new ArrayList<String>(1);
17468                noAction.add(null);
17469                actions = noAction.iterator();
17470            }
17471
17472            // Collect stickies of users
17473            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17474            while (actions.hasNext()) {
17475                String action = actions.next();
17476                for (int id : userIds) {
17477                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17478                    if (stickies != null) {
17479                        ArrayList<Intent> intents = stickies.get(action);
17480                        if (intents != null) {
17481                            if (stickyIntents == null) {
17482                                stickyIntents = new ArrayList<Intent>();
17483                            }
17484                            stickyIntents.addAll(intents);
17485                        }
17486                    }
17487                }
17488            }
17489        }
17490
17491        ArrayList<Intent> allSticky = null;
17492        if (stickyIntents != null) {
17493            final ContentResolver resolver = mContext.getContentResolver();
17494            // Look for any matching sticky broadcasts...
17495            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17496                Intent intent = stickyIntents.get(i);
17497                // If intent has scheme "content", it will need to acccess
17498                // provider that needs to lock mProviderMap in ActivityThread
17499                // and also it may need to wait application response, so we
17500                // cannot lock ActivityManagerService here.
17501                if (filter.match(resolver, intent, true, TAG) >= 0) {
17502                    if (allSticky == null) {
17503                        allSticky = new ArrayList<Intent>();
17504                    }
17505                    allSticky.add(intent);
17506                }
17507            }
17508        }
17509
17510        // The first sticky in the list is returned directly back to the client.
17511        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17512        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17513        if (receiver == null) {
17514            return sticky;
17515        }
17516
17517        synchronized (this) {
17518            if (callerApp != null && (callerApp.thread == null
17519                    || callerApp.thread.asBinder() != caller.asBinder())) {
17520                // Original caller already died
17521                return null;
17522            }
17523            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17524            if (rl == null) {
17525                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17526                        userId, receiver);
17527                if (rl.app != null) {
17528                    rl.app.receivers.add(rl);
17529                } else {
17530                    try {
17531                        receiver.asBinder().linkToDeath(rl, 0);
17532                    } catch (RemoteException e) {
17533                        return sticky;
17534                    }
17535                    rl.linkedToDeath = true;
17536                }
17537                mRegisteredReceivers.put(receiver.asBinder(), rl);
17538            } else if (rl.uid != callingUid) {
17539                throw new IllegalArgumentException(
17540                        "Receiver requested to register for uid " + callingUid
17541                        + " was previously registered for uid " + rl.uid);
17542            } else if (rl.pid != callingPid) {
17543                throw new IllegalArgumentException(
17544                        "Receiver requested to register for pid " + callingPid
17545                        + " was previously registered for pid " + rl.pid);
17546            } else if (rl.userId != userId) {
17547                throw new IllegalArgumentException(
17548                        "Receiver requested to register for user " + userId
17549                        + " was previously registered for user " + rl.userId);
17550            }
17551            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17552                    permission, callingUid, userId);
17553            rl.add(bf);
17554            if (!bf.debugCheck()) {
17555                Slog.w(TAG, "==> For Dynamic broadcast");
17556            }
17557            mReceiverResolver.addFilter(bf);
17558
17559            // Enqueue broadcasts for all existing stickies that match
17560            // this filter.
17561            if (allSticky != null) {
17562                ArrayList receivers = new ArrayList();
17563                receivers.add(bf);
17564
17565                final int stickyCount = allSticky.size();
17566                for (int i = 0; i < stickyCount; i++) {
17567                    Intent intent = allSticky.get(i);
17568                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17569                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17570                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17571                            null, 0, null, null, false, true, true, -1);
17572                    queue.enqueueParallelBroadcastLocked(r);
17573                    queue.scheduleBroadcastsLocked();
17574                }
17575            }
17576
17577            return sticky;
17578        }
17579    }
17580
17581    public void unregisterReceiver(IIntentReceiver receiver) {
17582        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17583
17584        final long origId = Binder.clearCallingIdentity();
17585        try {
17586            boolean doTrim = false;
17587
17588            synchronized(this) {
17589                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17590                if (rl != null) {
17591                    final BroadcastRecord r = rl.curBroadcast;
17592                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17593                        final boolean doNext = r.queue.finishReceiverLocked(
17594                                r, r.resultCode, r.resultData, r.resultExtras,
17595                                r.resultAbort, false);
17596                        if (doNext) {
17597                            doTrim = true;
17598                            r.queue.processNextBroadcast(false);
17599                        }
17600                    }
17601
17602                    if (rl.app != null) {
17603                        rl.app.receivers.remove(rl);
17604                    }
17605                    removeReceiverLocked(rl);
17606                    if (rl.linkedToDeath) {
17607                        rl.linkedToDeath = false;
17608                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17609                    }
17610                }
17611            }
17612
17613            // If we actually concluded any broadcasts, we might now be able
17614            // to trim the recipients' apps from our working set
17615            if (doTrim) {
17616                trimApplications();
17617                return;
17618            }
17619
17620        } finally {
17621            Binder.restoreCallingIdentity(origId);
17622        }
17623    }
17624
17625    void removeReceiverLocked(ReceiverList rl) {
17626        mRegisteredReceivers.remove(rl.receiver.asBinder());
17627        for (int i = rl.size() - 1; i >= 0; i--) {
17628            mReceiverResolver.removeFilter(rl.get(i));
17629        }
17630    }
17631
17632    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17633        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17634            ProcessRecord r = mLruProcesses.get(i);
17635            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17636                try {
17637                    r.thread.dispatchPackageBroadcast(cmd, packages);
17638                } catch (RemoteException ex) {
17639                }
17640            }
17641        }
17642    }
17643
17644    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17645            int callingUid, int[] users) {
17646        // TODO: come back and remove this assumption to triage all broadcasts
17647        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17648
17649        List<ResolveInfo> receivers = null;
17650        try {
17651            HashSet<ComponentName> singleUserReceivers = null;
17652            boolean scannedFirstReceivers = false;
17653            for (int user : users) {
17654                // Skip users that have Shell restrictions, with exception of always permitted
17655                // Shell broadcasts
17656                if (callingUid == Process.SHELL_UID
17657                        && mUserController.hasUserRestriction(
17658                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17659                        && !isPermittedShellBroadcast(intent)) {
17660                    continue;
17661                }
17662                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17663                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17664                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17665                    // If this is not the system user, we need to check for
17666                    // any receivers that should be filtered out.
17667                    for (int i=0; i<newReceivers.size(); i++) {
17668                        ResolveInfo ri = newReceivers.get(i);
17669                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17670                            newReceivers.remove(i);
17671                            i--;
17672                        }
17673                    }
17674                }
17675                if (newReceivers != null && newReceivers.size() == 0) {
17676                    newReceivers = null;
17677                }
17678                if (receivers == null) {
17679                    receivers = newReceivers;
17680                } else if (newReceivers != null) {
17681                    // We need to concatenate the additional receivers
17682                    // found with what we have do far.  This would be easy,
17683                    // but we also need to de-dup any receivers that are
17684                    // singleUser.
17685                    if (!scannedFirstReceivers) {
17686                        // Collect any single user receivers we had already retrieved.
17687                        scannedFirstReceivers = true;
17688                        for (int i=0; i<receivers.size(); i++) {
17689                            ResolveInfo ri = receivers.get(i);
17690                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17691                                ComponentName cn = new ComponentName(
17692                                        ri.activityInfo.packageName, ri.activityInfo.name);
17693                                if (singleUserReceivers == null) {
17694                                    singleUserReceivers = new HashSet<ComponentName>();
17695                                }
17696                                singleUserReceivers.add(cn);
17697                            }
17698                        }
17699                    }
17700                    // Add the new results to the existing results, tracking
17701                    // and de-dupping single user receivers.
17702                    for (int i=0; i<newReceivers.size(); i++) {
17703                        ResolveInfo ri = newReceivers.get(i);
17704                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17705                            ComponentName cn = new ComponentName(
17706                                    ri.activityInfo.packageName, ri.activityInfo.name);
17707                            if (singleUserReceivers == null) {
17708                                singleUserReceivers = new HashSet<ComponentName>();
17709                            }
17710                            if (!singleUserReceivers.contains(cn)) {
17711                                singleUserReceivers.add(cn);
17712                                receivers.add(ri);
17713                            }
17714                        } else {
17715                            receivers.add(ri);
17716                        }
17717                    }
17718                }
17719            }
17720        } catch (RemoteException ex) {
17721            // pm is in same process, this will never happen.
17722        }
17723        return receivers;
17724    }
17725
17726    private boolean isPermittedShellBroadcast(Intent intent) {
17727        // remote bugreport should always be allowed to be taken
17728        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17729    }
17730
17731    final int broadcastIntentLocked(ProcessRecord callerApp,
17732            String callerPackage, Intent intent, String resolvedType,
17733            IIntentReceiver resultTo, int resultCode, String resultData,
17734            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17735            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17736        intent = new Intent(intent);
17737
17738        // By default broadcasts do not go to stopped apps.
17739        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17740
17741        // If we have not finished booting, don't allow this to launch new processes.
17742        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17743            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17744        }
17745
17746        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17747                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17748                + " ordered=" + ordered + " userid=" + userId);
17749        if ((resultTo != null) && !ordered) {
17750            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17751        }
17752
17753        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17754                ALLOW_NON_FULL, "broadcast", callerPackage);
17755
17756        // Make sure that the user who is receiving this broadcast is running.
17757        // If not, we will just skip it. Make an exception for shutdown broadcasts
17758        // and upgrade steps.
17759
17760        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17761            if ((callingUid != Process.SYSTEM_UID
17762                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17763                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17764                Slog.w(TAG, "Skipping broadcast of " + intent
17765                        + ": user " + userId + " is stopped");
17766                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17767            }
17768        }
17769
17770        BroadcastOptions brOptions = null;
17771        if (bOptions != null) {
17772            brOptions = new BroadcastOptions(bOptions);
17773            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17774                // See if the caller is allowed to do this.  Note we are checking against
17775                // the actual real caller (not whoever provided the operation as say a
17776                // PendingIntent), because that who is actually supplied the arguments.
17777                if (checkComponentPermission(
17778                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17779                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17780                        != PackageManager.PERMISSION_GRANTED) {
17781                    String msg = "Permission Denial: " + intent.getAction()
17782                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17783                            + ", uid=" + callingUid + ")"
17784                            + " requires "
17785                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17786                    Slog.w(TAG, msg);
17787                    throw new SecurityException(msg);
17788                }
17789            }
17790        }
17791
17792        // Verify that protected broadcasts are only being sent by system code,
17793        // and that system code is only sending protected broadcasts.
17794        final String action = intent.getAction();
17795        final boolean isProtectedBroadcast;
17796        try {
17797            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17798        } catch (RemoteException e) {
17799            Slog.w(TAG, "Remote exception", e);
17800            return ActivityManager.BROADCAST_SUCCESS;
17801        }
17802
17803        final boolean isCallerSystem;
17804        switch (UserHandle.getAppId(callingUid)) {
17805            case Process.ROOT_UID:
17806            case Process.SYSTEM_UID:
17807            case Process.PHONE_UID:
17808            case Process.BLUETOOTH_UID:
17809            case Process.NFC_UID:
17810                isCallerSystem = true;
17811                break;
17812            default:
17813                isCallerSystem = (callerApp != null) && callerApp.persistent;
17814                break;
17815        }
17816
17817        if (isCallerSystem) {
17818            if (isProtectedBroadcast
17819                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17820                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17821                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17822                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17823                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17824                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17825                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17826                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17827                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17828                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17829                // Broadcast is either protected, or it's a public action that
17830                // we've relaxed, so it's fine for system internals to send.
17831            } else {
17832                // The vast majority of broadcasts sent from system internals
17833                // should be protected to avoid security holes, so yell loudly
17834                // to ensure we examine these cases.
17835                if (callerApp != null) {
17836                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17837                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17838                            new Throwable());
17839                } else {
17840                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17841                            + " from system uid " + UserHandle.formatUid(callingUid)
17842                            + " pkg " + callerPackage,
17843                            new Throwable());
17844                }
17845            }
17846
17847        } else {
17848            if (isProtectedBroadcast) {
17849                String msg = "Permission Denial: not allowed to send broadcast "
17850                        + action + " from pid="
17851                        + callingPid + ", uid=" + callingUid;
17852                Slog.w(TAG, msg);
17853                throw new SecurityException(msg);
17854
17855            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17856                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17857                // Special case for compatibility: we don't want apps to send this,
17858                // but historically it has not been protected and apps may be using it
17859                // to poke their own app widget.  So, instead of making it protected,
17860                // just limit it to the caller.
17861                if (callerPackage == null) {
17862                    String msg = "Permission Denial: not allowed to send broadcast "
17863                            + action + " from unknown caller.";
17864                    Slog.w(TAG, msg);
17865                    throw new SecurityException(msg);
17866                } else if (intent.getComponent() != null) {
17867                    // They are good enough to send to an explicit component...  verify
17868                    // it is being sent to the calling app.
17869                    if (!intent.getComponent().getPackageName().equals(
17870                            callerPackage)) {
17871                        String msg = "Permission Denial: not allowed to send broadcast "
17872                                + action + " to "
17873                                + intent.getComponent().getPackageName() + " from "
17874                                + callerPackage;
17875                        Slog.w(TAG, msg);
17876                        throw new SecurityException(msg);
17877                    }
17878                } else {
17879                    // Limit broadcast to their own package.
17880                    intent.setPackage(callerPackage);
17881                }
17882            }
17883        }
17884
17885        if (action != null) {
17886            switch (action) {
17887                case Intent.ACTION_UID_REMOVED:
17888                case Intent.ACTION_PACKAGE_REMOVED:
17889                case Intent.ACTION_PACKAGE_CHANGED:
17890                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17891                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17892                case Intent.ACTION_PACKAGES_SUSPENDED:
17893                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17894                    // Handle special intents: if this broadcast is from the package
17895                    // manager about a package being removed, we need to remove all of
17896                    // its activities from the history stack.
17897                    if (checkComponentPermission(
17898                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17899                            callingPid, callingUid, -1, true)
17900                            != PackageManager.PERMISSION_GRANTED) {
17901                        String msg = "Permission Denial: " + intent.getAction()
17902                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17903                                + ", uid=" + callingUid + ")"
17904                                + " requires "
17905                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17906                        Slog.w(TAG, msg);
17907                        throw new SecurityException(msg);
17908                    }
17909                    switch (action) {
17910                        case Intent.ACTION_UID_REMOVED:
17911                            final Bundle intentExtras = intent.getExtras();
17912                            final int uid = intentExtras != null
17913                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17914                            if (uid >= 0) {
17915                                mBatteryStatsService.removeUid(uid);
17916                                mAppOpsService.uidRemoved(uid);
17917                            }
17918                            break;
17919                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17920                            // If resources are unavailable just force stop all those packages
17921                            // and flush the attribute cache as well.
17922                            String list[] =
17923                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17924                            if (list != null && list.length > 0) {
17925                                for (int i = 0; i < list.length; i++) {
17926                                    forceStopPackageLocked(list[i], -1, false, true, true,
17927                                            false, false, userId, "storage unmount");
17928                                }
17929                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17930                                sendPackageBroadcastLocked(
17931                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17932                                        userId);
17933                            }
17934                            break;
17935                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17936                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17937                            break;
17938                        case Intent.ACTION_PACKAGE_REMOVED:
17939                        case Intent.ACTION_PACKAGE_CHANGED:
17940                            Uri data = intent.getData();
17941                            String ssp;
17942                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17943                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17944                                final boolean replacing =
17945                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17946                                final boolean killProcess =
17947                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17948                                final boolean fullUninstall = removed && !replacing;
17949                                if (removed) {
17950                                    if (killProcess) {
17951                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17952                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17953                                                false, true, true, false, fullUninstall, userId,
17954                                                removed ? "pkg removed" : "pkg changed");
17955                                    }
17956                                    final int cmd = killProcess
17957                                            ? IApplicationThread.PACKAGE_REMOVED
17958                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17959                                    sendPackageBroadcastLocked(cmd,
17960                                            new String[] {ssp}, userId);
17961                                    if (fullUninstall) {
17962                                        mAppOpsService.packageRemoved(
17963                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17964
17965                                        // Remove all permissions granted from/to this package
17966                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17967
17968                                        removeTasksByPackageNameLocked(ssp, userId);
17969
17970                                        // Hide the "unsupported display" dialog if necessary.
17971                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17972                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17973                                            mUnsupportedDisplaySizeDialog.dismiss();
17974                                            mUnsupportedDisplaySizeDialog = null;
17975                                        }
17976                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17977                                        mBatteryStatsService.notePackageUninstalled(ssp);
17978                                    }
17979                                } else {
17980                                    if (killProcess) {
17981                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17982                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17983                                                userId, ProcessList.INVALID_ADJ,
17984                                                false, true, true, false, "change " + ssp);
17985                                    }
17986                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17987                                            intent.getStringArrayExtra(
17988                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17989                                }
17990                            }
17991                            break;
17992                        case Intent.ACTION_PACKAGES_SUSPENDED:
17993                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17994                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17995                                    intent.getAction());
17996                            final String[] packageNames = intent.getStringArrayExtra(
17997                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17998                            final int userHandle = intent.getIntExtra(
17999                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18000
18001                            synchronized(ActivityManagerService.this) {
18002                                mRecentTasks.onPackagesSuspendedChanged(
18003                                        packageNames, suspended, userHandle);
18004                            }
18005                            break;
18006                    }
18007                    break;
18008                case Intent.ACTION_PACKAGE_REPLACED:
18009                {
18010                    final Uri data = intent.getData();
18011                    final String ssp;
18012                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18013                        final ApplicationInfo aInfo =
18014                                getPackageManagerInternalLocked().getApplicationInfo(
18015                                        ssp,
18016                                        userId);
18017                        if (aInfo == null) {
18018                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18019                                    + " ssp=" + ssp + " data=" + data);
18020                            return ActivityManager.BROADCAST_SUCCESS;
18021                        }
18022                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18023                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18024                                new String[] {ssp}, userId);
18025                    }
18026                    break;
18027                }
18028                case Intent.ACTION_PACKAGE_ADDED:
18029                {
18030                    // Special case for adding a package: by default turn on compatibility mode.
18031                    Uri data = intent.getData();
18032                    String ssp;
18033                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18034                        final boolean replacing =
18035                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18036                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18037
18038                        try {
18039                            ApplicationInfo ai = AppGlobals.getPackageManager().
18040                                    getApplicationInfo(ssp, 0, 0);
18041                            mBatteryStatsService.notePackageInstalled(ssp,
18042                                    ai != null ? ai.versionCode : 0);
18043                        } catch (RemoteException e) {
18044                        }
18045                    }
18046                    break;
18047                }
18048                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18049                {
18050                    Uri data = intent.getData();
18051                    String ssp;
18052                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18053                        // Hide the "unsupported display" dialog if necessary.
18054                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18055                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18056                            mUnsupportedDisplaySizeDialog.dismiss();
18057                            mUnsupportedDisplaySizeDialog = null;
18058                        }
18059                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18060                    }
18061                    break;
18062                }
18063                case Intent.ACTION_TIMEZONE_CHANGED:
18064                    // If this is the time zone changed action, queue up a message that will reset
18065                    // the timezone of all currently running processes. This message will get
18066                    // queued up before the broadcast happens.
18067                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18068                    break;
18069                case Intent.ACTION_TIME_CHANGED:
18070                    // If the user set the time, let all running processes know.
18071                    final int is24Hour =
18072                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18073                                    : 0;
18074                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18075                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18076                    synchronized (stats) {
18077                        stats.noteCurrentTimeChangedLocked();
18078                    }
18079                    break;
18080                case Intent.ACTION_CLEAR_DNS_CACHE:
18081                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18082                    break;
18083                case Proxy.PROXY_CHANGE_ACTION:
18084                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18085                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18086                    break;
18087                case android.hardware.Camera.ACTION_NEW_PICTURE:
18088                case android.hardware.Camera.ACTION_NEW_VIDEO:
18089                    // These broadcasts are no longer allowed by the system, since they can
18090                    // cause significant thrashing at a crictical point (using the camera).
18091                    // Apps should use JobScehduler to monitor for media provider changes.
18092                    Slog.w(TAG, action + " no longer allowed; dropping from "
18093                            + UserHandle.formatUid(callingUid));
18094                    if (resultTo != null) {
18095                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18096                        try {
18097                            queue.performReceiveLocked(callerApp, resultTo, intent,
18098                                    Activity.RESULT_CANCELED, null, null,
18099                                    false, false, userId);
18100                        } catch (RemoteException e) {
18101                            Slog.w(TAG, "Failure ["
18102                                    + queue.mQueueName + "] sending broadcast result of "
18103                                    + intent, e);
18104
18105                        }
18106                    }
18107                    // Lie; we don't want to crash the app.
18108                    return ActivityManager.BROADCAST_SUCCESS;
18109            }
18110        }
18111
18112        // Add to the sticky list if requested.
18113        if (sticky) {
18114            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18115                    callingPid, callingUid)
18116                    != PackageManager.PERMISSION_GRANTED) {
18117                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18118                        + callingPid + ", uid=" + callingUid
18119                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18120                Slog.w(TAG, msg);
18121                throw new SecurityException(msg);
18122            }
18123            if (requiredPermissions != null && requiredPermissions.length > 0) {
18124                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18125                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18126                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18127            }
18128            if (intent.getComponent() != null) {
18129                throw new SecurityException(
18130                        "Sticky broadcasts can't target a specific component");
18131            }
18132            // We use userId directly here, since the "all" target is maintained
18133            // as a separate set of sticky broadcasts.
18134            if (userId != UserHandle.USER_ALL) {
18135                // But first, if this is not a broadcast to all users, then
18136                // make sure it doesn't conflict with an existing broadcast to
18137                // all users.
18138                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18139                        UserHandle.USER_ALL);
18140                if (stickies != null) {
18141                    ArrayList<Intent> list = stickies.get(intent.getAction());
18142                    if (list != null) {
18143                        int N = list.size();
18144                        int i;
18145                        for (i=0; i<N; i++) {
18146                            if (intent.filterEquals(list.get(i))) {
18147                                throw new IllegalArgumentException(
18148                                        "Sticky broadcast " + intent + " for user "
18149                                        + userId + " conflicts with existing global broadcast");
18150                            }
18151                        }
18152                    }
18153                }
18154            }
18155            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18156            if (stickies == null) {
18157                stickies = new ArrayMap<>();
18158                mStickyBroadcasts.put(userId, stickies);
18159            }
18160            ArrayList<Intent> list = stickies.get(intent.getAction());
18161            if (list == null) {
18162                list = new ArrayList<>();
18163                stickies.put(intent.getAction(), list);
18164            }
18165            final int stickiesCount = list.size();
18166            int i;
18167            for (i = 0; i < stickiesCount; i++) {
18168                if (intent.filterEquals(list.get(i))) {
18169                    // This sticky already exists, replace it.
18170                    list.set(i, new Intent(intent));
18171                    break;
18172                }
18173            }
18174            if (i >= stickiesCount) {
18175                list.add(new Intent(intent));
18176            }
18177        }
18178
18179        int[] users;
18180        if (userId == UserHandle.USER_ALL) {
18181            // Caller wants broadcast to go to all started users.
18182            users = mUserController.getStartedUserArrayLocked();
18183        } else {
18184            // Caller wants broadcast to go to one specific user.
18185            users = new int[] {userId};
18186        }
18187
18188        // Figure out who all will receive this broadcast.
18189        List receivers = null;
18190        List<BroadcastFilter> registeredReceivers = null;
18191        // Need to resolve the intent to interested receivers...
18192        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18193                 == 0) {
18194            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18195        }
18196        if (intent.getComponent() == null) {
18197            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18198                // Query one target user at a time, excluding shell-restricted users
18199                for (int i = 0; i < users.length; i++) {
18200                    if (mUserController.hasUserRestriction(
18201                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18202                        continue;
18203                    }
18204                    List<BroadcastFilter> registeredReceiversForUser =
18205                            mReceiverResolver.queryIntent(intent,
18206                                    resolvedType, false, users[i]);
18207                    if (registeredReceivers == null) {
18208                        registeredReceivers = registeredReceiversForUser;
18209                    } else if (registeredReceiversForUser != null) {
18210                        registeredReceivers.addAll(registeredReceiversForUser);
18211                    }
18212                }
18213            } else {
18214                registeredReceivers = mReceiverResolver.queryIntent(intent,
18215                        resolvedType, false, userId);
18216            }
18217        }
18218
18219        final boolean replacePending =
18220                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18221
18222        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18223                + " replacePending=" + replacePending);
18224
18225        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18226        if (!ordered && NR > 0) {
18227            // If we are not serializing this broadcast, then send the
18228            // registered receivers separately so they don't wait for the
18229            // components to be launched.
18230            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18231            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18232                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18233                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18234                    resultExtras, ordered, sticky, false, userId);
18235            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18236            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18237            if (!replaced) {
18238                queue.enqueueParallelBroadcastLocked(r);
18239                queue.scheduleBroadcastsLocked();
18240            }
18241            registeredReceivers = null;
18242            NR = 0;
18243        }
18244
18245        // Merge into one list.
18246        int ir = 0;
18247        if (receivers != null) {
18248            // A special case for PACKAGE_ADDED: do not allow the package
18249            // being added to see this broadcast.  This prevents them from
18250            // using this as a back door to get run as soon as they are
18251            // installed.  Maybe in the future we want to have a special install
18252            // broadcast or such for apps, but we'd like to deliberately make
18253            // this decision.
18254            String skipPackages[] = null;
18255            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18256                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18257                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18258                Uri data = intent.getData();
18259                if (data != null) {
18260                    String pkgName = data.getSchemeSpecificPart();
18261                    if (pkgName != null) {
18262                        skipPackages = new String[] { pkgName };
18263                    }
18264                }
18265            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18266                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18267            }
18268            if (skipPackages != null && (skipPackages.length > 0)) {
18269                for (String skipPackage : skipPackages) {
18270                    if (skipPackage != null) {
18271                        int NT = receivers.size();
18272                        for (int it=0; it<NT; it++) {
18273                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18274                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18275                                receivers.remove(it);
18276                                it--;
18277                                NT--;
18278                            }
18279                        }
18280                    }
18281                }
18282            }
18283
18284            int NT = receivers != null ? receivers.size() : 0;
18285            int it = 0;
18286            ResolveInfo curt = null;
18287            BroadcastFilter curr = null;
18288            while (it < NT && ir < NR) {
18289                if (curt == null) {
18290                    curt = (ResolveInfo)receivers.get(it);
18291                }
18292                if (curr == null) {
18293                    curr = registeredReceivers.get(ir);
18294                }
18295                if (curr.getPriority() >= curt.priority) {
18296                    // Insert this broadcast record into the final list.
18297                    receivers.add(it, curr);
18298                    ir++;
18299                    curr = null;
18300                    it++;
18301                    NT++;
18302                } else {
18303                    // Skip to the next ResolveInfo in the final list.
18304                    it++;
18305                    curt = null;
18306                }
18307            }
18308        }
18309        while (ir < NR) {
18310            if (receivers == null) {
18311                receivers = new ArrayList();
18312            }
18313            receivers.add(registeredReceivers.get(ir));
18314            ir++;
18315        }
18316
18317        if ((receivers != null && receivers.size() > 0)
18318                || resultTo != null) {
18319            BroadcastQueue queue = broadcastQueueForIntent(intent);
18320            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18321                    callerPackage, callingPid, callingUid, resolvedType,
18322                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18323                    resultData, resultExtras, ordered, sticky, false, userId);
18324
18325            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18326                    + ": prev had " + queue.mOrderedBroadcasts.size());
18327            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18328                    "Enqueueing broadcast " + r.intent.getAction());
18329
18330            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18331            if (!replaced) {
18332                queue.enqueueOrderedBroadcastLocked(r);
18333                queue.scheduleBroadcastsLocked();
18334            }
18335        } else {
18336            // There was nobody interested in the broadcast, but we still want to record
18337            // that it happened.
18338            if (intent.getComponent() == null && intent.getPackage() == null
18339                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18340                // This was an implicit broadcast... let's record it for posterity.
18341                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18342            }
18343        }
18344
18345        return ActivityManager.BROADCAST_SUCCESS;
18346    }
18347
18348    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18349            int skipCount, long dispatchTime) {
18350        final long now = SystemClock.elapsedRealtime();
18351        if (mCurBroadcastStats == null ||
18352                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18353            mLastBroadcastStats = mCurBroadcastStats;
18354            if (mLastBroadcastStats != null) {
18355                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18356                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18357            }
18358            mCurBroadcastStats = new BroadcastStats();
18359        }
18360        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18361    }
18362
18363    final Intent verifyBroadcastLocked(Intent intent) {
18364        // Refuse possible leaked file descriptors
18365        if (intent != null && intent.hasFileDescriptors() == true) {
18366            throw new IllegalArgumentException("File descriptors passed in Intent");
18367        }
18368
18369        int flags = intent.getFlags();
18370
18371        if (!mProcessesReady) {
18372            // if the caller really truly claims to know what they're doing, go
18373            // ahead and allow the broadcast without launching any receivers
18374            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18375                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18376            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18377                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18378                        + " before boot completion");
18379                throw new IllegalStateException("Cannot broadcast before boot completed");
18380            }
18381        }
18382
18383        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18384            throw new IllegalArgumentException(
18385                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18386        }
18387
18388        return intent;
18389    }
18390
18391    public final int broadcastIntent(IApplicationThread caller,
18392            Intent intent, String resolvedType, IIntentReceiver resultTo,
18393            int resultCode, String resultData, Bundle resultExtras,
18394            String[] requiredPermissions, int appOp, Bundle bOptions,
18395            boolean serialized, boolean sticky, int userId) {
18396        enforceNotIsolatedCaller("broadcastIntent");
18397        synchronized(this) {
18398            intent = verifyBroadcastLocked(intent);
18399
18400            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18401            final int callingPid = Binder.getCallingPid();
18402            final int callingUid = Binder.getCallingUid();
18403            final long origId = Binder.clearCallingIdentity();
18404            int res = broadcastIntentLocked(callerApp,
18405                    callerApp != null ? callerApp.info.packageName : null,
18406                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18407                    requiredPermissions, appOp, bOptions, serialized, sticky,
18408                    callingPid, callingUid, userId);
18409            Binder.restoreCallingIdentity(origId);
18410            return res;
18411        }
18412    }
18413
18414
18415    int broadcastIntentInPackage(String packageName, int uid,
18416            Intent intent, String resolvedType, IIntentReceiver resultTo,
18417            int resultCode, String resultData, Bundle resultExtras,
18418            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18419            int userId) {
18420        synchronized(this) {
18421            intent = verifyBroadcastLocked(intent);
18422
18423            final long origId = Binder.clearCallingIdentity();
18424            String[] requiredPermissions = requiredPermission == null ? null
18425                    : new String[] {requiredPermission};
18426            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18427                    resultTo, resultCode, resultData, resultExtras,
18428                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18429                    sticky, -1, uid, userId);
18430            Binder.restoreCallingIdentity(origId);
18431            return res;
18432        }
18433    }
18434
18435    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18436        // Refuse possible leaked file descriptors
18437        if (intent != null && intent.hasFileDescriptors() == true) {
18438            throw new IllegalArgumentException("File descriptors passed in Intent");
18439        }
18440
18441        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18442                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18443
18444        synchronized(this) {
18445            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18446                    != PackageManager.PERMISSION_GRANTED) {
18447                String msg = "Permission Denial: unbroadcastIntent() from pid="
18448                        + Binder.getCallingPid()
18449                        + ", uid=" + Binder.getCallingUid()
18450                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18451                Slog.w(TAG, msg);
18452                throw new SecurityException(msg);
18453            }
18454            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18455            if (stickies != null) {
18456                ArrayList<Intent> list = stickies.get(intent.getAction());
18457                if (list != null) {
18458                    int N = list.size();
18459                    int i;
18460                    for (i=0; i<N; i++) {
18461                        if (intent.filterEquals(list.get(i))) {
18462                            list.remove(i);
18463                            break;
18464                        }
18465                    }
18466                    if (list.size() <= 0) {
18467                        stickies.remove(intent.getAction());
18468                    }
18469                }
18470                if (stickies.size() <= 0) {
18471                    mStickyBroadcasts.remove(userId);
18472                }
18473            }
18474        }
18475    }
18476
18477    void backgroundServicesFinishedLocked(int userId) {
18478        for (BroadcastQueue queue : mBroadcastQueues) {
18479            queue.backgroundServicesFinishedLocked(userId);
18480        }
18481    }
18482
18483    public void finishReceiver(IBinder who, int resultCode, String resultData,
18484            Bundle resultExtras, boolean resultAbort, int flags) {
18485        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18486
18487        // Refuse possible leaked file descriptors
18488        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18489            throw new IllegalArgumentException("File descriptors passed in Bundle");
18490        }
18491
18492        final long origId = Binder.clearCallingIdentity();
18493        try {
18494            boolean doNext = false;
18495            BroadcastRecord r;
18496
18497            synchronized(this) {
18498                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18499                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18500                r = queue.getMatchingOrderedReceiver(who);
18501                if (r != null) {
18502                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18503                        resultData, resultExtras, resultAbort, true);
18504                }
18505            }
18506
18507            if (doNext) {
18508                r.queue.processNextBroadcast(false);
18509            }
18510            trimApplications();
18511        } finally {
18512            Binder.restoreCallingIdentity(origId);
18513        }
18514    }
18515
18516    // =========================================================
18517    // INSTRUMENTATION
18518    // =========================================================
18519
18520    public boolean startInstrumentation(ComponentName className,
18521            String profileFile, int flags, Bundle arguments,
18522            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18523            int userId, String abiOverride) {
18524        enforceNotIsolatedCaller("startInstrumentation");
18525        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18526                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18527        // Refuse possible leaked file descriptors
18528        if (arguments != null && arguments.hasFileDescriptors()) {
18529            throw new IllegalArgumentException("File descriptors passed in Bundle");
18530        }
18531
18532        synchronized(this) {
18533            InstrumentationInfo ii = null;
18534            ApplicationInfo ai = null;
18535            try {
18536                ii = mContext.getPackageManager().getInstrumentationInfo(
18537                    className, STOCK_PM_FLAGS);
18538                ai = AppGlobals.getPackageManager().getApplicationInfo(
18539                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18540            } catch (PackageManager.NameNotFoundException e) {
18541            } catch (RemoteException e) {
18542            }
18543            if (ii == null) {
18544                reportStartInstrumentationFailureLocked(watcher, className,
18545                        "Unable to find instrumentation info for: " + className);
18546                return false;
18547            }
18548            if (ai == null) {
18549                reportStartInstrumentationFailureLocked(watcher, className,
18550                        "Unable to find instrumentation target package: " + ii.targetPackage);
18551                return false;
18552            }
18553            if (!ai.hasCode()) {
18554                reportStartInstrumentationFailureLocked(watcher, className,
18555                        "Instrumentation target has no code: " + ii.targetPackage);
18556                return false;
18557            }
18558
18559            int match = mContext.getPackageManager().checkSignatures(
18560                    ii.targetPackage, ii.packageName);
18561            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18562                String msg = "Permission Denial: starting instrumentation "
18563                        + className + " from pid="
18564                        + Binder.getCallingPid()
18565                        + ", uid=" + Binder.getCallingPid()
18566                        + " not allowed because package " + ii.packageName
18567                        + " does not have a signature matching the target "
18568                        + ii.targetPackage;
18569                reportStartInstrumentationFailureLocked(watcher, className, msg);
18570                throw new SecurityException(msg);
18571            }
18572
18573            final long origId = Binder.clearCallingIdentity();
18574            // Instrumentation can kill and relaunch even persistent processes
18575            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18576                    "start instr");
18577            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18578            app.instrumentationClass = className;
18579            app.instrumentationInfo = ai;
18580            app.instrumentationProfileFile = profileFile;
18581            app.instrumentationArguments = arguments;
18582            app.instrumentationWatcher = watcher;
18583            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18584            app.instrumentationResultClass = className;
18585            Binder.restoreCallingIdentity(origId);
18586        }
18587
18588        return true;
18589    }
18590
18591    /**
18592     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18593     * error to the logs, but if somebody is watching, send the report there too.  This enables
18594     * the "am" command to report errors with more information.
18595     *
18596     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18597     * @param cn The component name of the instrumentation.
18598     * @param report The error report.
18599     */
18600    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18601            ComponentName cn, String report) {
18602        Slog.w(TAG, report);
18603        if (watcher != null) {
18604            Bundle results = new Bundle();
18605            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18606            results.putString("Error", report);
18607            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18608        }
18609    }
18610
18611    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18612        if (app.instrumentationWatcher != null) {
18613            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18614                    app.instrumentationClass, resultCode, results);
18615        }
18616
18617        // Can't call out of the system process with a lock held, so post a message.
18618        if (app.instrumentationUiAutomationConnection != null) {
18619            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18620                    app.instrumentationUiAutomationConnection).sendToTarget();
18621        }
18622
18623        app.instrumentationWatcher = null;
18624        app.instrumentationUiAutomationConnection = null;
18625        app.instrumentationClass = null;
18626        app.instrumentationInfo = null;
18627        app.instrumentationProfileFile = null;
18628        app.instrumentationArguments = null;
18629
18630        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18631                "finished inst");
18632    }
18633
18634    public void finishInstrumentation(IApplicationThread target,
18635            int resultCode, Bundle results) {
18636        int userId = UserHandle.getCallingUserId();
18637        // Refuse possible leaked file descriptors
18638        if (results != null && results.hasFileDescriptors()) {
18639            throw new IllegalArgumentException("File descriptors passed in Intent");
18640        }
18641
18642        synchronized(this) {
18643            ProcessRecord app = getRecordForAppLocked(target);
18644            if (app == null) {
18645                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18646                return;
18647            }
18648            final long origId = Binder.clearCallingIdentity();
18649            finishInstrumentationLocked(app, resultCode, results);
18650            Binder.restoreCallingIdentity(origId);
18651        }
18652    }
18653
18654    // =========================================================
18655    // CONFIGURATION
18656    // =========================================================
18657
18658    public ConfigurationInfo getDeviceConfigurationInfo() {
18659        ConfigurationInfo config = new ConfigurationInfo();
18660        synchronized (this) {
18661            config.reqTouchScreen = mConfiguration.touchscreen;
18662            config.reqKeyboardType = mConfiguration.keyboard;
18663            config.reqNavigation = mConfiguration.navigation;
18664            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18665                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18666                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18667            }
18668            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18669                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18670                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18671            }
18672            config.reqGlEsVersion = GL_ES_VERSION;
18673        }
18674        return config;
18675    }
18676
18677    ActivityStack getFocusedStack() {
18678        return mStackSupervisor.getFocusedStack();
18679    }
18680
18681    @Override
18682    public int getFocusedStackId() throws RemoteException {
18683        ActivityStack focusedStack = getFocusedStack();
18684        if (focusedStack != null) {
18685            return focusedStack.getStackId();
18686        }
18687        return -1;
18688    }
18689
18690    public Configuration getConfiguration() {
18691        Configuration ci;
18692        synchronized(this) {
18693            ci = new Configuration(mConfiguration);
18694            ci.userSetLocale = false;
18695        }
18696        return ci;
18697    }
18698
18699    @Override
18700    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18701        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18702        synchronized (this) {
18703            mSuppressResizeConfigChanges = suppress;
18704        }
18705    }
18706
18707    @Override
18708    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18709        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18710        if (fromStackId == HOME_STACK_ID) {
18711            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18712        }
18713        synchronized (this) {
18714            final long origId = Binder.clearCallingIdentity();
18715            try {
18716                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18717            } finally {
18718                Binder.restoreCallingIdentity(origId);
18719            }
18720        }
18721    }
18722
18723    @Override
18724    public void updatePersistentConfiguration(Configuration values) {
18725        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18726                "updateConfiguration()");
18727        enforceWriteSettingsPermission("updateConfiguration()");
18728        if (values == null) {
18729            throw new NullPointerException("Configuration must not be null");
18730        }
18731
18732        int userId = UserHandle.getCallingUserId();
18733
18734        synchronized(this) {
18735            updatePersistentConfigurationLocked(values, userId);
18736        }
18737    }
18738
18739    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18740        final long origId = Binder.clearCallingIdentity();
18741        try {
18742            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18743        } finally {
18744            Binder.restoreCallingIdentity(origId);
18745        }
18746    }
18747
18748    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18749        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18750                FONT_SCALE, 1.0f, userId);
18751        if (mConfiguration.fontScale != scaleFactor) {
18752            final Configuration configuration = mWindowManager.computeNewConfiguration();
18753            configuration.fontScale = scaleFactor;
18754            synchronized (this) {
18755                updatePersistentConfigurationLocked(configuration, userId);
18756            }
18757        }
18758    }
18759
18760    private void enforceWriteSettingsPermission(String func) {
18761        int uid = Binder.getCallingUid();
18762        if (uid == Process.ROOT_UID) {
18763            return;
18764        }
18765
18766        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18767                Settings.getPackageNameForUid(mContext, uid), false)) {
18768            return;
18769        }
18770
18771        String msg = "Permission Denial: " + func + " from pid="
18772                + Binder.getCallingPid()
18773                + ", uid=" + uid
18774                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18775        Slog.w(TAG, msg);
18776        throw new SecurityException(msg);
18777    }
18778
18779    public void updateConfiguration(Configuration values) {
18780        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18781                "updateConfiguration()");
18782
18783        synchronized(this) {
18784            if (values == null && mWindowManager != null) {
18785                // sentinel: fetch the current configuration from the window manager
18786                values = mWindowManager.computeNewConfiguration();
18787            }
18788
18789            if (mWindowManager != null) {
18790                mProcessList.applyDisplaySize(mWindowManager);
18791            }
18792
18793            final long origId = Binder.clearCallingIdentity();
18794            if (values != null) {
18795                Settings.System.clearConfiguration(values);
18796            }
18797            updateConfigurationLocked(values, null, false);
18798            Binder.restoreCallingIdentity(origId);
18799        }
18800    }
18801
18802    void updateUserConfigurationLocked() {
18803        Configuration configuration = new Configuration(mConfiguration);
18804        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18805                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18806        updateConfigurationLocked(configuration, null, false);
18807    }
18808
18809    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18810            boolean initLocale) {
18811        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18812    }
18813
18814    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18815            boolean initLocale, boolean deferResume) {
18816        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18817        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18818                UserHandle.USER_NULL, deferResume);
18819    }
18820
18821    // To cache the list of supported system locales
18822    private String[] mSupportedSystemLocales = null;
18823
18824    /**
18825     * Do either or both things: (1) change the current configuration, and (2)
18826     * make sure the given activity is running with the (now) current
18827     * configuration.  Returns true if the activity has been left running, or
18828     * false if <var>starting</var> is being destroyed to match the new
18829     * configuration.
18830     *
18831     * @param userId is only used when persistent parameter is set to true to persist configuration
18832     *               for that particular user
18833     */
18834    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18835            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18836        int changes = 0;
18837
18838        if (mWindowManager != null) {
18839            mWindowManager.deferSurfaceLayout();
18840        }
18841        if (values != null) {
18842            Configuration newConfig = new Configuration(mConfiguration);
18843            changes = newConfig.updateFrom(values);
18844            if (changes != 0) {
18845                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18846                        "Updating configuration to: " + values);
18847
18848                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18849
18850                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18851                    final LocaleList locales = values.getLocales();
18852                    int bestLocaleIndex = 0;
18853                    if (locales.size() > 1) {
18854                        if (mSupportedSystemLocales == null) {
18855                            mSupportedSystemLocales =
18856                                    Resources.getSystem().getAssets().getLocales();
18857                        }
18858                        bestLocaleIndex = Math.max(0,
18859                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18860                    }
18861                    SystemProperties.set("persist.sys.locale",
18862                            locales.get(bestLocaleIndex).toLanguageTag());
18863                    LocaleList.setDefault(locales, bestLocaleIndex);
18864                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18865                            locales.get(bestLocaleIndex)));
18866                }
18867
18868                mConfigurationSeq++;
18869                if (mConfigurationSeq <= 0) {
18870                    mConfigurationSeq = 1;
18871                }
18872                newConfig.seq = mConfigurationSeq;
18873                mConfiguration = newConfig;
18874                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18875                mUsageStatsService.reportConfigurationChange(newConfig,
18876                        mUserController.getCurrentUserIdLocked());
18877                //mUsageStatsService.noteStartConfig(newConfig);
18878
18879                final Configuration configCopy = new Configuration(mConfiguration);
18880
18881                // TODO: If our config changes, should we auto dismiss any currently
18882                // showing dialogs?
18883                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18884
18885                AttributeCache ac = AttributeCache.instance();
18886                if (ac != null) {
18887                    ac.updateConfiguration(configCopy);
18888                }
18889
18890                // Make sure all resources in our process are updated
18891                // right now, so that anyone who is going to retrieve
18892                // resource values after we return will be sure to get
18893                // the new ones.  This is especially important during
18894                // boot, where the first config change needs to guarantee
18895                // all resources have that config before following boot
18896                // code is executed.
18897                mSystemThread.applyConfigurationToResources(configCopy);
18898
18899                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18900                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18901                    msg.obj = new Configuration(configCopy);
18902                    msg.arg1 = userId;
18903                    mHandler.sendMessage(msg);
18904                }
18905
18906                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18907                if (isDensityChange) {
18908                    // Reset the unsupported display size dialog.
18909                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18910
18911                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18912                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18913                }
18914
18915                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18916                    ProcessRecord app = mLruProcesses.get(i);
18917                    try {
18918                        if (app.thread != null) {
18919                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18920                                    + app.processName + " new config " + mConfiguration);
18921                            app.thread.scheduleConfigurationChanged(configCopy);
18922                        }
18923                    } catch (Exception e) {
18924                    }
18925                }
18926                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18927                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18928                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18929                        | Intent.FLAG_RECEIVER_FOREGROUND);
18930                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18931                        null, AppOpsManager.OP_NONE, null, false, false,
18932                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18933                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18934                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18935                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18936                    if (!mProcessesReady) {
18937                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18938                    }
18939                    broadcastIntentLocked(null, null, intent,
18940                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18941                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18942                }
18943            }
18944            // Update the configuration with WM first and check if any of the stacks need to be
18945            // resized due to the configuration change. If so, resize the stacks now and do any
18946            // relaunches if necessary. This way we don't need to relaunch again below in
18947            // ensureActivityConfigurationLocked().
18948            if (mWindowManager != null) {
18949                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18950                if (resizedStacks != null) {
18951                    for (int stackId : resizedStacks) {
18952                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18953                        mStackSupervisor.resizeStackLocked(
18954                                stackId, newBounds, null, null, false, false, deferResume);
18955                    }
18956                }
18957            }
18958        }
18959
18960        boolean kept = true;
18961        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18962        // mainStack is null during startup.
18963        if (mainStack != null) {
18964            if (changes != 0 && starting == null) {
18965                // If the configuration changed, and the caller is not already
18966                // in the process of starting an activity, then find the top
18967                // activity to check if its configuration needs to change.
18968                starting = mainStack.topRunningActivityLocked();
18969            }
18970
18971            if (starting != null) {
18972                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18973                // And we need to make sure at this point that all other activities
18974                // are made visible with the correct configuration.
18975                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18976                        !PRESERVE_WINDOWS);
18977            }
18978        }
18979        if (mWindowManager != null) {
18980            mWindowManager.continueSurfaceLayout();
18981        }
18982        return kept;
18983    }
18984
18985    /**
18986     * Decide based on the configuration whether we should shouw the ANR,
18987     * crash, etc dialogs.  The idea is that if there is no affordence to
18988     * press the on-screen buttons, or the user experience would be more
18989     * greatly impacted than the crash itself, we shouldn't show the dialog.
18990     *
18991     * A thought: SystemUI might also want to get told about this, the Power
18992     * dialog / global actions also might want different behaviors.
18993     */
18994    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18995        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18996                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18997                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18998        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18999        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19000                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19001        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19002    }
19003
19004    @Override
19005    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19006        synchronized (this) {
19007            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19008            if (srec != null) {
19009                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19010            }
19011        }
19012        return false;
19013    }
19014
19015    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19016            Intent resultData) {
19017
19018        synchronized (this) {
19019            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19020            if (r != null) {
19021                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19022            }
19023            return false;
19024        }
19025    }
19026
19027    public int getLaunchedFromUid(IBinder activityToken) {
19028        ActivityRecord srec;
19029        synchronized (this) {
19030            srec = ActivityRecord.forTokenLocked(activityToken);
19031        }
19032        if (srec == null) {
19033            return -1;
19034        }
19035        return srec.launchedFromUid;
19036    }
19037
19038    public String getLaunchedFromPackage(IBinder activityToken) {
19039        ActivityRecord srec;
19040        synchronized (this) {
19041            srec = ActivityRecord.forTokenLocked(activityToken);
19042        }
19043        if (srec == null) {
19044            return null;
19045        }
19046        return srec.launchedFromPackage;
19047    }
19048
19049    // =========================================================
19050    // LIFETIME MANAGEMENT
19051    // =========================================================
19052
19053    // Returns which broadcast queue the app is the current [or imminent] receiver
19054    // on, or 'null' if the app is not an active broadcast recipient.
19055    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19056        BroadcastRecord r = app.curReceiver;
19057        if (r != null) {
19058            return r.queue;
19059        }
19060
19061        // It's not the current receiver, but it might be starting up to become one
19062        synchronized (this) {
19063            for (BroadcastQueue queue : mBroadcastQueues) {
19064                r = queue.mPendingBroadcast;
19065                if (r != null && r.curApp == app) {
19066                    // found it; report which queue it's in
19067                    return queue;
19068                }
19069            }
19070        }
19071
19072        return null;
19073    }
19074
19075    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19076            int targetUid, ComponentName targetComponent, String targetProcess) {
19077        if (!mTrackingAssociations) {
19078            return null;
19079        }
19080        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19081                = mAssociations.get(targetUid);
19082        if (components == null) {
19083            components = new ArrayMap<>();
19084            mAssociations.put(targetUid, components);
19085        }
19086        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19087        if (sourceUids == null) {
19088            sourceUids = new SparseArray<>();
19089            components.put(targetComponent, sourceUids);
19090        }
19091        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19092        if (sourceProcesses == null) {
19093            sourceProcesses = new ArrayMap<>();
19094            sourceUids.put(sourceUid, sourceProcesses);
19095        }
19096        Association ass = sourceProcesses.get(sourceProcess);
19097        if (ass == null) {
19098            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19099                    targetProcess);
19100            sourceProcesses.put(sourceProcess, ass);
19101        }
19102        ass.mCount++;
19103        ass.mNesting++;
19104        if (ass.mNesting == 1) {
19105            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19106            ass.mLastState = sourceState;
19107        }
19108        return ass;
19109    }
19110
19111    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19112            ComponentName targetComponent) {
19113        if (!mTrackingAssociations) {
19114            return;
19115        }
19116        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19117                = mAssociations.get(targetUid);
19118        if (components == null) {
19119            return;
19120        }
19121        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19122        if (sourceUids == null) {
19123            return;
19124        }
19125        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19126        if (sourceProcesses == null) {
19127            return;
19128        }
19129        Association ass = sourceProcesses.get(sourceProcess);
19130        if (ass == null || ass.mNesting <= 0) {
19131            return;
19132        }
19133        ass.mNesting--;
19134        if (ass.mNesting == 0) {
19135            long uptime = SystemClock.uptimeMillis();
19136            ass.mTime += uptime - ass.mStartTime;
19137            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19138                    += uptime - ass.mLastStateUptime;
19139            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19140        }
19141    }
19142
19143    private void noteUidProcessState(final int uid, final int state) {
19144        mBatteryStatsService.noteUidProcessState(uid, state);
19145        if (mTrackingAssociations) {
19146            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19147                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19148                        = mAssociations.valueAt(i1);
19149                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19150                    SparseArray<ArrayMap<String, Association>> sourceUids
19151                            = targetComponents.valueAt(i2);
19152                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19153                    if (sourceProcesses != null) {
19154                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19155                            Association ass = sourceProcesses.valueAt(i4);
19156                            if (ass.mNesting >= 1) {
19157                                // currently associated
19158                                long uptime = SystemClock.uptimeMillis();
19159                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19160                                        += uptime - ass.mLastStateUptime;
19161                                ass.mLastState = state;
19162                                ass.mLastStateUptime = uptime;
19163                            }
19164                        }
19165                    }
19166                }
19167            }
19168        }
19169    }
19170
19171    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19172            boolean doingAll, long now) {
19173        if (mAdjSeq == app.adjSeq) {
19174            // This adjustment has already been computed.
19175            return app.curRawAdj;
19176        }
19177
19178        if (app.thread == null) {
19179            app.adjSeq = mAdjSeq;
19180            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19181            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19182            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19183        }
19184
19185        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19186        app.adjSource = null;
19187        app.adjTarget = null;
19188        app.empty = false;
19189        app.cached = false;
19190
19191        final int activitiesSize = app.activities.size();
19192
19193        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19194            // The max adjustment doesn't allow this app to be anything
19195            // below foreground, so it is not worth doing work for it.
19196            app.adjType = "fixed";
19197            app.adjSeq = mAdjSeq;
19198            app.curRawAdj = app.maxAdj;
19199            app.foregroundActivities = false;
19200            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19201            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19202            // System processes can do UI, and when they do we want to have
19203            // them trim their memory after the user leaves the UI.  To
19204            // facilitate this, here we need to determine whether or not it
19205            // is currently showing UI.
19206            app.systemNoUi = true;
19207            if (app == TOP_APP) {
19208                app.systemNoUi = false;
19209                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19210                app.adjType = "pers-top-activity";
19211            } else if (app.hasTopUi) {
19212                app.systemNoUi = false;
19213                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19214                app.adjType = "pers-top-ui";
19215            } else if (activitiesSize > 0) {
19216                for (int j = 0; j < activitiesSize; j++) {
19217                    final ActivityRecord r = app.activities.get(j);
19218                    if (r.visible) {
19219                        app.systemNoUi = false;
19220                    }
19221                }
19222            }
19223            if (!app.systemNoUi) {
19224                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19225            }
19226            return (app.curAdj=app.maxAdj);
19227        }
19228
19229        app.systemNoUi = false;
19230
19231        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19232
19233        // Determine the importance of the process, starting with most
19234        // important to least, and assign an appropriate OOM adjustment.
19235        int adj;
19236        int schedGroup;
19237        int procState;
19238        boolean foregroundActivities = false;
19239        BroadcastQueue queue;
19240        if (app == TOP_APP) {
19241            // The last app on the list is the foreground app.
19242            adj = ProcessList.FOREGROUND_APP_ADJ;
19243            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19244            app.adjType = "top-activity";
19245            foregroundActivities = true;
19246            procState = PROCESS_STATE_CUR_TOP;
19247        } else if (app.instrumentationClass != null) {
19248            // Don't want to kill running instrumentation.
19249            adj = ProcessList.FOREGROUND_APP_ADJ;
19250            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19251            app.adjType = "instrumentation";
19252            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19253        } else if ((queue = isReceivingBroadcast(app)) != null) {
19254            // An app that is currently receiving a broadcast also
19255            // counts as being in the foreground for OOM killer purposes.
19256            // It's placed in a sched group based on the nature of the
19257            // broadcast as reflected by which queue it's active in.
19258            adj = ProcessList.FOREGROUND_APP_ADJ;
19259            schedGroup = (queue == mFgBroadcastQueue)
19260                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19261            app.adjType = "broadcast";
19262            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19263        } else if (app.executingServices.size() > 0) {
19264            // An app that is currently executing a service callback also
19265            // counts as being in the foreground.
19266            adj = ProcessList.FOREGROUND_APP_ADJ;
19267            schedGroup = app.execServicesFg ?
19268                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19269            app.adjType = "exec-service";
19270            procState = ActivityManager.PROCESS_STATE_SERVICE;
19271            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19272        } else {
19273            // As far as we know the process is empty.  We may change our mind later.
19274            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19275            // At this point we don't actually know the adjustment.  Use the cached adj
19276            // value that the caller wants us to.
19277            adj = cachedAdj;
19278            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19279            app.cached = true;
19280            app.empty = true;
19281            app.adjType = "cch-empty";
19282        }
19283
19284        // Examine all activities if not already foreground.
19285        if (!foregroundActivities && activitiesSize > 0) {
19286            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19287            for (int j = 0; j < activitiesSize; j++) {
19288                final ActivityRecord r = app.activities.get(j);
19289                if (r.app != app) {
19290                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19291                            + " instead of expected " + app);
19292                    if (r.app == null || (r.app.uid == app.uid)) {
19293                        // Only fix things up when they look sane
19294                        r.app = app;
19295                    } else {
19296                        continue;
19297                    }
19298                }
19299                if (r.visible) {
19300                    // App has a visible activity; only upgrade adjustment.
19301                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19302                        adj = ProcessList.VISIBLE_APP_ADJ;
19303                        app.adjType = "visible";
19304                    }
19305                    if (procState > PROCESS_STATE_CUR_TOP) {
19306                        procState = PROCESS_STATE_CUR_TOP;
19307                    }
19308                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19309                    app.cached = false;
19310                    app.empty = false;
19311                    foregroundActivities = true;
19312                    if (r.task != null && minLayer > 0) {
19313                        final int layer = r.task.mLayerRank;
19314                        if (layer >= 0 && minLayer > layer) {
19315                            minLayer = layer;
19316                        }
19317                    }
19318                    break;
19319                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19320                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19321                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19322                        app.adjType = "pausing";
19323                    }
19324                    if (procState > PROCESS_STATE_CUR_TOP) {
19325                        procState = PROCESS_STATE_CUR_TOP;
19326                    }
19327                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19328                    app.cached = false;
19329                    app.empty = false;
19330                    foregroundActivities = true;
19331                } else if (r.state == ActivityState.STOPPING) {
19332                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19333                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19334                        app.adjType = "stopping";
19335                    }
19336                    // For the process state, we will at this point consider the
19337                    // process to be cached.  It will be cached either as an activity
19338                    // or empty depending on whether the activity is finishing.  We do
19339                    // this so that we can treat the process as cached for purposes of
19340                    // memory trimming (determing current memory level, trim command to
19341                    // send to process) since there can be an arbitrary number of stopping
19342                    // processes and they should soon all go into the cached state.
19343                    if (!r.finishing) {
19344                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19345                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19346                        }
19347                    }
19348                    app.cached = false;
19349                    app.empty = false;
19350                    foregroundActivities = true;
19351                } else {
19352                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19353                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19354                        app.adjType = "cch-act";
19355                    }
19356                }
19357            }
19358            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19359                adj += minLayer;
19360            }
19361        }
19362
19363        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19364                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19365            if (app.foregroundServices) {
19366                // The user is aware of this app, so make it visible.
19367                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19368                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19369                app.cached = false;
19370                app.adjType = "fg-service";
19371                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19372            } else if (app.forcingToForeground != null) {
19373                // The user is aware of this app, so make it visible.
19374                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19375                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19376                app.cached = false;
19377                app.adjType = "force-fg";
19378                app.adjSource = app.forcingToForeground;
19379                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19380            }
19381        }
19382
19383        if (app == mHeavyWeightProcess) {
19384            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19385                // We don't want to kill the current heavy-weight process.
19386                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19387                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19388                app.cached = false;
19389                app.adjType = "heavy";
19390            }
19391            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19392                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19393            }
19394        }
19395
19396        if (app == mHomeProcess) {
19397            if (adj > ProcessList.HOME_APP_ADJ) {
19398                // This process is hosting what we currently consider to be the
19399                // home app, so we don't want to let it go into the background.
19400                adj = ProcessList.HOME_APP_ADJ;
19401                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19402                app.cached = false;
19403                app.adjType = "home";
19404            }
19405            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19406                procState = ActivityManager.PROCESS_STATE_HOME;
19407            }
19408        }
19409
19410        if (app == mPreviousProcess && app.activities.size() > 0) {
19411            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19412                // This was the previous process that showed UI to the user.
19413                // We want to try to keep it around more aggressively, to give
19414                // a good experience around switching between two apps.
19415                adj = ProcessList.PREVIOUS_APP_ADJ;
19416                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19417                app.cached = false;
19418                app.adjType = "previous";
19419            }
19420            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19421                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19422            }
19423        }
19424
19425        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19426                + " reason=" + app.adjType);
19427
19428        // By default, we use the computed adjustment.  It may be changed if
19429        // there are applications dependent on our services or providers, but
19430        // this gives us a baseline and makes sure we don't get into an
19431        // infinite recursion.
19432        app.adjSeq = mAdjSeq;
19433        app.curRawAdj = adj;
19434        app.hasStartedServices = false;
19435
19436        if (mBackupTarget != null && app == mBackupTarget.app) {
19437            // If possible we want to avoid killing apps while they're being backed up
19438            if (adj > ProcessList.BACKUP_APP_ADJ) {
19439                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19440                adj = ProcessList.BACKUP_APP_ADJ;
19441                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19442                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19443                }
19444                app.adjType = "backup";
19445                app.cached = false;
19446            }
19447            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19448                procState = ActivityManager.PROCESS_STATE_BACKUP;
19449            }
19450        }
19451
19452        boolean mayBeTop = false;
19453
19454        for (int is = app.services.size()-1;
19455                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19456                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19457                        || procState > ActivityManager.PROCESS_STATE_TOP);
19458                is--) {
19459            ServiceRecord s = app.services.valueAt(is);
19460            if (s.startRequested) {
19461                app.hasStartedServices = true;
19462                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19463                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19464                }
19465                if (app.hasShownUi && app != mHomeProcess) {
19466                    // If this process has shown some UI, let it immediately
19467                    // go to the LRU list because it may be pretty heavy with
19468                    // UI stuff.  We'll tag it with a label just to help
19469                    // debug and understand what is going on.
19470                    if (adj > ProcessList.SERVICE_ADJ) {
19471                        app.adjType = "cch-started-ui-services";
19472                    }
19473                } else {
19474                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19475                        // This service has seen some activity within
19476                        // recent memory, so we will keep its process ahead
19477                        // of the background processes.
19478                        if (adj > ProcessList.SERVICE_ADJ) {
19479                            adj = ProcessList.SERVICE_ADJ;
19480                            app.adjType = "started-services";
19481                            app.cached = false;
19482                        }
19483                    }
19484                    // If we have let the service slide into the background
19485                    // state, still have some text describing what it is doing
19486                    // even though the service no longer has an impact.
19487                    if (adj > ProcessList.SERVICE_ADJ) {
19488                        app.adjType = "cch-started-services";
19489                    }
19490                }
19491            }
19492
19493            for (int conni = s.connections.size()-1;
19494                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19495                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19496                            || procState > ActivityManager.PROCESS_STATE_TOP);
19497                    conni--) {
19498                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19499                for (int i = 0;
19500                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19501                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19502                                || procState > ActivityManager.PROCESS_STATE_TOP);
19503                        i++) {
19504                    // XXX should compute this based on the max of
19505                    // all connected clients.
19506                    ConnectionRecord cr = clist.get(i);
19507                    if (cr.binding.client == app) {
19508                        // Binding to ourself is not interesting.
19509                        continue;
19510                    }
19511
19512                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19513                        ProcessRecord client = cr.binding.client;
19514                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19515                                TOP_APP, doingAll, now);
19516                        int clientProcState = client.curProcState;
19517                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19518                            // If the other app is cached for any reason, for purposes here
19519                            // we are going to consider it empty.  The specific cached state
19520                            // doesn't propagate except under certain conditions.
19521                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19522                        }
19523                        String adjType = null;
19524                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19525                            // Not doing bind OOM management, so treat
19526                            // this guy more like a started service.
19527                            if (app.hasShownUi && app != mHomeProcess) {
19528                                // If this process has shown some UI, let it immediately
19529                                // go to the LRU list because it may be pretty heavy with
19530                                // UI stuff.  We'll tag it with a label just to help
19531                                // debug and understand what is going on.
19532                                if (adj > clientAdj) {
19533                                    adjType = "cch-bound-ui-services";
19534                                }
19535                                app.cached = false;
19536                                clientAdj = adj;
19537                                clientProcState = procState;
19538                            } else {
19539                                if (now >= (s.lastActivity
19540                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19541                                    // This service has not seen activity within
19542                                    // recent memory, so allow it to drop to the
19543                                    // LRU list if there is no other reason to keep
19544                                    // it around.  We'll also tag it with a label just
19545                                    // to help debug and undertand what is going on.
19546                                    if (adj > clientAdj) {
19547                                        adjType = "cch-bound-services";
19548                                    }
19549                                    clientAdj = adj;
19550                                }
19551                            }
19552                        }
19553                        if (adj > clientAdj) {
19554                            // If this process has recently shown UI, and
19555                            // the process that is binding to it is less
19556                            // important than being visible, then we don't
19557                            // care about the binding as much as we care
19558                            // about letting this process get into the LRU
19559                            // list to be killed and restarted if needed for
19560                            // memory.
19561                            if (app.hasShownUi && app != mHomeProcess
19562                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19563                                adjType = "cch-bound-ui-services";
19564                            } else {
19565                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19566                                        |Context.BIND_IMPORTANT)) != 0) {
19567                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19568                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19569                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19570                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19571                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19572                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19573                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19574                                    adj = clientAdj;
19575                                } else {
19576                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19577                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19578                                    }
19579                                }
19580                                if (!client.cached) {
19581                                    app.cached = false;
19582                                }
19583                                adjType = "service";
19584                            }
19585                        }
19586                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19587                            // This will treat important bound services identically to
19588                            // the top app, which may behave differently than generic
19589                            // foreground work.
19590                            if (client.curSchedGroup > schedGroup) {
19591                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19592                                    schedGroup = client.curSchedGroup;
19593                                } else {
19594                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19595                                }
19596                            }
19597                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19598                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19599                                    // Special handling of clients who are in the top state.
19600                                    // We *may* want to consider this process to be in the
19601                                    // top state as well, but only if there is not another
19602                                    // reason for it to be running.  Being on the top is a
19603                                    // special state, meaning you are specifically running
19604                                    // for the current top app.  If the process is already
19605                                    // running in the background for some other reason, it
19606                                    // is more important to continue considering it to be
19607                                    // in the background state.
19608                                    mayBeTop = true;
19609                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19610                                } else {
19611                                    // Special handling for above-top states (persistent
19612                                    // processes).  These should not bring the current process
19613                                    // into the top state, since they are not on top.  Instead
19614                                    // give them the best state after that.
19615                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19616                                        clientProcState =
19617                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19618                                    } else if (mWakefulness
19619                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19620                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19621                                                    != 0) {
19622                                        clientProcState =
19623                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19624                                    } else {
19625                                        clientProcState =
19626                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19627                                    }
19628                                }
19629                            }
19630                        } else {
19631                            if (clientProcState <
19632                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19633                                clientProcState =
19634                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19635                            }
19636                        }
19637                        if (procState > clientProcState) {
19638                            procState = clientProcState;
19639                        }
19640                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19641                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19642                            app.pendingUiClean = true;
19643                        }
19644                        if (adjType != null) {
19645                            app.adjType = adjType;
19646                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19647                                    .REASON_SERVICE_IN_USE;
19648                            app.adjSource = cr.binding.client;
19649                            app.adjSourceProcState = clientProcState;
19650                            app.adjTarget = s.name;
19651                        }
19652                    }
19653                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19654                        app.treatLikeActivity = true;
19655                    }
19656                    final ActivityRecord a = cr.activity;
19657                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19658                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19659                            (a.visible || a.state == ActivityState.RESUMED ||
19660                             a.state == ActivityState.PAUSING)) {
19661                            adj = ProcessList.FOREGROUND_APP_ADJ;
19662                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19663                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19664                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19665                                } else {
19666                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19667                                }
19668                            }
19669                            app.cached = false;
19670                            app.adjType = "service";
19671                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19672                                    .REASON_SERVICE_IN_USE;
19673                            app.adjSource = a;
19674                            app.adjSourceProcState = procState;
19675                            app.adjTarget = s.name;
19676                        }
19677                    }
19678                }
19679            }
19680        }
19681
19682        for (int provi = app.pubProviders.size()-1;
19683                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19684                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19685                        || procState > ActivityManager.PROCESS_STATE_TOP);
19686                provi--) {
19687            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19688            for (int i = cpr.connections.size()-1;
19689                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19690                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19691                            || procState > ActivityManager.PROCESS_STATE_TOP);
19692                    i--) {
19693                ContentProviderConnection conn = cpr.connections.get(i);
19694                ProcessRecord client = conn.client;
19695                if (client == app) {
19696                    // Being our own client is not interesting.
19697                    continue;
19698                }
19699                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19700                int clientProcState = client.curProcState;
19701                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19702                    // If the other app is cached for any reason, for purposes here
19703                    // we are going to consider it empty.
19704                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19705                }
19706                if (adj > clientAdj) {
19707                    if (app.hasShownUi && app != mHomeProcess
19708                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19709                        app.adjType = "cch-ui-provider";
19710                    } else {
19711                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19712                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19713                        app.adjType = "provider";
19714                    }
19715                    app.cached &= client.cached;
19716                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19717                            .REASON_PROVIDER_IN_USE;
19718                    app.adjSource = client;
19719                    app.adjSourceProcState = clientProcState;
19720                    app.adjTarget = cpr.name;
19721                }
19722                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19723                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19724                        // Special handling of clients who are in the top state.
19725                        // We *may* want to consider this process to be in the
19726                        // top state as well, but only if there is not another
19727                        // reason for it to be running.  Being on the top is a
19728                        // special state, meaning you are specifically running
19729                        // for the current top app.  If the process is already
19730                        // running in the background for some other reason, it
19731                        // is more important to continue considering it to be
19732                        // in the background state.
19733                        mayBeTop = true;
19734                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19735                    } else {
19736                        // Special handling for above-top states (persistent
19737                        // processes).  These should not bring the current process
19738                        // into the top state, since they are not on top.  Instead
19739                        // give them the best state after that.
19740                        clientProcState =
19741                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19742                    }
19743                }
19744                if (procState > clientProcState) {
19745                    procState = clientProcState;
19746                }
19747                if (client.curSchedGroup > schedGroup) {
19748                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19749                }
19750            }
19751            // If the provider has external (non-framework) process
19752            // dependencies, ensure that its adjustment is at least
19753            // FOREGROUND_APP_ADJ.
19754            if (cpr.hasExternalProcessHandles()) {
19755                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19756                    adj = ProcessList.FOREGROUND_APP_ADJ;
19757                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19758                    app.cached = false;
19759                    app.adjType = "provider";
19760                    app.adjTarget = cpr.name;
19761                }
19762                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19763                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19764                }
19765            }
19766        }
19767
19768        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19769            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19770                adj = ProcessList.PREVIOUS_APP_ADJ;
19771                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19772                app.cached = false;
19773                app.adjType = "provider";
19774            }
19775            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19776                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19777            }
19778        }
19779
19780        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19781            // A client of one of our services or providers is in the top state.  We
19782            // *may* want to be in the top state, but not if we are already running in
19783            // the background for some other reason.  For the decision here, we are going
19784            // to pick out a few specific states that we want to remain in when a client
19785            // is top (states that tend to be longer-term) and otherwise allow it to go
19786            // to the top state.
19787            switch (procState) {
19788                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19789                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19790                case ActivityManager.PROCESS_STATE_SERVICE:
19791                    // These all are longer-term states, so pull them up to the top
19792                    // of the background states, but not all the way to the top state.
19793                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19794                    break;
19795                default:
19796                    // Otherwise, top is a better choice, so take it.
19797                    procState = ActivityManager.PROCESS_STATE_TOP;
19798                    break;
19799            }
19800        }
19801
19802        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19803            if (app.hasClientActivities) {
19804                // This is a cached process, but with client activities.  Mark it so.
19805                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19806                app.adjType = "cch-client-act";
19807            } else if (app.treatLikeActivity) {
19808                // This is a cached process, but somebody wants us to treat it like it has
19809                // an activity, okay!
19810                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19811                app.adjType = "cch-as-act";
19812            }
19813        }
19814
19815        if (adj == ProcessList.SERVICE_ADJ) {
19816            if (doingAll) {
19817                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19818                mNewNumServiceProcs++;
19819                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19820                if (!app.serviceb) {
19821                    // This service isn't far enough down on the LRU list to
19822                    // normally be a B service, but if we are low on RAM and it
19823                    // is large we want to force it down since we would prefer to
19824                    // keep launcher over it.
19825                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19826                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19827                        app.serviceHighRam = true;
19828                        app.serviceb = true;
19829                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19830                    } else {
19831                        mNewNumAServiceProcs++;
19832                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19833                    }
19834                } else {
19835                    app.serviceHighRam = false;
19836                }
19837            }
19838            if (app.serviceb) {
19839                adj = ProcessList.SERVICE_B_ADJ;
19840            }
19841        }
19842
19843        app.curRawAdj = adj;
19844
19845        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19846        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19847        if (adj > app.maxAdj) {
19848            adj = app.maxAdj;
19849            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19850                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19851            }
19852        }
19853
19854        // Do final modification to adj.  Everything we do between here and applying
19855        // the final setAdj must be done in this function, because we will also use
19856        // it when computing the final cached adj later.  Note that we don't need to
19857        // worry about this for max adj above, since max adj will always be used to
19858        // keep it out of the cached vaues.
19859        app.curAdj = app.modifyRawOomAdj(adj);
19860        app.curSchedGroup = schedGroup;
19861        app.curProcState = procState;
19862        app.foregroundActivities = foregroundActivities;
19863
19864        return app.curRawAdj;
19865    }
19866
19867    /**
19868     * Record new PSS sample for a process.
19869     */
19870    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19871            long now) {
19872        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19873                swapPss * 1024);
19874        proc.lastPssTime = now;
19875        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19876        if (DEBUG_PSS) Slog.d(TAG_PSS,
19877                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19878                + " state=" + ProcessList.makeProcStateString(procState));
19879        if (proc.initialIdlePss == 0) {
19880            proc.initialIdlePss = pss;
19881        }
19882        proc.lastPss = pss;
19883        proc.lastSwapPss = swapPss;
19884        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19885            proc.lastCachedPss = pss;
19886            proc.lastCachedSwapPss = swapPss;
19887        }
19888
19889        final SparseArray<Pair<Long, String>> watchUids
19890                = mMemWatchProcesses.getMap().get(proc.processName);
19891        Long check = null;
19892        if (watchUids != null) {
19893            Pair<Long, String> val = watchUids.get(proc.uid);
19894            if (val == null) {
19895                val = watchUids.get(0);
19896            }
19897            if (val != null) {
19898                check = val.first;
19899            }
19900        }
19901        if (check != null) {
19902            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19903                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19904                if (!isDebuggable) {
19905                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19906                        isDebuggable = true;
19907                    }
19908                }
19909                if (isDebuggable) {
19910                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19911                    final ProcessRecord myProc = proc;
19912                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19913                    mMemWatchDumpProcName = proc.processName;
19914                    mMemWatchDumpFile = heapdumpFile.toString();
19915                    mMemWatchDumpPid = proc.pid;
19916                    mMemWatchDumpUid = proc.uid;
19917                    BackgroundThread.getHandler().post(new Runnable() {
19918                        @Override
19919                        public void run() {
19920                            revokeUriPermission(ActivityThread.currentActivityThread()
19921                                            .getApplicationThread(),
19922                                    DumpHeapActivity.JAVA_URI,
19923                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19924                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19925                                    UserHandle.myUserId());
19926                            ParcelFileDescriptor fd = null;
19927                            try {
19928                                heapdumpFile.delete();
19929                                fd = ParcelFileDescriptor.open(heapdumpFile,
19930                                        ParcelFileDescriptor.MODE_CREATE |
19931                                                ParcelFileDescriptor.MODE_TRUNCATE |
19932                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19933                                                ParcelFileDescriptor.MODE_APPEND);
19934                                IApplicationThread thread = myProc.thread;
19935                                if (thread != null) {
19936                                    try {
19937                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19938                                                "Requesting dump heap from "
19939                                                + myProc + " to " + heapdumpFile);
19940                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19941                                    } catch (RemoteException e) {
19942                                    }
19943                                }
19944                            } catch (FileNotFoundException e) {
19945                                e.printStackTrace();
19946                            } finally {
19947                                if (fd != null) {
19948                                    try {
19949                                        fd.close();
19950                                    } catch (IOException e) {
19951                                    }
19952                                }
19953                            }
19954                        }
19955                    });
19956                } else {
19957                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19958                            + ", but debugging not enabled");
19959                }
19960            }
19961        }
19962    }
19963
19964    /**
19965     * Schedule PSS collection of a process.
19966     */
19967    void requestPssLocked(ProcessRecord proc, int procState) {
19968        if (mPendingPssProcesses.contains(proc)) {
19969            return;
19970        }
19971        if (mPendingPssProcesses.size() == 0) {
19972            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19973        }
19974        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19975        proc.pssProcState = procState;
19976        mPendingPssProcesses.add(proc);
19977    }
19978
19979    /**
19980     * Schedule PSS collection of all processes.
19981     */
19982    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19983        if (!always) {
19984            if (now < (mLastFullPssTime +
19985                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19986                return;
19987            }
19988        }
19989        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19990        mLastFullPssTime = now;
19991        mFullPssPending = true;
19992        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19993        mPendingPssProcesses.clear();
19994        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19995            ProcessRecord app = mLruProcesses.get(i);
19996            if (app.thread == null
19997                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19998                continue;
19999            }
20000            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20001                app.pssProcState = app.setProcState;
20002                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20003                        mTestPssMode, isSleepingLocked(), now);
20004                mPendingPssProcesses.add(app);
20005            }
20006        }
20007        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20008    }
20009
20010    public void setTestPssMode(boolean enabled) {
20011        synchronized (this) {
20012            mTestPssMode = enabled;
20013            if (enabled) {
20014                // Whenever we enable the mode, we want to take a snapshot all of current
20015                // process mem use.
20016                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20017            }
20018        }
20019    }
20020
20021    /**
20022     * Ask a given process to GC right now.
20023     */
20024    final void performAppGcLocked(ProcessRecord app) {
20025        try {
20026            app.lastRequestedGc = SystemClock.uptimeMillis();
20027            if (app.thread != null) {
20028                if (app.reportLowMemory) {
20029                    app.reportLowMemory = false;
20030                    app.thread.scheduleLowMemory();
20031                } else {
20032                    app.thread.processInBackground();
20033                }
20034            }
20035        } catch (Exception e) {
20036            // whatever.
20037        }
20038    }
20039
20040    /**
20041     * Returns true if things are idle enough to perform GCs.
20042     */
20043    private final boolean canGcNowLocked() {
20044        boolean processingBroadcasts = false;
20045        for (BroadcastQueue q : mBroadcastQueues) {
20046            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20047                processingBroadcasts = true;
20048            }
20049        }
20050        return !processingBroadcasts
20051                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20052    }
20053
20054    /**
20055     * Perform GCs on all processes that are waiting for it, but only
20056     * if things are idle.
20057     */
20058    final void performAppGcsLocked() {
20059        final int N = mProcessesToGc.size();
20060        if (N <= 0) {
20061            return;
20062        }
20063        if (canGcNowLocked()) {
20064            while (mProcessesToGc.size() > 0) {
20065                ProcessRecord proc = mProcessesToGc.remove(0);
20066                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20067                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20068                            <= SystemClock.uptimeMillis()) {
20069                        // To avoid spamming the system, we will GC processes one
20070                        // at a time, waiting a few seconds between each.
20071                        performAppGcLocked(proc);
20072                        scheduleAppGcsLocked();
20073                        return;
20074                    } else {
20075                        // It hasn't been long enough since we last GCed this
20076                        // process...  put it in the list to wait for its time.
20077                        addProcessToGcListLocked(proc);
20078                        break;
20079                    }
20080                }
20081            }
20082
20083            scheduleAppGcsLocked();
20084        }
20085    }
20086
20087    /**
20088     * If all looks good, perform GCs on all processes waiting for them.
20089     */
20090    final void performAppGcsIfAppropriateLocked() {
20091        if (canGcNowLocked()) {
20092            performAppGcsLocked();
20093            return;
20094        }
20095        // Still not idle, wait some more.
20096        scheduleAppGcsLocked();
20097    }
20098
20099    /**
20100     * Schedule the execution of all pending app GCs.
20101     */
20102    final void scheduleAppGcsLocked() {
20103        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20104
20105        if (mProcessesToGc.size() > 0) {
20106            // Schedule a GC for the time to the next process.
20107            ProcessRecord proc = mProcessesToGc.get(0);
20108            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20109
20110            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20111            long now = SystemClock.uptimeMillis();
20112            if (when < (now+GC_TIMEOUT)) {
20113                when = now + GC_TIMEOUT;
20114            }
20115            mHandler.sendMessageAtTime(msg, when);
20116        }
20117    }
20118
20119    /**
20120     * Add a process to the array of processes waiting to be GCed.  Keeps the
20121     * list in sorted order by the last GC time.  The process can't already be
20122     * on the list.
20123     */
20124    final void addProcessToGcListLocked(ProcessRecord proc) {
20125        boolean added = false;
20126        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20127            if (mProcessesToGc.get(i).lastRequestedGc <
20128                    proc.lastRequestedGc) {
20129                added = true;
20130                mProcessesToGc.add(i+1, proc);
20131                break;
20132            }
20133        }
20134        if (!added) {
20135            mProcessesToGc.add(0, proc);
20136        }
20137    }
20138
20139    /**
20140     * Set up to ask a process to GC itself.  This will either do it
20141     * immediately, or put it on the list of processes to gc the next
20142     * time things are idle.
20143     */
20144    final void scheduleAppGcLocked(ProcessRecord app) {
20145        long now = SystemClock.uptimeMillis();
20146        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20147            return;
20148        }
20149        if (!mProcessesToGc.contains(app)) {
20150            addProcessToGcListLocked(app);
20151            scheduleAppGcsLocked();
20152        }
20153    }
20154
20155    final void checkExcessivePowerUsageLocked(boolean doKills) {
20156        updateCpuStatsNow();
20157
20158        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20159        boolean doWakeKills = doKills;
20160        boolean doCpuKills = doKills;
20161        if (mLastPowerCheckRealtime == 0) {
20162            doWakeKills = false;
20163        }
20164        if (mLastPowerCheckUptime == 0) {
20165            doCpuKills = false;
20166        }
20167        if (stats.isScreenOn()) {
20168            doWakeKills = false;
20169        }
20170        final long curRealtime = SystemClock.elapsedRealtime();
20171        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20172        final long curUptime = SystemClock.uptimeMillis();
20173        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20174        mLastPowerCheckRealtime = curRealtime;
20175        mLastPowerCheckUptime = curUptime;
20176        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20177            doWakeKills = false;
20178        }
20179        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20180            doCpuKills = false;
20181        }
20182        int i = mLruProcesses.size();
20183        while (i > 0) {
20184            i--;
20185            ProcessRecord app = mLruProcesses.get(i);
20186            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20187                long wtime;
20188                synchronized (stats) {
20189                    wtime = stats.getProcessWakeTime(app.info.uid,
20190                            app.pid, curRealtime);
20191                }
20192                long wtimeUsed = wtime - app.lastWakeTime;
20193                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20194                if (DEBUG_POWER) {
20195                    StringBuilder sb = new StringBuilder(128);
20196                    sb.append("Wake for ");
20197                    app.toShortString(sb);
20198                    sb.append(": over ");
20199                    TimeUtils.formatDuration(realtimeSince, sb);
20200                    sb.append(" used ");
20201                    TimeUtils.formatDuration(wtimeUsed, sb);
20202                    sb.append(" (");
20203                    sb.append((wtimeUsed*100)/realtimeSince);
20204                    sb.append("%)");
20205                    Slog.i(TAG_POWER, sb.toString());
20206                    sb.setLength(0);
20207                    sb.append("CPU for ");
20208                    app.toShortString(sb);
20209                    sb.append(": over ");
20210                    TimeUtils.formatDuration(uptimeSince, sb);
20211                    sb.append(" used ");
20212                    TimeUtils.formatDuration(cputimeUsed, sb);
20213                    sb.append(" (");
20214                    sb.append((cputimeUsed*100)/uptimeSince);
20215                    sb.append("%)");
20216                    Slog.i(TAG_POWER, sb.toString());
20217                }
20218                // If a process has held a wake lock for more
20219                // than 50% of the time during this period,
20220                // that sounds bad.  Kill!
20221                if (doWakeKills && realtimeSince > 0
20222                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20223                    synchronized (stats) {
20224                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20225                                realtimeSince, wtimeUsed);
20226                    }
20227                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20228                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20229                } else if (doCpuKills && uptimeSince > 0
20230                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20231                    synchronized (stats) {
20232                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20233                                uptimeSince, cputimeUsed);
20234                    }
20235                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20236                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20237                } else {
20238                    app.lastWakeTime = wtime;
20239                    app.lastCpuTime = app.curCpuTime;
20240                }
20241            }
20242        }
20243    }
20244
20245    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20246            long nowElapsed) {
20247        boolean success = true;
20248
20249        if (app.curRawAdj != app.setRawAdj) {
20250            app.setRawAdj = app.curRawAdj;
20251        }
20252
20253        int changes = 0;
20254
20255        if (app.curAdj != app.setAdj) {
20256            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20257            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20258                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20259                    + app.adjType);
20260            app.setAdj = app.curAdj;
20261            app.verifiedAdj = ProcessList.INVALID_ADJ;
20262        }
20263
20264        if (app.setSchedGroup != app.curSchedGroup) {
20265            int oldSchedGroup = app.setSchedGroup;
20266            app.setSchedGroup = app.curSchedGroup;
20267            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20268                    "Setting sched group of " + app.processName
20269                    + " to " + app.curSchedGroup);
20270            if (app.waitingToKill != null && app.curReceiver == null
20271                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20272                app.kill(app.waitingToKill, true);
20273                success = false;
20274            } else {
20275                int processGroup;
20276                switch (app.curSchedGroup) {
20277                    case ProcessList.SCHED_GROUP_BACKGROUND:
20278                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20279                        break;
20280                    case ProcessList.SCHED_GROUP_TOP_APP:
20281                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20282                        processGroup = Process.THREAD_GROUP_TOP_APP;
20283                        break;
20284                    default:
20285                        processGroup = Process.THREAD_GROUP_DEFAULT;
20286                        break;
20287                }
20288                long oldId = Binder.clearCallingIdentity();
20289                try {
20290                    Process.setProcessGroup(app.pid, processGroup);
20291                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20292                        // do nothing if we already switched to RT
20293                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20294                            // Switch VR thread for app to SCHED_FIFO
20295                            if (mInVrMode && app.vrThreadTid != 0) {
20296                                Process.setThreadScheduler(app.vrThreadTid,
20297                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20298                            }
20299                            if (mUseFifoUiScheduling) {
20300                                // Switch UI pipeline for app to SCHED_FIFO
20301                                app.savedPriority = Process.getThreadPriority(app.pid);
20302                                Process.setThreadScheduler(app.pid,
20303                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20304                                if (app.renderThreadTid != 0) {
20305                                    Process.setThreadScheduler(app.renderThreadTid,
20306                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20307                                    if (DEBUG_OOM_ADJ) {
20308                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20309                                            app.renderThreadTid + ") to FIFO");
20310                                    }
20311                                } else {
20312                                    if (DEBUG_OOM_ADJ) {
20313                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20314                                    }
20315                                }
20316                            } else {
20317                                // Boost priority for top app UI and render threads
20318                                Process.setThreadPriority(app.pid, -10);
20319                                if (app.renderThreadTid != 0) {
20320                                    Process.setThreadPriority(app.renderThreadTid, -10);
20321                                }
20322                            }
20323                        }
20324                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20325                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20326                        // Reset VR thread to SCHED_OTHER
20327                        // Safe to do even if we're not in VR mode
20328                        if (app.vrThreadTid != 0) {
20329                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20330                        }
20331                        if (mUseFifoUiScheduling) {
20332                            // Reset UI pipeline to SCHED_OTHER
20333                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20334                            Process.setThreadPriority(app.pid, app.savedPriority);
20335                            if (app.renderThreadTid != 0) {
20336                                Process.setThreadScheduler(app.renderThreadTid,
20337                                    Process.SCHED_OTHER, 0);
20338                                Process.setThreadPriority(app.renderThreadTid, -4);
20339                            }
20340                        } else {
20341                            // Reset priority for top app UI and render threads
20342                            Process.setThreadPriority(app.pid, 0);
20343                            if (app.renderThreadTid != 0) {
20344                                Process.setThreadPriority(app.renderThreadTid, 0);
20345                            }
20346                        }
20347                    }
20348                } catch (Exception e) {
20349                    Slog.w(TAG, "Failed setting process group of " + app.pid
20350                            + " to " + app.curSchedGroup);
20351                    e.printStackTrace();
20352                } finally {
20353                    Binder.restoreCallingIdentity(oldId);
20354                }
20355            }
20356        }
20357        if (app.repForegroundActivities != app.foregroundActivities) {
20358            app.repForegroundActivities = app.foregroundActivities;
20359            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20360        }
20361        if (app.repProcState != app.curProcState) {
20362            app.repProcState = app.curProcState;
20363            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20364            if (app.thread != null) {
20365                try {
20366                    if (false) {
20367                        //RuntimeException h = new RuntimeException("here");
20368                        Slog.i(TAG, "Sending new process state " + app.repProcState
20369                                + " to " + app /*, h*/);
20370                    }
20371                    app.thread.setProcessState(app.repProcState);
20372                } catch (RemoteException e) {
20373                }
20374            }
20375        }
20376        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20377                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20378            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20379                // Experimental code to more aggressively collect pss while
20380                // running test...  the problem is that this tends to collect
20381                // the data right when a process is transitioning between process
20382                // states, which well tend to give noisy data.
20383                long start = SystemClock.uptimeMillis();
20384                long pss = Debug.getPss(app.pid, mTmpLong, null);
20385                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20386                mPendingPssProcesses.remove(app);
20387                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20388                        + " to " + app.curProcState + ": "
20389                        + (SystemClock.uptimeMillis()-start) + "ms");
20390            }
20391            app.lastStateTime = now;
20392            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20393                    mTestPssMode, isSleepingLocked(), now);
20394            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20395                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20396                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20397                    + (app.nextPssTime-now) + ": " + app);
20398        } else {
20399            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20400                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20401                    mTestPssMode)))) {
20402                requestPssLocked(app, app.setProcState);
20403                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20404                        mTestPssMode, isSleepingLocked(), now);
20405            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20406                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20407        }
20408        if (app.setProcState != app.curProcState) {
20409            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20410                    "Proc state change of " + app.processName
20411                            + " to " + app.curProcState);
20412            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20413            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20414            if (setImportant && !curImportant) {
20415                // This app is no longer something we consider important enough to allow to
20416                // use arbitrary amounts of battery power.  Note
20417                // its current wake lock time to later know to kill it if
20418                // it is not behaving well.
20419                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20420                synchronized (stats) {
20421                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20422                            app.pid, nowElapsed);
20423                }
20424                app.lastCpuTime = app.curCpuTime;
20425
20426            }
20427            // Inform UsageStats of important process state change
20428            // Must be called before updating setProcState
20429            maybeUpdateUsageStatsLocked(app, nowElapsed);
20430
20431            app.setProcState = app.curProcState;
20432            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20433                app.notCachedSinceIdle = false;
20434            }
20435            if (!doingAll) {
20436                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20437            } else {
20438                app.procStateChanged = true;
20439            }
20440        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20441                > USAGE_STATS_INTERACTION_INTERVAL) {
20442            // For apps that sit around for a long time in the interactive state, we need
20443            // to report this at least once a day so they don't go idle.
20444            maybeUpdateUsageStatsLocked(app, nowElapsed);
20445        }
20446
20447        if (changes != 0) {
20448            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20449                    "Changes in " + app + ": " + changes);
20450            int i = mPendingProcessChanges.size()-1;
20451            ProcessChangeItem item = null;
20452            while (i >= 0) {
20453                item = mPendingProcessChanges.get(i);
20454                if (item.pid == app.pid) {
20455                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20456                            "Re-using existing item: " + item);
20457                    break;
20458                }
20459                i--;
20460            }
20461            if (i < 0) {
20462                // No existing item in pending changes; need a new one.
20463                final int NA = mAvailProcessChanges.size();
20464                if (NA > 0) {
20465                    item = mAvailProcessChanges.remove(NA-1);
20466                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20467                            "Retrieving available item: " + item);
20468                } else {
20469                    item = new ProcessChangeItem();
20470                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20471                            "Allocating new item: " + item);
20472                }
20473                item.changes = 0;
20474                item.pid = app.pid;
20475                item.uid = app.info.uid;
20476                if (mPendingProcessChanges.size() == 0) {
20477                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20478                            "*** Enqueueing dispatch processes changed!");
20479                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20480                }
20481                mPendingProcessChanges.add(item);
20482            }
20483            item.changes |= changes;
20484            item.processState = app.repProcState;
20485            item.foregroundActivities = app.repForegroundActivities;
20486            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20487                    "Item " + Integer.toHexString(System.identityHashCode(item))
20488                    + " " + app.toShortString() + ": changes=" + item.changes
20489                    + " procState=" + item.processState
20490                    + " foreground=" + item.foregroundActivities
20491                    + " type=" + app.adjType + " source=" + app.adjSource
20492                    + " target=" + app.adjTarget);
20493        }
20494
20495        return success;
20496    }
20497
20498    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20499        final UidRecord.ChangeItem pendingChange;
20500        if (uidRec == null || uidRec.pendingChange == null) {
20501            if (mPendingUidChanges.size() == 0) {
20502                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20503                        "*** Enqueueing dispatch uid changed!");
20504                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20505            }
20506            final int NA = mAvailUidChanges.size();
20507            if (NA > 0) {
20508                pendingChange = mAvailUidChanges.remove(NA-1);
20509                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20510                        "Retrieving available item: " + pendingChange);
20511            } else {
20512                pendingChange = new UidRecord.ChangeItem();
20513                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20514                        "Allocating new item: " + pendingChange);
20515            }
20516            if (uidRec != null) {
20517                uidRec.pendingChange = pendingChange;
20518                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20519                    // If this uid is going away, and we haven't yet reported it is gone,
20520                    // then do so now.
20521                    change = UidRecord.CHANGE_GONE_IDLE;
20522                }
20523            } else if (uid < 0) {
20524                throw new IllegalArgumentException("No UidRecord or uid");
20525            }
20526            pendingChange.uidRecord = uidRec;
20527            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20528            mPendingUidChanges.add(pendingChange);
20529        } else {
20530            pendingChange = uidRec.pendingChange;
20531            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20532                change = UidRecord.CHANGE_GONE_IDLE;
20533            }
20534        }
20535        pendingChange.change = change;
20536        pendingChange.processState = uidRec != null
20537                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20538    }
20539
20540    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20541            String authority) {
20542        if (app == null) return;
20543        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20544            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20545            if (userState == null) return;
20546            final long now = SystemClock.elapsedRealtime();
20547            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20548            if (lastReported == null || lastReported < now - 60 * 1000L) {
20549                mUsageStatsService.reportContentProviderUsage(
20550                        authority, providerPkgName, app.userId);
20551                userState.mProviderLastReportedFg.put(authority, now);
20552            }
20553        }
20554    }
20555
20556    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20557        if (DEBUG_USAGE_STATS) {
20558            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20559                    + "] state changes: old = " + app.setProcState + ", new = "
20560                    + app.curProcState);
20561        }
20562        if (mUsageStatsService == null) {
20563            return;
20564        }
20565        boolean isInteraction;
20566        // To avoid some abuse patterns, we are going to be careful about what we consider
20567        // to be an app interaction.  Being the top activity doesn't count while the display
20568        // is sleeping, nor do short foreground services.
20569        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20570            isInteraction = true;
20571            app.fgInteractionTime = 0;
20572        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20573            if (app.fgInteractionTime == 0) {
20574                app.fgInteractionTime = nowElapsed;
20575                isInteraction = false;
20576            } else {
20577                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20578            }
20579        } else {
20580            isInteraction = app.curProcState
20581                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20582            app.fgInteractionTime = 0;
20583        }
20584        if (isInteraction && (!app.reportedInteraction
20585                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20586            app.interactionEventTime = nowElapsed;
20587            String[] packages = app.getPackageList();
20588            if (packages != null) {
20589                for (int i = 0; i < packages.length; i++) {
20590                    mUsageStatsService.reportEvent(packages[i], app.userId,
20591                            UsageEvents.Event.SYSTEM_INTERACTION);
20592                }
20593            }
20594        }
20595        app.reportedInteraction = isInteraction;
20596        if (!isInteraction) {
20597            app.interactionEventTime = 0;
20598        }
20599    }
20600
20601    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20602        if (proc.thread != null) {
20603            if (proc.baseProcessTracker != null) {
20604                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20605            }
20606        }
20607    }
20608
20609    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20610            ProcessRecord TOP_APP, boolean doingAll, long now) {
20611        if (app.thread == null) {
20612            return false;
20613        }
20614
20615        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20616
20617        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20618    }
20619
20620    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20621            boolean oomAdj) {
20622        if (isForeground != proc.foregroundServices) {
20623            proc.foregroundServices = isForeground;
20624            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20625                    proc.info.uid);
20626            if (isForeground) {
20627                if (curProcs == null) {
20628                    curProcs = new ArrayList<ProcessRecord>();
20629                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20630                }
20631                if (!curProcs.contains(proc)) {
20632                    curProcs.add(proc);
20633                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20634                            proc.info.packageName, proc.info.uid);
20635                }
20636            } else {
20637                if (curProcs != null) {
20638                    if (curProcs.remove(proc)) {
20639                        mBatteryStatsService.noteEvent(
20640                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20641                                proc.info.packageName, proc.info.uid);
20642                        if (curProcs.size() <= 0) {
20643                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20644                        }
20645                    }
20646                }
20647            }
20648            if (oomAdj) {
20649                updateOomAdjLocked();
20650            }
20651        }
20652    }
20653
20654    private final ActivityRecord resumedAppLocked() {
20655        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20656        String pkg;
20657        int uid;
20658        if (act != null) {
20659            pkg = act.packageName;
20660            uid = act.info.applicationInfo.uid;
20661        } else {
20662            pkg = null;
20663            uid = -1;
20664        }
20665        // Has the UID or resumed package name changed?
20666        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20667                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20668            if (mCurResumedPackage != null) {
20669                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20670                        mCurResumedPackage, mCurResumedUid);
20671            }
20672            mCurResumedPackage = pkg;
20673            mCurResumedUid = uid;
20674            if (mCurResumedPackage != null) {
20675                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20676                        mCurResumedPackage, mCurResumedUid);
20677            }
20678        }
20679        return act;
20680    }
20681
20682    final boolean updateOomAdjLocked(ProcessRecord app) {
20683        final ActivityRecord TOP_ACT = resumedAppLocked();
20684        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20685        final boolean wasCached = app.cached;
20686
20687        mAdjSeq++;
20688
20689        // This is the desired cached adjusment we want to tell it to use.
20690        // If our app is currently cached, we know it, and that is it.  Otherwise,
20691        // we don't know it yet, and it needs to now be cached we will then
20692        // need to do a complete oom adj.
20693        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20694                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20695        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20696                SystemClock.uptimeMillis());
20697        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20698            // Changed to/from cached state, so apps after it in the LRU
20699            // list may also be changed.
20700            updateOomAdjLocked();
20701        }
20702        return success;
20703    }
20704
20705    final void updateOomAdjLocked() {
20706        final ActivityRecord TOP_ACT = resumedAppLocked();
20707        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20708        final long now = SystemClock.uptimeMillis();
20709        final long nowElapsed = SystemClock.elapsedRealtime();
20710        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20711        final int N = mLruProcesses.size();
20712
20713        if (false) {
20714            RuntimeException e = new RuntimeException();
20715            e.fillInStackTrace();
20716            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20717        }
20718
20719        // Reset state in all uid records.
20720        for (int i=mActiveUids.size()-1; i>=0; i--) {
20721            final UidRecord uidRec = mActiveUids.valueAt(i);
20722            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20723                    "Starting update of " + uidRec);
20724            uidRec.reset();
20725        }
20726
20727        mStackSupervisor.rankTaskLayersIfNeeded();
20728
20729        mAdjSeq++;
20730        mNewNumServiceProcs = 0;
20731        mNewNumAServiceProcs = 0;
20732
20733        final int emptyProcessLimit;
20734        final int cachedProcessLimit;
20735        if (mProcessLimit <= 0) {
20736            emptyProcessLimit = cachedProcessLimit = 0;
20737        } else if (mProcessLimit == 1) {
20738            emptyProcessLimit = 1;
20739            cachedProcessLimit = 0;
20740        } else {
20741            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20742            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20743        }
20744
20745        // Let's determine how many processes we have running vs.
20746        // how many slots we have for background processes; we may want
20747        // to put multiple processes in a slot of there are enough of
20748        // them.
20749        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20750                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20751        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20752        if (numEmptyProcs > cachedProcessLimit) {
20753            // If there are more empty processes than our limit on cached
20754            // processes, then use the cached process limit for the factor.
20755            // This ensures that the really old empty processes get pushed
20756            // down to the bottom, so if we are running low on memory we will
20757            // have a better chance at keeping around more cached processes
20758            // instead of a gazillion empty processes.
20759            numEmptyProcs = cachedProcessLimit;
20760        }
20761        int emptyFactor = numEmptyProcs/numSlots;
20762        if (emptyFactor < 1) emptyFactor = 1;
20763        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20764        if (cachedFactor < 1) cachedFactor = 1;
20765        int stepCached = 0;
20766        int stepEmpty = 0;
20767        int numCached = 0;
20768        int numEmpty = 0;
20769        int numTrimming = 0;
20770
20771        mNumNonCachedProcs = 0;
20772        mNumCachedHiddenProcs = 0;
20773
20774        // First update the OOM adjustment for each of the
20775        // application processes based on their current state.
20776        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20777        int nextCachedAdj = curCachedAdj+1;
20778        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20779        int nextEmptyAdj = curEmptyAdj+2;
20780        for (int i=N-1; i>=0; i--) {
20781            ProcessRecord app = mLruProcesses.get(i);
20782            if (!app.killedByAm && app.thread != null) {
20783                app.procStateChanged = false;
20784                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20785
20786                // If we haven't yet assigned the final cached adj
20787                // to the process, do that now.
20788                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20789                    switch (app.curProcState) {
20790                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20791                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20792                            // This process is a cached process holding activities...
20793                            // assign it the next cached value for that type, and then
20794                            // step that cached level.
20795                            app.curRawAdj = curCachedAdj;
20796                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20797                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20798                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20799                                    + ")");
20800                            if (curCachedAdj != nextCachedAdj) {
20801                                stepCached++;
20802                                if (stepCached >= cachedFactor) {
20803                                    stepCached = 0;
20804                                    curCachedAdj = nextCachedAdj;
20805                                    nextCachedAdj += 2;
20806                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20807                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20808                                    }
20809                                }
20810                            }
20811                            break;
20812                        default:
20813                            // For everything else, assign next empty cached process
20814                            // level and bump that up.  Note that this means that
20815                            // long-running services that have dropped down to the
20816                            // cached level will be treated as empty (since their process
20817                            // state is still as a service), which is what we want.
20818                            app.curRawAdj = curEmptyAdj;
20819                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20820                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20821                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20822                                    + ")");
20823                            if (curEmptyAdj != nextEmptyAdj) {
20824                                stepEmpty++;
20825                                if (stepEmpty >= emptyFactor) {
20826                                    stepEmpty = 0;
20827                                    curEmptyAdj = nextEmptyAdj;
20828                                    nextEmptyAdj += 2;
20829                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20830                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20831                                    }
20832                                }
20833                            }
20834                            break;
20835                    }
20836                }
20837
20838                applyOomAdjLocked(app, true, now, nowElapsed);
20839
20840                // Count the number of process types.
20841                switch (app.curProcState) {
20842                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20843                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20844                        mNumCachedHiddenProcs++;
20845                        numCached++;
20846                        if (numCached > cachedProcessLimit) {
20847                            app.kill("cached #" + numCached, true);
20848                        }
20849                        break;
20850                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20851                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20852                                && app.lastActivityTime < oldTime) {
20853                            app.kill("empty for "
20854                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20855                                    / 1000) + "s", true);
20856                        } else {
20857                            numEmpty++;
20858                            if (numEmpty > emptyProcessLimit) {
20859                                app.kill("empty #" + numEmpty, true);
20860                            }
20861                        }
20862                        break;
20863                    default:
20864                        mNumNonCachedProcs++;
20865                        break;
20866                }
20867
20868                if (app.isolated && app.services.size() <= 0) {
20869                    // If this is an isolated process, and there are no
20870                    // services running in it, then the process is no longer
20871                    // needed.  We agressively kill these because we can by
20872                    // definition not re-use the same process again, and it is
20873                    // good to avoid having whatever code was running in them
20874                    // left sitting around after no longer needed.
20875                    app.kill("isolated not needed", true);
20876                } else {
20877                    // Keeping this process, update its uid.
20878                    final UidRecord uidRec = app.uidRecord;
20879                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20880                        uidRec.curProcState = app.curProcState;
20881                    }
20882                }
20883
20884                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20885                        && !app.killedByAm) {
20886                    numTrimming++;
20887                }
20888            }
20889        }
20890
20891        mNumServiceProcs = mNewNumServiceProcs;
20892
20893        // Now determine the memory trimming level of background processes.
20894        // Unfortunately we need to start at the back of the list to do this
20895        // properly.  We only do this if the number of background apps we
20896        // are managing to keep around is less than half the maximum we desire;
20897        // if we are keeping a good number around, we'll let them use whatever
20898        // memory they want.
20899        final int numCachedAndEmpty = numCached + numEmpty;
20900        int memFactor;
20901        if (numCached <= ProcessList.TRIM_CACHED_APPS
20902                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20903            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20904                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20905            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20906                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20907            } else {
20908                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20909            }
20910        } else {
20911            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20912        }
20913        // We always allow the memory level to go up (better).  We only allow it to go
20914        // down if we are in a state where that is allowed, *and* the total number of processes
20915        // has gone down since last time.
20916        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20917                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20918                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20919        if (memFactor > mLastMemoryLevel) {
20920            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20921                memFactor = mLastMemoryLevel;
20922                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20923            }
20924        }
20925        if (memFactor != mLastMemoryLevel) {
20926            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20927        }
20928        mLastMemoryLevel = memFactor;
20929        mLastNumProcesses = mLruProcesses.size();
20930        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20931        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20932        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20933            if (mLowRamStartTime == 0) {
20934                mLowRamStartTime = now;
20935            }
20936            int step = 0;
20937            int fgTrimLevel;
20938            switch (memFactor) {
20939                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20940                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20941                    break;
20942                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20943                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20944                    break;
20945                default:
20946                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20947                    break;
20948            }
20949            int factor = numTrimming/3;
20950            int minFactor = 2;
20951            if (mHomeProcess != null) minFactor++;
20952            if (mPreviousProcess != null) minFactor++;
20953            if (factor < minFactor) factor = minFactor;
20954            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20955            for (int i=N-1; i>=0; i--) {
20956                ProcessRecord app = mLruProcesses.get(i);
20957                if (allChanged || app.procStateChanged) {
20958                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20959                    app.procStateChanged = false;
20960                }
20961                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20962                        && !app.killedByAm) {
20963                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20964                        try {
20965                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20966                                    "Trimming memory of " + app.processName + " to " + curLevel);
20967                            app.thread.scheduleTrimMemory(curLevel);
20968                        } catch (RemoteException e) {
20969                        }
20970                        if (false) {
20971                            // For now we won't do this; our memory trimming seems
20972                            // to be good enough at this point that destroying
20973                            // activities causes more harm than good.
20974                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20975                                    && app != mHomeProcess && app != mPreviousProcess) {
20976                                // Need to do this on its own message because the stack may not
20977                                // be in a consistent state at this point.
20978                                // For these apps we will also finish their activities
20979                                // to help them free memory.
20980                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20981                            }
20982                        }
20983                    }
20984                    app.trimMemoryLevel = curLevel;
20985                    step++;
20986                    if (step >= factor) {
20987                        step = 0;
20988                        switch (curLevel) {
20989                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20990                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20991                                break;
20992                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20993                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20994                                break;
20995                        }
20996                    }
20997                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20998                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20999                            && app.thread != null) {
21000                        try {
21001                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21002                                    "Trimming memory of heavy-weight " + app.processName
21003                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21004                            app.thread.scheduleTrimMemory(
21005                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21006                        } catch (RemoteException e) {
21007                        }
21008                    }
21009                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21010                } else {
21011                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21012                            || app.systemNoUi) && app.pendingUiClean) {
21013                        // If this application is now in the background and it
21014                        // had done UI, then give it the special trim level to
21015                        // have it free UI resources.
21016                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21017                        if (app.trimMemoryLevel < level && app.thread != null) {
21018                            try {
21019                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21020                                        "Trimming memory of bg-ui " + app.processName
21021                                        + " to " + level);
21022                                app.thread.scheduleTrimMemory(level);
21023                            } catch (RemoteException e) {
21024                            }
21025                        }
21026                        app.pendingUiClean = false;
21027                    }
21028                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21029                        try {
21030                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21031                                    "Trimming memory of fg " + app.processName
21032                                    + " to " + fgTrimLevel);
21033                            app.thread.scheduleTrimMemory(fgTrimLevel);
21034                        } catch (RemoteException e) {
21035                        }
21036                    }
21037                    app.trimMemoryLevel = fgTrimLevel;
21038                }
21039            }
21040        } else {
21041            if (mLowRamStartTime != 0) {
21042                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21043                mLowRamStartTime = 0;
21044            }
21045            for (int i=N-1; i>=0; i--) {
21046                ProcessRecord app = mLruProcesses.get(i);
21047                if (allChanged || app.procStateChanged) {
21048                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21049                    app.procStateChanged = false;
21050                }
21051                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21052                        || app.systemNoUi) && app.pendingUiClean) {
21053                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21054                            && app.thread != null) {
21055                        try {
21056                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21057                                    "Trimming memory of ui hidden " + app.processName
21058                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21059                            app.thread.scheduleTrimMemory(
21060                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21061                        } catch (RemoteException e) {
21062                        }
21063                    }
21064                    app.pendingUiClean = false;
21065                }
21066                app.trimMemoryLevel = 0;
21067            }
21068        }
21069
21070        if (mAlwaysFinishActivities) {
21071            // Need to do this on its own message because the stack may not
21072            // be in a consistent state at this point.
21073            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21074        }
21075
21076        if (allChanged) {
21077            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21078        }
21079
21080        // Update from any uid changes.
21081        for (int i=mActiveUids.size()-1; i>=0; i--) {
21082            final UidRecord uidRec = mActiveUids.valueAt(i);
21083            int uidChange = UidRecord.CHANGE_PROCSTATE;
21084            if (uidRec.setProcState != uidRec.curProcState) {
21085                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21086                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21087                        + " to " + uidRec.curProcState);
21088                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21089                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21090                        uidRec.lastBackgroundTime = nowElapsed;
21091                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21092                            // Note: the background settle time is in elapsed realtime, while
21093                            // the handler time base is uptime.  All this means is that we may
21094                            // stop background uids later than we had intended, but that only
21095                            // happens because the device was sleeping so we are okay anyway.
21096                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21097                        }
21098                    }
21099                } else {
21100                    if (uidRec.idle) {
21101                        uidChange = UidRecord.CHANGE_ACTIVE;
21102                        uidRec.idle = false;
21103                    }
21104                    uidRec.lastBackgroundTime = 0;
21105                }
21106                uidRec.setProcState = uidRec.curProcState;
21107                enqueueUidChangeLocked(uidRec, -1, uidChange);
21108                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21109            }
21110        }
21111
21112        if (mProcessStats.shouldWriteNowLocked(now)) {
21113            mHandler.post(new Runnable() {
21114                @Override public void run() {
21115                    synchronized (ActivityManagerService.this) {
21116                        mProcessStats.writeStateAsyncLocked();
21117                    }
21118                }
21119            });
21120        }
21121
21122        if (DEBUG_OOM_ADJ) {
21123            final long duration = SystemClock.uptimeMillis() - now;
21124            if (false) {
21125                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21126                        new RuntimeException("here").fillInStackTrace());
21127            } else {
21128                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21129            }
21130        }
21131    }
21132
21133    final void idleUids() {
21134        synchronized (this) {
21135            final long nowElapsed = SystemClock.elapsedRealtime();
21136            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21137            long nextTime = 0;
21138            for (int i=mActiveUids.size()-1; i>=0; i--) {
21139                final UidRecord uidRec = mActiveUids.valueAt(i);
21140                final long bgTime = uidRec.lastBackgroundTime;
21141                if (bgTime > 0 && !uidRec.idle) {
21142                    if (bgTime <= maxBgTime) {
21143                        uidRec.idle = true;
21144                        doStopUidLocked(uidRec.uid, uidRec);
21145                    } else {
21146                        if (nextTime == 0 || nextTime > bgTime) {
21147                            nextTime = bgTime;
21148                        }
21149                    }
21150                }
21151            }
21152            if (nextTime > 0) {
21153                mHandler.removeMessages(IDLE_UIDS_MSG);
21154                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21155                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21156            }
21157        }
21158    }
21159
21160    final void runInBackgroundDisabled(int uid) {
21161        synchronized (this) {
21162            UidRecord uidRec = mActiveUids.get(uid);
21163            if (uidRec != null) {
21164                // This uid is actually running...  should it be considered background now?
21165                if (uidRec.idle) {
21166                    doStopUidLocked(uidRec.uid, uidRec);
21167                }
21168            } else {
21169                // This uid isn't actually running...  still send a report about it being "stopped".
21170                doStopUidLocked(uid, null);
21171            }
21172        }
21173    }
21174
21175    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21176        mServices.stopInBackgroundLocked(uid);
21177        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21178    }
21179
21180    final void trimApplications() {
21181        synchronized (this) {
21182            int i;
21183
21184            // First remove any unused application processes whose package
21185            // has been removed.
21186            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21187                final ProcessRecord app = mRemovedProcesses.get(i);
21188                if (app.activities.size() == 0
21189                        && app.curReceiver == null && app.services.size() == 0) {
21190                    Slog.i(
21191                        TAG, "Exiting empty application process "
21192                        + app.toShortString() + " ("
21193                        + (app.thread != null ? app.thread.asBinder() : null)
21194                        + ")\n");
21195                    if (app.pid > 0 && app.pid != MY_PID) {
21196                        app.kill("empty", false);
21197                    } else {
21198                        try {
21199                            app.thread.scheduleExit();
21200                        } catch (Exception e) {
21201                            // Ignore exceptions.
21202                        }
21203                    }
21204                    cleanUpApplicationRecordLocked(app, false, true, -1);
21205                    mRemovedProcesses.remove(i);
21206
21207                    if (app.persistent) {
21208                        addAppLocked(app.info, false, null /* ABI override */);
21209                    }
21210                }
21211            }
21212
21213            // Now update the oom adj for all processes.
21214            updateOomAdjLocked();
21215        }
21216    }
21217
21218    /** This method sends the specified signal to each of the persistent apps */
21219    public void signalPersistentProcesses(int sig) throws RemoteException {
21220        if (sig != Process.SIGNAL_USR1) {
21221            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21222        }
21223
21224        synchronized (this) {
21225            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21226                    != PackageManager.PERMISSION_GRANTED) {
21227                throw new SecurityException("Requires permission "
21228                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21229            }
21230
21231            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21232                ProcessRecord r = mLruProcesses.get(i);
21233                if (r.thread != null && r.persistent) {
21234                    Process.sendSignal(r.pid, sig);
21235                }
21236            }
21237        }
21238    }
21239
21240    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21241        if (proc == null || proc == mProfileProc) {
21242            proc = mProfileProc;
21243            profileType = mProfileType;
21244            clearProfilerLocked();
21245        }
21246        if (proc == null) {
21247            return;
21248        }
21249        try {
21250            proc.thread.profilerControl(false, null, profileType);
21251        } catch (RemoteException e) {
21252            throw new IllegalStateException("Process disappeared");
21253        }
21254    }
21255
21256    private void clearProfilerLocked() {
21257        if (mProfileFd != null) {
21258            try {
21259                mProfileFd.close();
21260            } catch (IOException e) {
21261            }
21262        }
21263        mProfileApp = null;
21264        mProfileProc = null;
21265        mProfileFile = null;
21266        mProfileType = 0;
21267        mAutoStopProfiler = false;
21268        mSamplingInterval = 0;
21269    }
21270
21271    public boolean profileControl(String process, int userId, boolean start,
21272            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21273
21274        try {
21275            synchronized (this) {
21276                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21277                // its own permission.
21278                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21279                        != PackageManager.PERMISSION_GRANTED) {
21280                    throw new SecurityException("Requires permission "
21281                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21282                }
21283
21284                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21285                    throw new IllegalArgumentException("null profile info or fd");
21286                }
21287
21288                ProcessRecord proc = null;
21289                if (process != null) {
21290                    proc = findProcessLocked(process, userId, "profileControl");
21291                }
21292
21293                if (start && (proc == null || proc.thread == null)) {
21294                    throw new IllegalArgumentException("Unknown process: " + process);
21295                }
21296
21297                if (start) {
21298                    stopProfilerLocked(null, 0);
21299                    setProfileApp(proc.info, proc.processName, profilerInfo);
21300                    mProfileProc = proc;
21301                    mProfileType = profileType;
21302                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21303                    try {
21304                        fd = fd.dup();
21305                    } catch (IOException e) {
21306                        fd = null;
21307                    }
21308                    profilerInfo.profileFd = fd;
21309                    proc.thread.profilerControl(start, profilerInfo, profileType);
21310                    fd = null;
21311                    mProfileFd = null;
21312                } else {
21313                    stopProfilerLocked(proc, profileType);
21314                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21315                        try {
21316                            profilerInfo.profileFd.close();
21317                        } catch (IOException e) {
21318                        }
21319                    }
21320                }
21321
21322                return true;
21323            }
21324        } catch (RemoteException e) {
21325            throw new IllegalStateException("Process disappeared");
21326        } finally {
21327            if (profilerInfo != null && profilerInfo.profileFd != null) {
21328                try {
21329                    profilerInfo.profileFd.close();
21330                } catch (IOException e) {
21331                }
21332            }
21333        }
21334    }
21335
21336    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21337        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21338                userId, true, ALLOW_FULL_ONLY, callName, null);
21339        ProcessRecord proc = null;
21340        try {
21341            int pid = Integer.parseInt(process);
21342            synchronized (mPidsSelfLocked) {
21343                proc = mPidsSelfLocked.get(pid);
21344            }
21345        } catch (NumberFormatException e) {
21346        }
21347
21348        if (proc == null) {
21349            ArrayMap<String, SparseArray<ProcessRecord>> all
21350                    = mProcessNames.getMap();
21351            SparseArray<ProcessRecord> procs = all.get(process);
21352            if (procs != null && procs.size() > 0) {
21353                proc = procs.valueAt(0);
21354                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21355                    for (int i=1; i<procs.size(); i++) {
21356                        ProcessRecord thisProc = procs.valueAt(i);
21357                        if (thisProc.userId == userId) {
21358                            proc = thisProc;
21359                            break;
21360                        }
21361                    }
21362                }
21363            }
21364        }
21365
21366        return proc;
21367    }
21368
21369    public boolean dumpHeap(String process, int userId, boolean managed,
21370            String path, ParcelFileDescriptor fd) throws RemoteException {
21371
21372        try {
21373            synchronized (this) {
21374                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21375                // its own permission (same as profileControl).
21376                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21377                        != PackageManager.PERMISSION_GRANTED) {
21378                    throw new SecurityException("Requires permission "
21379                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21380                }
21381
21382                if (fd == null) {
21383                    throw new IllegalArgumentException("null fd");
21384                }
21385
21386                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21387                if (proc == null || proc.thread == null) {
21388                    throw new IllegalArgumentException("Unknown process: " + process);
21389                }
21390
21391                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21392                if (!isDebuggable) {
21393                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21394                        throw new SecurityException("Process not debuggable: " + proc);
21395                    }
21396                }
21397
21398                proc.thread.dumpHeap(managed, path, fd);
21399                fd = null;
21400                return true;
21401            }
21402        } catch (RemoteException e) {
21403            throw new IllegalStateException("Process disappeared");
21404        } finally {
21405            if (fd != null) {
21406                try {
21407                    fd.close();
21408                } catch (IOException e) {
21409                }
21410            }
21411        }
21412    }
21413
21414    @Override
21415    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21416            String reportPackage) {
21417        if (processName != null) {
21418            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21419                    "setDumpHeapDebugLimit()");
21420        } else {
21421            synchronized (mPidsSelfLocked) {
21422                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21423                if (proc == null) {
21424                    throw new SecurityException("No process found for calling pid "
21425                            + Binder.getCallingPid());
21426                }
21427                if (!Build.IS_DEBUGGABLE
21428                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21429                    throw new SecurityException("Not running a debuggable build");
21430                }
21431                processName = proc.processName;
21432                uid = proc.uid;
21433                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21434                    throw new SecurityException("Package " + reportPackage + " is not running in "
21435                            + proc);
21436                }
21437            }
21438        }
21439        synchronized (this) {
21440            if (maxMemSize > 0) {
21441                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21442            } else {
21443                if (uid != 0) {
21444                    mMemWatchProcesses.remove(processName, uid);
21445                } else {
21446                    mMemWatchProcesses.getMap().remove(processName);
21447                }
21448            }
21449        }
21450    }
21451
21452    @Override
21453    public void dumpHeapFinished(String path) {
21454        synchronized (this) {
21455            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21456                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21457                        + " does not match last pid " + mMemWatchDumpPid);
21458                return;
21459            }
21460            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21461                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21462                        + " does not match last path " + mMemWatchDumpFile);
21463                return;
21464            }
21465            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21466            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21467        }
21468    }
21469
21470    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21471    public void monitor() {
21472        synchronized (this) { }
21473    }
21474
21475    void onCoreSettingsChange(Bundle settings) {
21476        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21477            ProcessRecord processRecord = mLruProcesses.get(i);
21478            try {
21479                if (processRecord.thread != null) {
21480                    processRecord.thread.setCoreSettings(settings);
21481                }
21482            } catch (RemoteException re) {
21483                /* ignore */
21484            }
21485        }
21486    }
21487
21488    // Multi-user methods
21489
21490    /**
21491     * Start user, if its not already running, but don't bring it to foreground.
21492     */
21493    @Override
21494    public boolean startUserInBackground(final int userId) {
21495        return mUserController.startUser(userId, /* foreground */ false);
21496    }
21497
21498    @Override
21499    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21500        return mUserController.unlockUser(userId, token, secret, listener);
21501    }
21502
21503    @Override
21504    public boolean switchUser(final int targetUserId) {
21505        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21506        UserInfo currentUserInfo;
21507        UserInfo targetUserInfo;
21508        synchronized (this) {
21509            int currentUserId = mUserController.getCurrentUserIdLocked();
21510            currentUserInfo = mUserController.getUserInfo(currentUserId);
21511            targetUserInfo = mUserController.getUserInfo(targetUserId);
21512            if (targetUserInfo == null) {
21513                Slog.w(TAG, "No user info for user #" + targetUserId);
21514                return false;
21515            }
21516            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21517                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21518                        + " when device is in demo mode");
21519                return false;
21520            }
21521            if (!targetUserInfo.supportsSwitchTo()) {
21522                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21523                return false;
21524            }
21525            if (targetUserInfo.isManagedProfile()) {
21526                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21527                return false;
21528            }
21529            mUserController.setTargetUserIdLocked(targetUserId);
21530        }
21531        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21532        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21533        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21534        return true;
21535    }
21536
21537    void scheduleStartProfilesLocked() {
21538        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21539            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21540                    DateUtils.SECOND_IN_MILLIS);
21541        }
21542    }
21543
21544    @Override
21545    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21546        return mUserController.stopUser(userId, force, callback);
21547    }
21548
21549    @Override
21550    public UserInfo getCurrentUser() {
21551        return mUserController.getCurrentUser();
21552    }
21553
21554    @Override
21555    public boolean isUserRunning(int userId, int flags) {
21556        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21557                && checkCallingPermission(INTERACT_ACROSS_USERS)
21558                    != PackageManager.PERMISSION_GRANTED) {
21559            String msg = "Permission Denial: isUserRunning() from pid="
21560                    + Binder.getCallingPid()
21561                    + ", uid=" + Binder.getCallingUid()
21562                    + " requires " + INTERACT_ACROSS_USERS;
21563            Slog.w(TAG, msg);
21564            throw new SecurityException(msg);
21565        }
21566        synchronized (this) {
21567            return mUserController.isUserRunningLocked(userId, flags);
21568        }
21569    }
21570
21571    @Override
21572    public int[] getRunningUserIds() {
21573        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21574                != PackageManager.PERMISSION_GRANTED) {
21575            String msg = "Permission Denial: isUserRunning() from pid="
21576                    + Binder.getCallingPid()
21577                    + ", uid=" + Binder.getCallingUid()
21578                    + " requires " + INTERACT_ACROSS_USERS;
21579            Slog.w(TAG, msg);
21580            throw new SecurityException(msg);
21581        }
21582        synchronized (this) {
21583            return mUserController.getStartedUserArrayLocked();
21584        }
21585    }
21586
21587    @Override
21588    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21589        mUserController.registerUserSwitchObserver(observer, name);
21590    }
21591
21592    @Override
21593    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21594        mUserController.unregisterUserSwitchObserver(observer);
21595    }
21596
21597    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21598        if (info == null) return null;
21599        ApplicationInfo newInfo = new ApplicationInfo(info);
21600        newInfo.initForUser(userId);
21601        return newInfo;
21602    }
21603
21604    public boolean isUserStopped(int userId) {
21605        synchronized (this) {
21606            return mUserController.getStartedUserStateLocked(userId) == null;
21607        }
21608    }
21609
21610    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21611        if (aInfo == null
21612                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21613            return aInfo;
21614        }
21615
21616        ActivityInfo info = new ActivityInfo(aInfo);
21617        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21618        return info;
21619    }
21620
21621    private boolean processSanityChecksLocked(ProcessRecord process) {
21622        if (process == null || process.thread == null) {
21623            return false;
21624        }
21625
21626        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21627        if (!isDebuggable) {
21628            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21629                return false;
21630            }
21631        }
21632
21633        return true;
21634    }
21635
21636    public boolean startBinderTracking() throws RemoteException {
21637        synchronized (this) {
21638            mBinderTransactionTrackingEnabled = true;
21639            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21640            // permission (same as profileControl).
21641            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21642                    != PackageManager.PERMISSION_GRANTED) {
21643                throw new SecurityException("Requires permission "
21644                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21645            }
21646
21647            for (int i = 0; i < mLruProcesses.size(); i++) {
21648                ProcessRecord process = mLruProcesses.get(i);
21649                if (!processSanityChecksLocked(process)) {
21650                    continue;
21651                }
21652                try {
21653                    process.thread.startBinderTracking();
21654                } catch (RemoteException e) {
21655                    Log.v(TAG, "Process disappared");
21656                }
21657            }
21658            return true;
21659        }
21660    }
21661
21662    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21663        try {
21664            synchronized (this) {
21665                mBinderTransactionTrackingEnabled = false;
21666                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21667                // permission (same as profileControl).
21668                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21669                        != PackageManager.PERMISSION_GRANTED) {
21670                    throw new SecurityException("Requires permission "
21671                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21672                }
21673
21674                if (fd == null) {
21675                    throw new IllegalArgumentException("null fd");
21676                }
21677
21678                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21679                pw.println("Binder transaction traces for all processes.\n");
21680                for (ProcessRecord process : mLruProcesses) {
21681                    if (!processSanityChecksLocked(process)) {
21682                        continue;
21683                    }
21684
21685                    pw.println("Traces for process: " + process.processName);
21686                    pw.flush();
21687                    try {
21688                        TransferPipe tp = new TransferPipe();
21689                        try {
21690                            process.thread.stopBinderTrackingAndDump(
21691                                    tp.getWriteFd().getFileDescriptor());
21692                            tp.go(fd.getFileDescriptor());
21693                        } finally {
21694                            tp.kill();
21695                        }
21696                    } catch (IOException e) {
21697                        pw.println("Failure while dumping IPC traces from " + process +
21698                                ".  Exception: " + e);
21699                        pw.flush();
21700                    } catch (RemoteException e) {
21701                        pw.println("Got a RemoteException while dumping IPC traces from " +
21702                                process + ".  Exception: " + e);
21703                        pw.flush();
21704                    }
21705                }
21706                fd = null;
21707                return true;
21708            }
21709        } finally {
21710            if (fd != null) {
21711                try {
21712                    fd.close();
21713                } catch (IOException e) {
21714                }
21715            }
21716        }
21717    }
21718
21719    private final class LocalService extends ActivityManagerInternal {
21720        @Override
21721        public void onWakefulnessChanged(int wakefulness) {
21722            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21723        }
21724
21725        @Override
21726        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21727                String processName, String abiOverride, int uid, Runnable crashHandler) {
21728            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21729                    processName, abiOverride, uid, crashHandler);
21730        }
21731
21732        @Override
21733        public SleepToken acquireSleepToken(String tag) {
21734            Preconditions.checkNotNull(tag);
21735
21736            ComponentName requestedVrService = null;
21737            ComponentName callingVrActivity = null;
21738            int userId = -1;
21739            synchronized (ActivityManagerService.this) {
21740                if (mFocusedActivity != null) {
21741                    requestedVrService = mFocusedActivity.requestedVrComponent;
21742                    callingVrActivity = mFocusedActivity.info.getComponentName();
21743                    userId = mFocusedActivity.userId;
21744                }
21745            }
21746
21747            if (requestedVrService != null) {
21748                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21749            }
21750
21751            synchronized (ActivityManagerService.this) {
21752                SleepTokenImpl token = new SleepTokenImpl(tag);
21753                mSleepTokens.add(token);
21754                updateSleepIfNeededLocked();
21755                return token;
21756            }
21757        }
21758
21759        @Override
21760        public ComponentName getHomeActivityForUser(int userId) {
21761            synchronized (ActivityManagerService.this) {
21762                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21763                return homeActivity == null ? null : homeActivity.realActivity;
21764            }
21765        }
21766
21767        @Override
21768        public void onUserRemoved(int userId) {
21769            synchronized (ActivityManagerService.this) {
21770                ActivityManagerService.this.onUserStoppedLocked(userId);
21771            }
21772        }
21773
21774        @Override
21775        public void onLocalVoiceInteractionStarted(IBinder activity,
21776                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21777            synchronized (ActivityManagerService.this) {
21778                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21779                        voiceSession, voiceInteractor);
21780            }
21781        }
21782
21783        @Override
21784        public void notifyStartingWindowDrawn() {
21785            synchronized (ActivityManagerService.this) {
21786                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21787            }
21788        }
21789
21790        @Override
21791        public void notifyAppTransitionStarting(int reason) {
21792            synchronized (ActivityManagerService.this) {
21793                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21794            }
21795        }
21796
21797        @Override
21798        public void notifyAppTransitionFinished() {
21799            synchronized (ActivityManagerService.this) {
21800                mStackSupervisor.notifyAppTransitionDone();
21801            }
21802        }
21803
21804        @Override
21805        public void notifyAppTransitionCancelled() {
21806            synchronized (ActivityManagerService.this) {
21807                mStackSupervisor.notifyAppTransitionDone();
21808            }
21809        }
21810
21811        @Override
21812        public List<IBinder> getTopVisibleActivities() {
21813            synchronized (ActivityManagerService.this) {
21814                return mStackSupervisor.getTopVisibleActivities();
21815            }
21816        }
21817
21818        @Override
21819        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21820            synchronized (ActivityManagerService.this) {
21821                mStackSupervisor.setDockedStackMinimized(minimized);
21822            }
21823        }
21824
21825        @Override
21826        public void killForegroundAppsForUser(int userHandle) {
21827            synchronized (ActivityManagerService.this) {
21828                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21829                final int NP = mProcessNames.getMap().size();
21830                for (int ip = 0; ip < NP; ip++) {
21831                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21832                    final int NA = apps.size();
21833                    for (int ia = 0; ia < NA; ia++) {
21834                        final ProcessRecord app = apps.valueAt(ia);
21835                        if (app.persistent) {
21836                            // We don't kill persistent processes.
21837                            continue;
21838                        }
21839                        if (app.removed) {
21840                            procs.add(app);
21841                        } else if (app.userId == userHandle && app.foregroundActivities) {
21842                            app.removed = true;
21843                            procs.add(app);
21844                        }
21845                    }
21846                }
21847
21848                final int N = procs.size();
21849                for (int i = 0; i < N; i++) {
21850                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21851                }
21852            }
21853        }
21854
21855        @Override
21856        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21857            if (!(target instanceof PendingIntentRecord)) {
21858                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21859                return;
21860            }
21861            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21862        }
21863
21864        @Override
21865        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21866                int userId) {
21867            Preconditions.checkNotNull(values, "Configuration must not be null");
21868            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21869            synchronized (ActivityManagerService.this) {
21870                updateConfigurationLocked(values, null, false, true, userId,
21871                        false /* deferResume */);
21872            }
21873        }
21874
21875        @Override
21876        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
21877                Bundle bOptions) {
21878            Preconditions.checkNotNull(intents, "intents");
21879            final String[] resolvedTypes = new String[intents.length];
21880            for (int i = 0; i < intents.length; i++) {
21881                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
21882            }
21883
21884            // UID of the package on user userId.
21885            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21886            // packageUid may not be initialized.
21887            int packageUid = 0;
21888            try {
21889                packageUid = AppGlobals.getPackageManager().getPackageUid(
21890                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21891            } catch (RemoteException e) {
21892                // Shouldn't happen.
21893            }
21894
21895            synchronized (ActivityManagerService.this) {
21896                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
21897                        /*resultTo*/ null, bOptions, userId);
21898            }
21899        }
21900    }
21901
21902    private final class SleepTokenImpl extends SleepToken {
21903        private final String mTag;
21904        private final long mAcquireTime;
21905
21906        public SleepTokenImpl(String tag) {
21907            mTag = tag;
21908            mAcquireTime = SystemClock.uptimeMillis();
21909        }
21910
21911        @Override
21912        public void release() {
21913            synchronized (ActivityManagerService.this) {
21914                if (mSleepTokens.remove(this)) {
21915                    updateSleepIfNeededLocked();
21916                }
21917            }
21918        }
21919
21920        @Override
21921        public String toString() {
21922            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21923        }
21924    }
21925
21926    /**
21927     * An implementation of IAppTask, that allows an app to manage its own tasks via
21928     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21929     * only the process that calls getAppTasks() can call the AppTask methods.
21930     */
21931    class AppTaskImpl extends IAppTask.Stub {
21932        private int mTaskId;
21933        private int mCallingUid;
21934
21935        public AppTaskImpl(int taskId, int callingUid) {
21936            mTaskId = taskId;
21937            mCallingUid = callingUid;
21938        }
21939
21940        private void checkCaller() {
21941            if (mCallingUid != Binder.getCallingUid()) {
21942                throw new SecurityException("Caller " + mCallingUid
21943                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21944            }
21945        }
21946
21947        @Override
21948        public void finishAndRemoveTask() {
21949            checkCaller();
21950
21951            synchronized (ActivityManagerService.this) {
21952                long origId = Binder.clearCallingIdentity();
21953                try {
21954                    // We remove the task from recents to preserve backwards
21955                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21956                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21957                    }
21958                } finally {
21959                    Binder.restoreCallingIdentity(origId);
21960                }
21961            }
21962        }
21963
21964        @Override
21965        public ActivityManager.RecentTaskInfo getTaskInfo() {
21966            checkCaller();
21967
21968            synchronized (ActivityManagerService.this) {
21969                long origId = Binder.clearCallingIdentity();
21970                try {
21971                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21972                    if (tr == null) {
21973                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21974                    }
21975                    return createRecentTaskInfoFromTaskRecord(tr);
21976                } finally {
21977                    Binder.restoreCallingIdentity(origId);
21978                }
21979            }
21980        }
21981
21982        @Override
21983        public void moveToFront() {
21984            checkCaller();
21985            // Will bring task to front if it already has a root activity.
21986            final long origId = Binder.clearCallingIdentity();
21987            try {
21988                synchronized (this) {
21989                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21990                }
21991            } finally {
21992                Binder.restoreCallingIdentity(origId);
21993            }
21994        }
21995
21996        @Override
21997        public int startActivity(IBinder whoThread, String callingPackage,
21998                Intent intent, String resolvedType, Bundle bOptions) {
21999            checkCaller();
22000
22001            int callingUser = UserHandle.getCallingUserId();
22002            TaskRecord tr;
22003            IApplicationThread appThread;
22004            synchronized (ActivityManagerService.this) {
22005                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22006                if (tr == null) {
22007                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22008                }
22009                appThread = ApplicationThreadNative.asInterface(whoThread);
22010                if (appThread == null) {
22011                    throw new IllegalArgumentException("Bad app thread " + appThread);
22012                }
22013            }
22014            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22015                    resolvedType, null, null, null, null, 0, 0, null, null,
22016                    null, bOptions, false, callingUser, null, tr);
22017        }
22018
22019        @Override
22020        public void setExcludeFromRecents(boolean exclude) {
22021            checkCaller();
22022
22023            synchronized (ActivityManagerService.this) {
22024                long origId = Binder.clearCallingIdentity();
22025                try {
22026                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22027                    if (tr == null) {
22028                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22029                    }
22030                    Intent intent = tr.getBaseIntent();
22031                    if (exclude) {
22032                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22033                    } else {
22034                        intent.setFlags(intent.getFlags()
22035                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22036                    }
22037                } finally {
22038                    Binder.restoreCallingIdentity(origId);
22039                }
22040            }
22041        }
22042    }
22043
22044    /**
22045     * Kill processes for the user with id userId and that depend on the package named packageName
22046     */
22047    @Override
22048    public void killPackageDependents(String packageName, int userId) {
22049        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22050        if (packageName == null) {
22051            throw new NullPointerException(
22052                    "Cannot kill the dependents of a package without its name.");
22053        }
22054
22055        long callingId = Binder.clearCallingIdentity();
22056        IPackageManager pm = AppGlobals.getPackageManager();
22057        int pkgUid = -1;
22058        try {
22059            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22060        } catch (RemoteException e) {
22061        }
22062        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22063            throw new IllegalArgumentException(
22064                    "Cannot kill dependents of non-existing package " + packageName);
22065        }
22066        try {
22067            synchronized(this) {
22068                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22069                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22070                        "dep: " + packageName);
22071            }
22072        } finally {
22073            Binder.restoreCallingIdentity(callingId);
22074        }
22075    }
22076}
22077