ActivityManagerService.java revision 7853ba63cd8b0d79a7bd99ca91035399ac00d73f
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            if (app.isolated) {
3784                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3785            }
3786            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3787            checkTime(startTime, "startProcess: done updating battery stats");
3788
3789            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3790                    UserHandle.getUserId(uid), startResult.pid, uid,
3791                    app.processName, hostingType,
3792                    hostingNameStr != null ? hostingNameStr : "");
3793
3794            try {
3795                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3796                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3797            } catch (RemoteException ex) {
3798                // Ignore
3799            }
3800
3801            if (app.persistent) {
3802                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3803            }
3804
3805            checkTime(startTime, "startProcess: building log message");
3806            StringBuilder buf = mStringBuilder;
3807            buf.setLength(0);
3808            buf.append("Start proc ");
3809            buf.append(startResult.pid);
3810            buf.append(':');
3811            buf.append(app.processName);
3812            buf.append('/');
3813            UserHandle.formatUid(buf, uid);
3814            if (!isActivityProcess) {
3815                buf.append(" [");
3816                buf.append(entryPoint);
3817                buf.append("]");
3818            }
3819            buf.append(" for ");
3820            buf.append(hostingType);
3821            if (hostingNameStr != null) {
3822                buf.append(" ");
3823                buf.append(hostingNameStr);
3824            }
3825            Slog.i(TAG, buf.toString());
3826            app.setPid(startResult.pid);
3827            app.usingWrapper = startResult.usingWrapper;
3828            app.removed = false;
3829            app.killed = false;
3830            app.killedByAm = false;
3831            checkTime(startTime, "startProcess: starting to update pids map");
3832            synchronized (mPidsSelfLocked) {
3833                this.mPidsSelfLocked.put(startResult.pid, app);
3834                if (isActivityProcess) {
3835                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3836                    msg.obj = app;
3837                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3838                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3839                }
3840            }
3841            checkTime(startTime, "startProcess: done updating pids map");
3842        } catch (RuntimeException e) {
3843            Slog.e(TAG, "Failure starting process " + app.processName, e);
3844
3845            // Something went very wrong while trying to start this process; one
3846            // common case is when the package is frozen due to an active
3847            // upgrade. To recover, clean up any active bookkeeping related to
3848            // starting this process. (We already invoked this method once when
3849            // the package was initially frozen through KILL_APPLICATION_MSG, so
3850            // it doesn't hurt to use it again.)
3851            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3852                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3853        }
3854    }
3855
3856    void updateUsageStats(ActivityRecord component, boolean resumed) {
3857        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3858                "updateUsageStats: comp=" + component + "res=" + resumed);
3859        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3860        if (resumed) {
3861            if (mUsageStatsService != null) {
3862                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3863                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3864            }
3865            synchronized (stats) {
3866                stats.noteActivityResumedLocked(component.app.uid);
3867            }
3868        } else {
3869            if (mUsageStatsService != null) {
3870                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3871                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3872            }
3873            synchronized (stats) {
3874                stats.noteActivityPausedLocked(component.app.uid);
3875            }
3876        }
3877    }
3878
3879    Intent getHomeIntent() {
3880        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3881        intent.setComponent(mTopComponent);
3882        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3883        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3884            intent.addCategory(Intent.CATEGORY_HOME);
3885        }
3886        return intent;
3887    }
3888
3889    boolean startHomeActivityLocked(int userId, String reason) {
3890        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3891                && mTopAction == null) {
3892            // We are running in factory test mode, but unable to find
3893            // the factory test app, so just sit around displaying the
3894            // error message and don't try to start anything.
3895            return false;
3896        }
3897        Intent intent = getHomeIntent();
3898        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3899        if (aInfo != null) {
3900            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3901            // Don't do this if the home app is currently being
3902            // instrumented.
3903            aInfo = new ActivityInfo(aInfo);
3904            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3905            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3906                    aInfo.applicationInfo.uid, true);
3907            if (app == null || app.instrumentationClass == null) {
3908                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3909                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3910            }
3911        } else {
3912            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3913        }
3914
3915        return true;
3916    }
3917
3918    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3919        ActivityInfo ai = null;
3920        ComponentName comp = intent.getComponent();
3921        try {
3922            if (comp != null) {
3923                // Factory test.
3924                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3925            } else {
3926                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3927                        intent,
3928                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3929                        flags, userId);
3930
3931                if (info != null) {
3932                    ai = info.activityInfo;
3933                }
3934            }
3935        } catch (RemoteException e) {
3936            // ignore
3937        }
3938
3939        return ai;
3940    }
3941
3942    /**
3943     * Starts the "new version setup screen" if appropriate.
3944     */
3945    void startSetupActivityLocked() {
3946        // Only do this once per boot.
3947        if (mCheckedForSetup) {
3948            return;
3949        }
3950
3951        // We will show this screen if the current one is a different
3952        // version than the last one shown, and we are not running in
3953        // low-level factory test mode.
3954        final ContentResolver resolver = mContext.getContentResolver();
3955        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3956                Settings.Global.getInt(resolver,
3957                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3958            mCheckedForSetup = true;
3959
3960            // See if we should be showing the platform update setup UI.
3961            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3962            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3963                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3964            if (!ris.isEmpty()) {
3965                final ResolveInfo ri = ris.get(0);
3966                String vers = ri.activityInfo.metaData != null
3967                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3968                        : null;
3969                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3970                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3971                            Intent.METADATA_SETUP_VERSION);
3972                }
3973                String lastVers = Settings.Secure.getString(
3974                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3975                if (vers != null && !vers.equals(lastVers)) {
3976                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3977                    intent.setComponent(new ComponentName(
3978                            ri.activityInfo.packageName, ri.activityInfo.name));
3979                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3980                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3981                            null, 0, 0, 0, null, false, false, null, null, null);
3982                }
3983            }
3984        }
3985    }
3986
3987    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3988        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3989    }
3990
3991    void enforceNotIsolatedCaller(String caller) {
3992        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3993            throw new SecurityException("Isolated process not allowed to call " + caller);
3994        }
3995    }
3996
3997    void enforceShellRestriction(String restriction, int userHandle) {
3998        if (Binder.getCallingUid() == Process.SHELL_UID) {
3999            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4000                throw new SecurityException("Shell does not have permission to access user "
4001                        + userHandle);
4002            }
4003        }
4004    }
4005
4006    @Override
4007    public int getFrontActivityScreenCompatMode() {
4008        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4009        synchronized (this) {
4010            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4011        }
4012    }
4013
4014    @Override
4015    public void setFrontActivityScreenCompatMode(int mode) {
4016        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4017                "setFrontActivityScreenCompatMode");
4018        synchronized (this) {
4019            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4020        }
4021    }
4022
4023    @Override
4024    public int getPackageScreenCompatMode(String packageName) {
4025        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4026        synchronized (this) {
4027            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4028        }
4029    }
4030
4031    @Override
4032    public void setPackageScreenCompatMode(String packageName, int mode) {
4033        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4034                "setPackageScreenCompatMode");
4035        synchronized (this) {
4036            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4037        }
4038    }
4039
4040    @Override
4041    public boolean getPackageAskScreenCompat(String packageName) {
4042        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4043        synchronized (this) {
4044            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4045        }
4046    }
4047
4048    @Override
4049    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4050        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4051                "setPackageAskScreenCompat");
4052        synchronized (this) {
4053            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4054        }
4055    }
4056
4057    private boolean hasUsageStatsPermission(String callingPackage) {
4058        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4059                Binder.getCallingUid(), callingPackage);
4060        if (mode == AppOpsManager.MODE_DEFAULT) {
4061            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4062                    == PackageManager.PERMISSION_GRANTED;
4063        }
4064        return mode == AppOpsManager.MODE_ALLOWED;
4065    }
4066
4067    @Override
4068    public int getPackageProcessState(String packageName, String callingPackage) {
4069        if (!hasUsageStatsPermission(callingPackage)) {
4070            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4071                    "getPackageProcessState");
4072        }
4073
4074        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4075        synchronized (this) {
4076            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4077                final ProcessRecord proc = mLruProcesses.get(i);
4078                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4079                        || procState > proc.setProcState) {
4080                    boolean found = false;
4081                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4082                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4083                            procState = proc.setProcState;
4084                            found = true;
4085                        }
4086                    }
4087                    if (proc.pkgDeps != null && !found) {
4088                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4089                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4090                                procState = proc.setProcState;
4091                                break;
4092                            }
4093                        }
4094                    }
4095                }
4096            }
4097        }
4098        return procState;
4099    }
4100
4101    @Override
4102    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4103        synchronized (this) {
4104            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4105            if (app == null) {
4106                return false;
4107            }
4108            if (app.trimMemoryLevel < level && app.thread != null &&
4109                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4110                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4111                try {
4112                    app.thread.scheduleTrimMemory(level);
4113                    app.trimMemoryLevel = level;
4114                    return true;
4115                } catch (RemoteException e) {
4116                    // Fallthrough to failure case.
4117                }
4118            }
4119        }
4120        return false;
4121    }
4122
4123    private void dispatchProcessesChanged() {
4124        int N;
4125        synchronized (this) {
4126            N = mPendingProcessChanges.size();
4127            if (mActiveProcessChanges.length < N) {
4128                mActiveProcessChanges = new ProcessChangeItem[N];
4129            }
4130            mPendingProcessChanges.toArray(mActiveProcessChanges);
4131            mPendingProcessChanges.clear();
4132            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4133                    "*** Delivering " + N + " process changes");
4134        }
4135
4136        int i = mProcessObservers.beginBroadcast();
4137        while (i > 0) {
4138            i--;
4139            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4140            if (observer != null) {
4141                try {
4142                    for (int j=0; j<N; j++) {
4143                        ProcessChangeItem item = mActiveProcessChanges[j];
4144                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4145                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4146                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4147                                    + item.uid + ": " + item.foregroundActivities);
4148                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4149                                    item.foregroundActivities);
4150                        }
4151                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4152                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4153                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4154                                    + ": " + item.processState);
4155                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4156                        }
4157                    }
4158                } catch (RemoteException e) {
4159                }
4160            }
4161        }
4162        mProcessObservers.finishBroadcast();
4163
4164        synchronized (this) {
4165            for (int j=0; j<N; j++) {
4166                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4167            }
4168        }
4169    }
4170
4171    private void dispatchProcessDied(int pid, int uid) {
4172        int i = mProcessObservers.beginBroadcast();
4173        while (i > 0) {
4174            i--;
4175            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4176            if (observer != null) {
4177                try {
4178                    observer.onProcessDied(pid, uid);
4179                } catch (RemoteException e) {
4180                }
4181            }
4182        }
4183        mProcessObservers.finishBroadcast();
4184    }
4185
4186    private void dispatchUidsChanged() {
4187        int N;
4188        synchronized (this) {
4189            N = mPendingUidChanges.size();
4190            if (mActiveUidChanges.length < N) {
4191                mActiveUidChanges = new UidRecord.ChangeItem[N];
4192            }
4193            for (int i=0; i<N; i++) {
4194                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4195                mActiveUidChanges[i] = change;
4196                if (change.uidRecord != null) {
4197                    change.uidRecord.pendingChange = null;
4198                    change.uidRecord = null;
4199                }
4200            }
4201            mPendingUidChanges.clear();
4202            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4203                    "*** Delivering " + N + " uid changes");
4204        }
4205
4206        if (mLocalPowerManager != null) {
4207            for (int j=0; j<N; j++) {
4208                UidRecord.ChangeItem item = mActiveUidChanges[j];
4209                if (item.change == UidRecord.CHANGE_GONE
4210                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4211                    mLocalPowerManager.uidGone(item.uid);
4212                } else {
4213                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4214                }
4215            }
4216        }
4217
4218        int i = mUidObservers.beginBroadcast();
4219        while (i > 0) {
4220            i--;
4221            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4222            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4223            if (observer != null) {
4224                try {
4225                    for (int j=0; j<N; j++) {
4226                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4227                        final int change = item.change;
4228                        UidRecord validateUid = null;
4229                        if (VALIDATE_UID_STATES && i == 0) {
4230                            validateUid = mValidateUids.get(item.uid);
4231                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4232                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4233                                validateUid = new UidRecord(item.uid);
4234                                mValidateUids.put(item.uid, validateUid);
4235                            }
4236                        }
4237                        if (change == UidRecord.CHANGE_IDLE
4238                                || change == UidRecord.CHANGE_GONE_IDLE) {
4239                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4240                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4241                                        "UID idle uid=" + item.uid);
4242                                observer.onUidIdle(item.uid);
4243                            }
4244                            if (VALIDATE_UID_STATES && i == 0) {
4245                                if (validateUid != null) {
4246                                    validateUid.idle = true;
4247                                }
4248                            }
4249                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4250                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4251                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4252                                        "UID active uid=" + item.uid);
4253                                observer.onUidActive(item.uid);
4254                            }
4255                            if (VALIDATE_UID_STATES && i == 0) {
4256                                validateUid.idle = false;
4257                            }
4258                        }
4259                        if (change == UidRecord.CHANGE_GONE
4260                                || change == UidRecord.CHANGE_GONE_IDLE) {
4261                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4262                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4263                                        "UID gone uid=" + item.uid);
4264                                observer.onUidGone(item.uid);
4265                            }
4266                            if (VALIDATE_UID_STATES && i == 0) {
4267                                if (validateUid != null) {
4268                                    mValidateUids.remove(item.uid);
4269                                }
4270                            }
4271                        } else {
4272                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4273                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4274                                        "UID CHANGED uid=" + item.uid
4275                                                + ": " + item.processState);
4276                                observer.onUidStateChanged(item.uid, item.processState);
4277                            }
4278                            if (VALIDATE_UID_STATES && i == 0) {
4279                                validateUid.curProcState = validateUid.setProcState
4280                                        = item.processState;
4281                            }
4282                        }
4283                    }
4284                } catch (RemoteException e) {
4285                }
4286            }
4287        }
4288        mUidObservers.finishBroadcast();
4289
4290        synchronized (this) {
4291            for (int j=0; j<N; j++) {
4292                mAvailUidChanges.add(mActiveUidChanges[j]);
4293            }
4294        }
4295    }
4296
4297    @Override
4298    public final int startActivity(IApplicationThread caller, String callingPackage,
4299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4300            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4301        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4302                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4303                UserHandle.getCallingUserId());
4304    }
4305
4306    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4307        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4308        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4309                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4310                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4311
4312        // TODO: Switch to user app stacks here.
4313        String mimeType = intent.getType();
4314        final Uri data = intent.getData();
4315        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4316            mimeType = getProviderMimeType(data, userId);
4317        }
4318        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4319
4320        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4321        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4322                null, 0, 0, null, null, null, null, false, userId, container, null);
4323    }
4324
4325    @Override
4326    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4327            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4328            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4329        enforceNotIsolatedCaller("startActivity");
4330        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4331                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4332        // TODO: Switch to user app stacks here.
4333        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4334                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4335                profilerInfo, null, null, bOptions, false, userId, null, null);
4336    }
4337
4338    @Override
4339    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4341            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4342            int userId) {
4343
4344        // This is very dangerous -- it allows you to perform a start activity (including
4345        // permission grants) as any app that may launch one of your own activities.  So
4346        // we will only allow this to be done from activities that are part of the core framework,
4347        // and then only when they are running as the system.
4348        final ActivityRecord sourceRecord;
4349        final int targetUid;
4350        final String targetPackage;
4351        synchronized (this) {
4352            if (resultTo == null) {
4353                throw new SecurityException("Must be called from an activity");
4354            }
4355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4356            if (sourceRecord == null) {
4357                throw new SecurityException("Called with bad activity token: " + resultTo);
4358            }
4359            if (!sourceRecord.info.packageName.equals("android")) {
4360                throw new SecurityException(
4361                        "Must be called from an activity that is declared in the android package");
4362            }
4363            if (sourceRecord.app == null) {
4364                throw new SecurityException("Called without a process attached to activity");
4365            }
4366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4367                // This is still okay, as long as this activity is running under the
4368                // uid of the original calling activity.
4369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4370                    throw new SecurityException(
4371                            "Calling activity in uid " + sourceRecord.app.uid
4372                                    + " must be system uid or original calling uid "
4373                                    + sourceRecord.launchedFromUid);
4374                }
4375            }
4376            if (ignoreTargetSecurity) {
4377                if (intent.getComponent() == null) {
4378                    throw new SecurityException(
4379                            "Component must be specified with ignoreTargetSecurity");
4380                }
4381                if (intent.getSelector() != null) {
4382                    throw new SecurityException(
4383                            "Selector not allowed with ignoreTargetSecurity");
4384                }
4385            }
4386            targetUid = sourceRecord.launchedFromUid;
4387            targetPackage = sourceRecord.launchedFromPackage;
4388        }
4389
4390        if (userId == UserHandle.USER_NULL) {
4391            userId = UserHandle.getUserId(sourceRecord.app.uid);
4392        }
4393
4394        // TODO: Switch to user app stacks here.
4395        try {
4396            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4397                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4398                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4399            return ret;
4400        } catch (SecurityException e) {
4401            // XXX need to figure out how to propagate to original app.
4402            // A SecurityException here is generally actually a fault of the original
4403            // calling activity (such as a fairly granting permissions), so propagate it
4404            // back to them.
4405            /*
4406            StringBuilder msg = new StringBuilder();
4407            msg.append("While launching");
4408            msg.append(intent.toString());
4409            msg.append(": ");
4410            msg.append(e.getMessage());
4411            */
4412            throw e;
4413        }
4414    }
4415
4416    @Override
4417    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4418            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4419            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4420        enforceNotIsolatedCaller("startActivityAndWait");
4421        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4422                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4423        WaitResult res = new WaitResult();
4424        // TODO: Switch to user app stacks here.
4425        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4426                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4427                bOptions, false, userId, null, null);
4428        return res;
4429    }
4430
4431    @Override
4432    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4433            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4434            int startFlags, Configuration config, Bundle bOptions, int userId) {
4435        enforceNotIsolatedCaller("startActivityWithConfig");
4436        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4437                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4438        // TODO: Switch to user app stacks here.
4439        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4440                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4441                null, null, config, bOptions, false, userId, null, null);
4442        return ret;
4443    }
4444
4445    @Override
4446    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4447            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4448            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4449            throws TransactionTooLargeException {
4450        enforceNotIsolatedCaller("startActivityIntentSender");
4451        // Refuse possible leaked file descriptors
4452        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4453            throw new IllegalArgumentException("File descriptors passed in Intent");
4454        }
4455
4456        IIntentSender sender = intent.getTarget();
4457        if (!(sender instanceof PendingIntentRecord)) {
4458            throw new IllegalArgumentException("Bad PendingIntent object");
4459        }
4460
4461        PendingIntentRecord pir = (PendingIntentRecord)sender;
4462
4463        synchronized (this) {
4464            // If this is coming from the currently resumed activity, it is
4465            // effectively saying that app switches are allowed at this point.
4466            final ActivityStack stack = getFocusedStack();
4467            if (stack.mResumedActivity != null &&
4468                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4469                mAppSwitchesAllowedTime = 0;
4470            }
4471        }
4472        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4473                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4474        return ret;
4475    }
4476
4477    @Override
4478    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4479            Intent intent, String resolvedType, IVoiceInteractionSession session,
4480            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4481            Bundle bOptions, int userId) {
4482        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4483                != PackageManager.PERMISSION_GRANTED) {
4484            String msg = "Permission Denial: startVoiceActivity() from pid="
4485                    + Binder.getCallingPid()
4486                    + ", uid=" + Binder.getCallingUid()
4487                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4488            Slog.w(TAG, msg);
4489            throw new SecurityException(msg);
4490        }
4491        if (session == null || interactor == null) {
4492            throw new NullPointerException("null session or interactor");
4493        }
4494        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4495                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4496        // TODO: Switch to user app stacks here.
4497        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4498                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4499                null, bOptions, false, userId, null, null);
4500    }
4501
4502    @Override
4503    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4504            throws RemoteException {
4505        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4506        synchronized (this) {
4507            ActivityRecord activity = getFocusedStack().topActivity();
4508            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4509                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4510            }
4511            if (mRunningVoice != null || activity.task.voiceSession != null
4512                    || activity.voiceSession != null) {
4513                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4514                return;
4515            }
4516            if (activity.pendingVoiceInteractionStart) {
4517                Slog.w(TAG, "Pending start of voice interaction already.");
4518                return;
4519            }
4520            activity.pendingVoiceInteractionStart = true;
4521        }
4522        LocalServices.getService(VoiceInteractionManagerInternal.class)
4523                .startLocalVoiceInteraction(callingActivity, options);
4524    }
4525
4526    @Override
4527    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4528        LocalServices.getService(VoiceInteractionManagerInternal.class)
4529                .stopLocalVoiceInteraction(callingActivity);
4530    }
4531
4532    @Override
4533    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4534        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4535                .supportsLocalVoiceInteraction();
4536    }
4537
4538    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4539            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4540        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4541        if (activityToCallback == null) return;
4542        activityToCallback.setVoiceSessionLocked(voiceSession);
4543
4544        // Inform the activity
4545        try {
4546            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4547                    voiceInteractor);
4548            long token = Binder.clearCallingIdentity();
4549            try {
4550                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4551            } finally {
4552                Binder.restoreCallingIdentity(token);
4553            }
4554            // TODO: VI Should we cache the activity so that it's easier to find later
4555            // rather than scan through all the stacks and activities?
4556        } catch (RemoteException re) {
4557            activityToCallback.clearVoiceSessionLocked();
4558            // TODO: VI Should this terminate the voice session?
4559        }
4560    }
4561
4562    @Override
4563    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4564        synchronized (this) {
4565            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4566                if (keepAwake) {
4567                    mVoiceWakeLock.acquire();
4568                } else {
4569                    mVoiceWakeLock.release();
4570                }
4571            }
4572        }
4573    }
4574
4575    @Override
4576    public boolean startNextMatchingActivity(IBinder callingActivity,
4577            Intent intent, Bundle bOptions) {
4578        // Refuse possible leaked file descriptors
4579        if (intent != null && intent.hasFileDescriptors() == true) {
4580            throw new IllegalArgumentException("File descriptors passed in Intent");
4581        }
4582        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4583
4584        synchronized (this) {
4585            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4586            if (r == null) {
4587                ActivityOptions.abort(options);
4588                return false;
4589            }
4590            if (r.app == null || r.app.thread == null) {
4591                // The caller is not running...  d'oh!
4592                ActivityOptions.abort(options);
4593                return false;
4594            }
4595            intent = new Intent(intent);
4596            // The caller is not allowed to change the data.
4597            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4598            // And we are resetting to find the next component...
4599            intent.setComponent(null);
4600
4601            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4602
4603            ActivityInfo aInfo = null;
4604            try {
4605                List<ResolveInfo> resolves =
4606                    AppGlobals.getPackageManager().queryIntentActivities(
4607                            intent, r.resolvedType,
4608                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4609                            UserHandle.getCallingUserId()).getList();
4610
4611                // Look for the original activity in the list...
4612                final int N = resolves != null ? resolves.size() : 0;
4613                for (int i=0; i<N; i++) {
4614                    ResolveInfo rInfo = resolves.get(i);
4615                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4616                            && rInfo.activityInfo.name.equals(r.info.name)) {
4617                        // We found the current one...  the next matching is
4618                        // after it.
4619                        i++;
4620                        if (i<N) {
4621                            aInfo = resolves.get(i).activityInfo;
4622                        }
4623                        if (debug) {
4624                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4625                                    + "/" + r.info.name);
4626                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4627                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4628                        }
4629                        break;
4630                    }
4631                }
4632            } catch (RemoteException e) {
4633            }
4634
4635            if (aInfo == null) {
4636                // Nobody who is next!
4637                ActivityOptions.abort(options);
4638                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4639                return false;
4640            }
4641
4642            intent.setComponent(new ComponentName(
4643                    aInfo.applicationInfo.packageName, aInfo.name));
4644            intent.setFlags(intent.getFlags()&~(
4645                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4646                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4647                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4648                    Intent.FLAG_ACTIVITY_NEW_TASK));
4649
4650            // Okay now we need to start the new activity, replacing the
4651            // currently running activity.  This is a little tricky because
4652            // we want to start the new one as if the current one is finished,
4653            // but not finish the current one first so that there is no flicker.
4654            // And thus...
4655            final boolean wasFinishing = r.finishing;
4656            r.finishing = true;
4657
4658            // Propagate reply information over to the new activity.
4659            final ActivityRecord resultTo = r.resultTo;
4660            final String resultWho = r.resultWho;
4661            final int requestCode = r.requestCode;
4662            r.resultTo = null;
4663            if (resultTo != null) {
4664                resultTo.removeResultsLocked(r, resultWho, requestCode);
4665            }
4666
4667            final long origId = Binder.clearCallingIdentity();
4668            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4669                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4670                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4671                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4672                    false, false, null, null, null);
4673            Binder.restoreCallingIdentity(origId);
4674
4675            r.finishing = wasFinishing;
4676            if (res != ActivityManager.START_SUCCESS) {
4677                return false;
4678            }
4679            return true;
4680        }
4681    }
4682
4683    @Override
4684    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4685        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4686            String msg = "Permission Denial: startActivityFromRecents called without " +
4687                    START_TASKS_FROM_RECENTS;
4688            Slog.w(TAG, msg);
4689            throw new SecurityException(msg);
4690        }
4691        final long origId = Binder.clearCallingIdentity();
4692        try {
4693            synchronized (this) {
4694                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4695            }
4696        } finally {
4697            Binder.restoreCallingIdentity(origId);
4698        }
4699    }
4700
4701    final int startActivityInPackage(int uid, String callingPackage,
4702            Intent intent, String resolvedType, IBinder resultTo,
4703            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4704            IActivityContainer container, TaskRecord inTask) {
4705
4706        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4707                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4708
4709        // TODO: Switch to user app stacks here.
4710        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4711                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4712                null, null, null, bOptions, false, userId, container, inTask);
4713        return ret;
4714    }
4715
4716    @Override
4717    public final int startActivities(IApplicationThread caller, String callingPackage,
4718            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4719            int userId) {
4720        enforceNotIsolatedCaller("startActivities");
4721        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4722                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4723        // TODO: Switch to user app stacks here.
4724        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4725                resolvedTypes, resultTo, bOptions, userId);
4726        return ret;
4727    }
4728
4729    final int startActivitiesInPackage(int uid, String callingPackage,
4730            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4731            Bundle bOptions, int userId) {
4732
4733        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4734                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4735        // TODO: Switch to user app stacks here.
4736        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4737                resultTo, bOptions, userId);
4738        return ret;
4739    }
4740
4741    @Override
4742    public void reportActivityFullyDrawn(IBinder token) {
4743        synchronized (this) {
4744            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4745            if (r == null) {
4746                return;
4747            }
4748            r.reportFullyDrawnLocked();
4749        }
4750    }
4751
4752    @Override
4753    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4754        synchronized (this) {
4755            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4756            if (r == null) {
4757                return;
4758            }
4759            TaskRecord task = r.task;
4760            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4761                // Fixed screen orientation isn't supported when activities aren't in full screen
4762                // mode.
4763                return;
4764            }
4765            final long origId = Binder.clearCallingIdentity();
4766            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4767            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4768                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4769            if (config != null) {
4770                r.frozenBeforeDestroy = true;
4771                if (!updateConfigurationLocked(config, r, false)) {
4772                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4773                }
4774            }
4775            Binder.restoreCallingIdentity(origId);
4776        }
4777    }
4778
4779    @Override
4780    public int getRequestedOrientation(IBinder token) {
4781        synchronized (this) {
4782            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4783            if (r == null) {
4784                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4785            }
4786            return mWindowManager.getAppOrientation(r.appToken);
4787        }
4788    }
4789
4790    /**
4791     * This is the internal entry point for handling Activity.finish().
4792     *
4793     * @param token The Binder token referencing the Activity we want to finish.
4794     * @param resultCode Result code, if any, from this Activity.
4795     * @param resultData Result data (Intent), if any, from this Activity.
4796     * @param finishTask Whether to finish the task associated with this Activity.
4797     *
4798     * @return Returns true if the activity successfully finished, or false if it is still running.
4799     */
4800    @Override
4801    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4802            int finishTask) {
4803        // Refuse possible leaked file descriptors
4804        if (resultData != null && resultData.hasFileDescriptors() == true) {
4805            throw new IllegalArgumentException("File descriptors passed in Intent");
4806        }
4807
4808        synchronized(this) {
4809            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4810            if (r == null) {
4811                return true;
4812            }
4813            // Keep track of the root activity of the task before we finish it
4814            TaskRecord tr = r.task;
4815            ActivityRecord rootR = tr.getRootActivity();
4816            if (rootR == null) {
4817                Slog.w(TAG, "Finishing task with all activities already finished");
4818            }
4819            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4820            // finish.
4821            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4822                    mStackSupervisor.isLastLockedTask(tr)) {
4823                Slog.i(TAG, "Not finishing task in lock task mode");
4824                mStackSupervisor.showLockTaskToast();
4825                return false;
4826            }
4827            if (mController != null) {
4828                // Find the first activity that is not finishing.
4829                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4830                if (next != null) {
4831                    // ask watcher if this is allowed
4832                    boolean resumeOK = true;
4833                    try {
4834                        resumeOK = mController.activityResuming(next.packageName);
4835                    } catch (RemoteException e) {
4836                        mController = null;
4837                        Watchdog.getInstance().setActivityController(null);
4838                    }
4839
4840                    if (!resumeOK) {
4841                        Slog.i(TAG, "Not finishing activity because controller resumed");
4842                        return false;
4843                    }
4844                }
4845            }
4846            final long origId = Binder.clearCallingIdentity();
4847            try {
4848                boolean res;
4849                final boolean finishWithRootActivity =
4850                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4851                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4852                        || (finishWithRootActivity && r == rootR)) {
4853                    // If requested, remove the task that is associated to this activity only if it
4854                    // was the root activity in the task. The result code and data is ignored
4855                    // because we don't support returning them across task boundaries. Also, to
4856                    // keep backwards compatibility we remove the task from recents when finishing
4857                    // task with root activity.
4858                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4859                    if (!res) {
4860                        Slog.i(TAG, "Removing task failed to finish activity");
4861                    }
4862                } else {
4863                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4864                            resultData, "app-request", true);
4865                    if (!res) {
4866                        Slog.i(TAG, "Failed to finish by app-request");
4867                    }
4868                }
4869                return res;
4870            } finally {
4871                Binder.restoreCallingIdentity(origId);
4872            }
4873        }
4874    }
4875
4876    @Override
4877    public final void finishHeavyWeightApp() {
4878        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4879                != PackageManager.PERMISSION_GRANTED) {
4880            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4881                    + Binder.getCallingPid()
4882                    + ", uid=" + Binder.getCallingUid()
4883                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4884            Slog.w(TAG, msg);
4885            throw new SecurityException(msg);
4886        }
4887
4888        synchronized(this) {
4889            if (mHeavyWeightProcess == null) {
4890                return;
4891            }
4892
4893            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4894            for (int i = 0; i < activities.size(); i++) {
4895                ActivityRecord r = activities.get(i);
4896                if (!r.finishing && r.isInStackLocked()) {
4897                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4898                            null, "finish-heavy", true);
4899                }
4900            }
4901
4902            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4903                    mHeavyWeightProcess.userId, 0));
4904            mHeavyWeightProcess = null;
4905        }
4906    }
4907
4908    @Override
4909    public void crashApplication(int uid, int initialPid, String packageName,
4910            String message) {
4911        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4912                != PackageManager.PERMISSION_GRANTED) {
4913            String msg = "Permission Denial: crashApplication() from pid="
4914                    + Binder.getCallingPid()
4915                    + ", uid=" + Binder.getCallingUid()
4916                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4917            Slog.w(TAG, msg);
4918            throw new SecurityException(msg);
4919        }
4920
4921        synchronized(this) {
4922            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4923        }
4924    }
4925
4926    @Override
4927    public final void finishSubActivity(IBinder token, String resultWho,
4928            int requestCode) {
4929        synchronized(this) {
4930            final long origId = Binder.clearCallingIdentity();
4931            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4932            if (r != null) {
4933                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4934            }
4935            Binder.restoreCallingIdentity(origId);
4936        }
4937    }
4938
4939    @Override
4940    public boolean finishActivityAffinity(IBinder token) {
4941        synchronized(this) {
4942            final long origId = Binder.clearCallingIdentity();
4943            try {
4944                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945                if (r == null) {
4946                    return false;
4947                }
4948
4949                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4950                // can finish.
4951                final TaskRecord task = r.task;
4952                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4953                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4954                    mStackSupervisor.showLockTaskToast();
4955                    return false;
4956                }
4957                return task.stack.finishActivityAffinityLocked(r);
4958            } finally {
4959                Binder.restoreCallingIdentity(origId);
4960            }
4961        }
4962    }
4963
4964    @Override
4965    public void finishVoiceTask(IVoiceInteractionSession session) {
4966        synchronized (this) {
4967            final long origId = Binder.clearCallingIdentity();
4968            try {
4969                // TODO: VI Consider treating local voice interactions and voice tasks
4970                // differently here
4971                mStackSupervisor.finishVoiceTask(session);
4972            } finally {
4973                Binder.restoreCallingIdentity(origId);
4974            }
4975        }
4976
4977    }
4978
4979    @Override
4980    public boolean releaseActivityInstance(IBinder token) {
4981        synchronized(this) {
4982            final long origId = Binder.clearCallingIdentity();
4983            try {
4984                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4985                if (r == null) {
4986                    return false;
4987                }
4988                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4989            } finally {
4990                Binder.restoreCallingIdentity(origId);
4991            }
4992        }
4993    }
4994
4995    @Override
4996    public void releaseSomeActivities(IApplicationThread appInt) {
4997        synchronized(this) {
4998            final long origId = Binder.clearCallingIdentity();
4999            try {
5000                ProcessRecord app = getRecordForAppLocked(appInt);
5001                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5002            } finally {
5003                Binder.restoreCallingIdentity(origId);
5004            }
5005        }
5006    }
5007
5008    @Override
5009    public boolean willActivityBeVisible(IBinder token) {
5010        synchronized(this) {
5011            ActivityStack stack = ActivityRecord.getStackLocked(token);
5012            if (stack != null) {
5013                return stack.willActivityBeVisibleLocked(token);
5014            }
5015            return false;
5016        }
5017    }
5018
5019    @Override
5020    public void overridePendingTransition(IBinder token, String packageName,
5021            int enterAnim, int exitAnim) {
5022        synchronized(this) {
5023            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5024            if (self == null) {
5025                return;
5026            }
5027
5028            final long origId = Binder.clearCallingIdentity();
5029
5030            if (self.state == ActivityState.RESUMED
5031                    || self.state == ActivityState.PAUSING) {
5032                mWindowManager.overridePendingAppTransition(packageName,
5033                        enterAnim, exitAnim, null);
5034            }
5035
5036            Binder.restoreCallingIdentity(origId);
5037        }
5038    }
5039
5040    /**
5041     * Main function for removing an existing process from the activity manager
5042     * as a result of that process going away.  Clears out all connections
5043     * to the process.
5044     */
5045    private final void handleAppDiedLocked(ProcessRecord app,
5046            boolean restarting, boolean allowRestart) {
5047        int pid = app.pid;
5048        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5049        if (!kept && !restarting) {
5050            removeLruProcessLocked(app);
5051            if (pid > 0) {
5052                ProcessList.remove(pid);
5053            }
5054        }
5055
5056        if (mProfileProc == app) {
5057            clearProfilerLocked();
5058        }
5059
5060        // Remove this application's activities from active lists.
5061        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5062
5063        app.activities.clear();
5064
5065        if (app.instrumentationClass != null) {
5066            Slog.w(TAG, "Crash of app " + app.processName
5067                  + " running instrumentation " + app.instrumentationClass);
5068            Bundle info = new Bundle();
5069            info.putString("shortMsg", "Process crashed.");
5070            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5071        }
5072
5073        if (!restarting && hasVisibleActivities
5074                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5075            // If there was nothing to resume, and we are not already restarting this process, but
5076            // there is a visible activity that is hosted by the process...  then make sure all
5077            // visible activities are running, taking care of restarting this process.
5078            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5079        }
5080    }
5081
5082    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5083        IBinder threadBinder = thread.asBinder();
5084        // Find the application record.
5085        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5086            ProcessRecord rec = mLruProcesses.get(i);
5087            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5088                return i;
5089            }
5090        }
5091        return -1;
5092    }
5093
5094    final ProcessRecord getRecordForAppLocked(
5095            IApplicationThread thread) {
5096        if (thread == null) {
5097            return null;
5098        }
5099
5100        int appIndex = getLRURecordIndexForAppLocked(thread);
5101        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5102    }
5103
5104    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5105        // If there are no longer any background processes running,
5106        // and the app that died was not running instrumentation,
5107        // then tell everyone we are now low on memory.
5108        boolean haveBg = false;
5109        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5110            ProcessRecord rec = mLruProcesses.get(i);
5111            if (rec.thread != null
5112                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5113                haveBg = true;
5114                break;
5115            }
5116        }
5117
5118        if (!haveBg) {
5119            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5120            if (doReport) {
5121                long now = SystemClock.uptimeMillis();
5122                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5123                    doReport = false;
5124                } else {
5125                    mLastMemUsageReportTime = now;
5126                }
5127            }
5128            final ArrayList<ProcessMemInfo> memInfos
5129                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5130            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5131            long now = SystemClock.uptimeMillis();
5132            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5133                ProcessRecord rec = mLruProcesses.get(i);
5134                if (rec == dyingProc || rec.thread == null) {
5135                    continue;
5136                }
5137                if (doReport) {
5138                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5139                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5140                }
5141                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5142                    // The low memory report is overriding any current
5143                    // state for a GC request.  Make sure to do
5144                    // heavy/important/visible/foreground processes first.
5145                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5146                        rec.lastRequestedGc = 0;
5147                    } else {
5148                        rec.lastRequestedGc = rec.lastLowMemory;
5149                    }
5150                    rec.reportLowMemory = true;
5151                    rec.lastLowMemory = now;
5152                    mProcessesToGc.remove(rec);
5153                    addProcessToGcListLocked(rec);
5154                }
5155            }
5156            if (doReport) {
5157                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5158                mHandler.sendMessage(msg);
5159            }
5160            scheduleAppGcsLocked();
5161        }
5162    }
5163
5164    final void appDiedLocked(ProcessRecord app) {
5165       appDiedLocked(app, app.pid, app.thread, false);
5166    }
5167
5168    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5169            boolean fromBinderDied) {
5170        // First check if this ProcessRecord is actually active for the pid.
5171        synchronized (mPidsSelfLocked) {
5172            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5173            if (curProc != app) {
5174                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5175                return;
5176            }
5177        }
5178
5179        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5180        synchronized (stats) {
5181            stats.noteProcessDiedLocked(app.info.uid, pid);
5182        }
5183
5184        if (!app.killed) {
5185            if (!fromBinderDied) {
5186                Process.killProcessQuiet(pid);
5187            }
5188            killProcessGroup(app.uid, pid);
5189            app.killed = true;
5190        }
5191
5192        // Clean up already done if the process has been re-started.
5193        if (app.pid == pid && app.thread != null &&
5194                app.thread.asBinder() == thread.asBinder()) {
5195            boolean doLowMem = app.instrumentationClass == null;
5196            boolean doOomAdj = doLowMem;
5197            if (!app.killedByAm) {
5198                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5199                        + ") has died");
5200                mAllowLowerMemLevel = true;
5201            } else {
5202                // Note that we always want to do oom adj to update our state with the
5203                // new number of procs.
5204                mAllowLowerMemLevel = false;
5205                doLowMem = false;
5206            }
5207            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5208            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5209                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5210            handleAppDiedLocked(app, false, true);
5211
5212            if (doOomAdj) {
5213                updateOomAdjLocked();
5214            }
5215            if (doLowMem) {
5216                doLowMemReportIfNeededLocked(app);
5217            }
5218        } else if (app.pid != pid) {
5219            // A new process has already been started.
5220            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5221                    + ") has died and restarted (pid " + app.pid + ").");
5222            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5223        } else if (DEBUG_PROCESSES) {
5224            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5225                    + thread.asBinder());
5226        }
5227    }
5228
5229    /**
5230     * If a stack trace dump file is configured, dump process stack traces.
5231     * @param clearTraces causes the dump file to be erased prior to the new
5232     *    traces being written, if true; when false, the new traces will be
5233     *    appended to any existing file content.
5234     * @param firstPids of dalvik VM processes to dump stack traces for first
5235     * @param lastPids of dalvik VM processes to dump stack traces for last
5236     * @param nativeProcs optional list of native process names to dump stack crawls
5237     * @return file containing stack traces, or null if no dump file is configured
5238     */
5239    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5240            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5241        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5242        if (tracesPath == null || tracesPath.length() == 0) {
5243            return null;
5244        }
5245
5246        File tracesFile = new File(tracesPath);
5247        try {
5248            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5249            tracesFile.createNewFile();
5250            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5251        } catch (IOException e) {
5252            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5253            return null;
5254        }
5255
5256        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5257        return tracesFile;
5258    }
5259
5260    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5261            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5262        // Use a FileObserver to detect when traces finish writing.
5263        // The order of traces is considered important to maintain for legibility.
5264        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5265            @Override
5266            public synchronized void onEvent(int event, String path) { notify(); }
5267        };
5268
5269        try {
5270            observer.startWatching();
5271
5272            // First collect all of the stacks of the most important pids.
5273            if (firstPids != null) {
5274                try {
5275                    int num = firstPids.size();
5276                    for (int i = 0; i < num; i++) {
5277                        synchronized (observer) {
5278                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5279                                    + firstPids.get(i));
5280                            final long sime = SystemClock.elapsedRealtime();
5281                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5282                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5283                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5284                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5285                        }
5286                    }
5287                } catch (InterruptedException e) {
5288                    Slog.wtf(TAG, e);
5289                }
5290            }
5291
5292            // Next collect the stacks of the native pids
5293            if (nativeProcs != null) {
5294                int[] pids = Process.getPidsForCommands(nativeProcs);
5295                if (pids != null) {
5296                    for (int pid : pids) {
5297                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5298                        final long sime = SystemClock.elapsedRealtime();
5299                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5300                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5301                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5302                    }
5303                }
5304            }
5305
5306            // Lastly, measure CPU usage.
5307            if (processCpuTracker != null) {
5308                processCpuTracker.init();
5309                System.gc();
5310                processCpuTracker.update();
5311                try {
5312                    synchronized (processCpuTracker) {
5313                        processCpuTracker.wait(500); // measure over 1/2 second.
5314                    }
5315                } catch (InterruptedException e) {
5316                }
5317                processCpuTracker.update();
5318
5319                // We'll take the stack crawls of just the top apps using CPU.
5320                final int N = processCpuTracker.countWorkingStats();
5321                int numProcs = 0;
5322                for (int i=0; i<N && numProcs<5; i++) {
5323                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5324                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5325                        numProcs++;
5326                        try {
5327                            synchronized (observer) {
5328                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5329                                        + stats.pid);
5330                                final long stime = SystemClock.elapsedRealtime();
5331                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5332                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5333                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5334                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5335                            }
5336                        } catch (InterruptedException e) {
5337                            Slog.wtf(TAG, e);
5338                        }
5339                    } else if (DEBUG_ANR) {
5340                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5341                                + stats.pid);
5342                    }
5343                }
5344            }
5345        } finally {
5346            observer.stopWatching();
5347        }
5348    }
5349
5350    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5351        if (true || IS_USER_BUILD) {
5352            return;
5353        }
5354        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5355        if (tracesPath == null || tracesPath.length() == 0) {
5356            return;
5357        }
5358
5359        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5360        StrictMode.allowThreadDiskWrites();
5361        try {
5362            final File tracesFile = new File(tracesPath);
5363            final File tracesDir = tracesFile.getParentFile();
5364            final File tracesTmp = new File(tracesDir, "__tmp__");
5365            try {
5366                if (tracesFile.exists()) {
5367                    tracesTmp.delete();
5368                    tracesFile.renameTo(tracesTmp);
5369                }
5370                StringBuilder sb = new StringBuilder();
5371                Time tobj = new Time();
5372                tobj.set(System.currentTimeMillis());
5373                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5374                sb.append(": ");
5375                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5376                sb.append(" since ");
5377                sb.append(msg);
5378                FileOutputStream fos = new FileOutputStream(tracesFile);
5379                fos.write(sb.toString().getBytes());
5380                if (app == null) {
5381                    fos.write("\n*** No application process!".getBytes());
5382                }
5383                fos.close();
5384                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5385            } catch (IOException e) {
5386                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5387                return;
5388            }
5389
5390            if (app != null) {
5391                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5392                firstPids.add(app.pid);
5393                dumpStackTraces(tracesPath, firstPids, null, null, null);
5394            }
5395
5396            File lastTracesFile = null;
5397            File curTracesFile = null;
5398            for (int i=9; i>=0; i--) {
5399                String name = String.format(Locale.US, "slow%02d.txt", i);
5400                curTracesFile = new File(tracesDir, name);
5401                if (curTracesFile.exists()) {
5402                    if (lastTracesFile != null) {
5403                        curTracesFile.renameTo(lastTracesFile);
5404                    } else {
5405                        curTracesFile.delete();
5406                    }
5407                }
5408                lastTracesFile = curTracesFile;
5409            }
5410            tracesFile.renameTo(curTracesFile);
5411            if (tracesTmp.exists()) {
5412                tracesTmp.renameTo(tracesFile);
5413            }
5414        } finally {
5415            StrictMode.setThreadPolicy(oldPolicy);
5416        }
5417    }
5418
5419    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5420        if (!mLaunchWarningShown) {
5421            mLaunchWarningShown = true;
5422            mUiHandler.post(new Runnable() {
5423                @Override
5424                public void run() {
5425                    synchronized (ActivityManagerService.this) {
5426                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5427                        d.show();
5428                        mUiHandler.postDelayed(new Runnable() {
5429                            @Override
5430                            public void run() {
5431                                synchronized (ActivityManagerService.this) {
5432                                    d.dismiss();
5433                                    mLaunchWarningShown = false;
5434                                }
5435                            }
5436                        }, 4000);
5437                    }
5438                }
5439            });
5440        }
5441    }
5442
5443    @Override
5444    public boolean clearApplicationUserData(final String packageName,
5445            final IPackageDataObserver observer, int userId) {
5446        enforceNotIsolatedCaller("clearApplicationUserData");
5447        int uid = Binder.getCallingUid();
5448        int pid = Binder.getCallingPid();
5449        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5450                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5451
5452
5453        long callingId = Binder.clearCallingIdentity();
5454        try {
5455            IPackageManager pm = AppGlobals.getPackageManager();
5456            int pkgUid = -1;
5457            synchronized(this) {
5458                if (getPackageManagerInternalLocked().isPackageDataProtected(
5459                        userId, packageName)) {
5460                    throw new SecurityException(
5461                            "Cannot clear data for a protected package: " + packageName);
5462                }
5463
5464                try {
5465                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5466                } catch (RemoteException e) {
5467                }
5468                if (pkgUid == -1) {
5469                    Slog.w(TAG, "Invalid packageName: " + packageName);
5470                    if (observer != null) {
5471                        try {
5472                            observer.onRemoveCompleted(packageName, false);
5473                        } catch (RemoteException e) {
5474                            Slog.i(TAG, "Observer no longer exists.");
5475                        }
5476                    }
5477                    return false;
5478                }
5479                if (uid == pkgUid || checkComponentPermission(
5480                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5481                        pid, uid, -1, true)
5482                        == PackageManager.PERMISSION_GRANTED) {
5483                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5484                } else {
5485                    throw new SecurityException("PID " + pid + " does not have permission "
5486                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5487                                    + " of package " + packageName);
5488                }
5489
5490                // Remove all tasks match the cleared application package and user
5491                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5492                    final TaskRecord tr = mRecentTasks.get(i);
5493                    final String taskPackageName =
5494                            tr.getBaseIntent().getComponent().getPackageName();
5495                    if (tr.userId != userId) continue;
5496                    if (!taskPackageName.equals(packageName)) continue;
5497                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5498                }
5499            }
5500
5501            final int pkgUidF = pkgUid;
5502            final int userIdF = userId;
5503            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5504                @Override
5505                public void onRemoveCompleted(String packageName, boolean succeeded)
5506                        throws RemoteException {
5507                    synchronized (ActivityManagerService.this) {
5508                        finishForceStopPackageLocked(packageName, pkgUidF);
5509                    }
5510
5511                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5512                            Uri.fromParts("package", packageName, null));
5513                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5514                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5515                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5516                            null, null, 0, null, null, null, null, false, false, userIdF);
5517
5518                    if (observer != null) {
5519                        observer.onRemoveCompleted(packageName, succeeded);
5520                    }
5521                }
5522            };
5523
5524            try {
5525                // Clear application user data
5526                pm.clearApplicationUserData(packageName, localObserver, userId);
5527
5528                synchronized(this) {
5529                    // Remove all permissions granted from/to this package
5530                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5531                }
5532
5533                // Remove all zen rules created by this package; revoke it's zen access.
5534                INotificationManager inm = NotificationManager.getService();
5535                inm.removeAutomaticZenRules(packageName);
5536                inm.setNotificationPolicyAccessGranted(packageName, false);
5537
5538            } catch (RemoteException e) {
5539            }
5540        } finally {
5541            Binder.restoreCallingIdentity(callingId);
5542        }
5543        return true;
5544    }
5545
5546    @Override
5547    public void killBackgroundProcesses(final String packageName, int userId) {
5548        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5549                != PackageManager.PERMISSION_GRANTED &&
5550                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5551                        != PackageManager.PERMISSION_GRANTED) {
5552            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5553                    + Binder.getCallingPid()
5554                    + ", uid=" + Binder.getCallingUid()
5555                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5556            Slog.w(TAG, msg);
5557            throw new SecurityException(msg);
5558        }
5559
5560        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5561                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5562        long callingId = Binder.clearCallingIdentity();
5563        try {
5564            IPackageManager pm = AppGlobals.getPackageManager();
5565            synchronized(this) {
5566                int appId = -1;
5567                try {
5568                    appId = UserHandle.getAppId(
5569                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5570                } catch (RemoteException e) {
5571                }
5572                if (appId == -1) {
5573                    Slog.w(TAG, "Invalid packageName: " + packageName);
5574                    return;
5575                }
5576                killPackageProcessesLocked(packageName, appId, userId,
5577                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5578            }
5579        } finally {
5580            Binder.restoreCallingIdentity(callingId);
5581        }
5582    }
5583
5584    @Override
5585    public void killAllBackgroundProcesses() {
5586        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5587                != PackageManager.PERMISSION_GRANTED) {
5588            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5589                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5590                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5591            Slog.w(TAG, msg);
5592            throw new SecurityException(msg);
5593        }
5594
5595        final long callingId = Binder.clearCallingIdentity();
5596        try {
5597            synchronized (this) {
5598                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5599                final int NP = mProcessNames.getMap().size();
5600                for (int ip = 0; ip < NP; ip++) {
5601                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5602                    final int NA = apps.size();
5603                    for (int ia = 0; ia < NA; ia++) {
5604                        final ProcessRecord app = apps.valueAt(ia);
5605                        if (app.persistent) {
5606                            // We don't kill persistent processes.
5607                            continue;
5608                        }
5609                        if (app.removed) {
5610                            procs.add(app);
5611                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5612                            app.removed = true;
5613                            procs.add(app);
5614                        }
5615                    }
5616                }
5617
5618                final int N = procs.size();
5619                for (int i = 0; i < N; i++) {
5620                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5621                }
5622
5623                mAllowLowerMemLevel = true;
5624
5625                updateOomAdjLocked();
5626                doLowMemReportIfNeededLocked(null);
5627            }
5628        } finally {
5629            Binder.restoreCallingIdentity(callingId);
5630        }
5631    }
5632
5633    /**
5634     * Kills all background processes, except those matching any of the
5635     * specified properties.
5636     *
5637     * @param minTargetSdk the target SDK version at or above which to preserve
5638     *                     processes, or {@code -1} to ignore the target SDK
5639     * @param maxProcState the process state at or below which to preserve
5640     *                     processes, or {@code -1} to ignore the process state
5641     */
5642    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5643        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5644                != PackageManager.PERMISSION_GRANTED) {
5645            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5646                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5647                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5648            Slog.w(TAG, msg);
5649            throw new SecurityException(msg);
5650        }
5651
5652        final long callingId = Binder.clearCallingIdentity();
5653        try {
5654            synchronized (this) {
5655                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5656                final int NP = mProcessNames.getMap().size();
5657                for (int ip = 0; ip < NP; ip++) {
5658                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5659                    final int NA = apps.size();
5660                    for (int ia = 0; ia < NA; ia++) {
5661                        final ProcessRecord app = apps.valueAt(ia);
5662                        if (app.removed) {
5663                            procs.add(app);
5664                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5665                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5666                            app.removed = true;
5667                            procs.add(app);
5668                        }
5669                    }
5670                }
5671
5672                final int N = procs.size();
5673                for (int i = 0; i < N; i++) {
5674                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5675                }
5676            }
5677        } finally {
5678            Binder.restoreCallingIdentity(callingId);
5679        }
5680    }
5681
5682    @Override
5683    public void forceStopPackage(final String packageName, int userId) {
5684        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5685                != PackageManager.PERMISSION_GRANTED) {
5686            String msg = "Permission Denial: forceStopPackage() from pid="
5687                    + Binder.getCallingPid()
5688                    + ", uid=" + Binder.getCallingUid()
5689                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5690            Slog.w(TAG, msg);
5691            throw new SecurityException(msg);
5692        }
5693        final int callingPid = Binder.getCallingPid();
5694        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5695                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5696        long callingId = Binder.clearCallingIdentity();
5697        try {
5698            IPackageManager pm = AppGlobals.getPackageManager();
5699            synchronized(this) {
5700                int[] users = userId == UserHandle.USER_ALL
5701                        ? mUserController.getUsers() : new int[] { userId };
5702                for (int user : users) {
5703                    int pkgUid = -1;
5704                    try {
5705                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5706                                user);
5707                    } catch (RemoteException e) {
5708                    }
5709                    if (pkgUid == -1) {
5710                        Slog.w(TAG, "Invalid packageName: " + packageName);
5711                        continue;
5712                    }
5713                    try {
5714                        pm.setPackageStoppedState(packageName, true, user);
5715                    } catch (RemoteException e) {
5716                    } catch (IllegalArgumentException e) {
5717                        Slog.w(TAG, "Failed trying to unstop package "
5718                                + packageName + ": " + e);
5719                    }
5720                    if (mUserController.isUserRunningLocked(user, 0)) {
5721                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5722                        finishForceStopPackageLocked(packageName, pkgUid);
5723                    }
5724                }
5725            }
5726        } finally {
5727            Binder.restoreCallingIdentity(callingId);
5728        }
5729    }
5730
5731    @Override
5732    public void addPackageDependency(String packageName) {
5733        synchronized (this) {
5734            int callingPid = Binder.getCallingPid();
5735            if (callingPid == Process.myPid()) {
5736                //  Yeah, um, no.
5737                return;
5738            }
5739            ProcessRecord proc;
5740            synchronized (mPidsSelfLocked) {
5741                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5742            }
5743            if (proc != null) {
5744                if (proc.pkgDeps == null) {
5745                    proc.pkgDeps = new ArraySet<String>(1);
5746                }
5747                proc.pkgDeps.add(packageName);
5748            }
5749        }
5750    }
5751
5752    /*
5753     * The pkg name and app id have to be specified.
5754     */
5755    @Override
5756    public void killApplication(String pkg, int appId, int userId, String reason) {
5757        if (pkg == null) {
5758            return;
5759        }
5760        // Make sure the uid is valid.
5761        if (appId < 0) {
5762            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5763            return;
5764        }
5765        int callerUid = Binder.getCallingUid();
5766        // Only the system server can kill an application
5767        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5768            // Post an aysnc message to kill the application
5769            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5770            msg.arg1 = appId;
5771            msg.arg2 = userId;
5772            Bundle bundle = new Bundle();
5773            bundle.putString("pkg", pkg);
5774            bundle.putString("reason", reason);
5775            msg.obj = bundle;
5776            mHandler.sendMessage(msg);
5777        } else {
5778            throw new SecurityException(callerUid + " cannot kill pkg: " +
5779                    pkg);
5780        }
5781    }
5782
5783    @Override
5784    public void closeSystemDialogs(String reason) {
5785        enforceNotIsolatedCaller("closeSystemDialogs");
5786
5787        final int pid = Binder.getCallingPid();
5788        final int uid = Binder.getCallingUid();
5789        final long origId = Binder.clearCallingIdentity();
5790        try {
5791            synchronized (this) {
5792                // Only allow this from foreground processes, so that background
5793                // applications can't abuse it to prevent system UI from being shown.
5794                if (uid >= Process.FIRST_APPLICATION_UID) {
5795                    ProcessRecord proc;
5796                    synchronized (mPidsSelfLocked) {
5797                        proc = mPidsSelfLocked.get(pid);
5798                    }
5799                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5800                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5801                                + " from background process " + proc);
5802                        return;
5803                    }
5804                }
5805                closeSystemDialogsLocked(reason);
5806            }
5807        } finally {
5808            Binder.restoreCallingIdentity(origId);
5809        }
5810    }
5811
5812    void closeSystemDialogsLocked(String reason) {
5813        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5814        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5815                | Intent.FLAG_RECEIVER_FOREGROUND);
5816        if (reason != null) {
5817            intent.putExtra("reason", reason);
5818        }
5819        mWindowManager.closeSystemDialogs(reason);
5820
5821        mStackSupervisor.closeSystemDialogsLocked();
5822
5823        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5824                AppOpsManager.OP_NONE, null, false, false,
5825                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5826    }
5827
5828    @Override
5829    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5830        enforceNotIsolatedCaller("getProcessMemoryInfo");
5831        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5832        for (int i=pids.length-1; i>=0; i--) {
5833            ProcessRecord proc;
5834            int oomAdj;
5835            synchronized (this) {
5836                synchronized (mPidsSelfLocked) {
5837                    proc = mPidsSelfLocked.get(pids[i]);
5838                    oomAdj = proc != null ? proc.setAdj : 0;
5839                }
5840            }
5841            infos[i] = new Debug.MemoryInfo();
5842            Debug.getMemoryInfo(pids[i], infos[i]);
5843            if (proc != null) {
5844                synchronized (this) {
5845                    if (proc.thread != null && proc.setAdj == oomAdj) {
5846                        // Record this for posterity if the process has been stable.
5847                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5848                                infos[i].getTotalUss(), false, proc.pkgList);
5849                    }
5850                }
5851            }
5852        }
5853        return infos;
5854    }
5855
5856    @Override
5857    public long[] getProcessPss(int[] pids) {
5858        enforceNotIsolatedCaller("getProcessPss");
5859        long[] pss = new long[pids.length];
5860        for (int i=pids.length-1; i>=0; i--) {
5861            ProcessRecord proc;
5862            int oomAdj;
5863            synchronized (this) {
5864                synchronized (mPidsSelfLocked) {
5865                    proc = mPidsSelfLocked.get(pids[i]);
5866                    oomAdj = proc != null ? proc.setAdj : 0;
5867                }
5868            }
5869            long[] tmpUss = new long[1];
5870            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5871            if (proc != null) {
5872                synchronized (this) {
5873                    if (proc.thread != null && proc.setAdj == oomAdj) {
5874                        // Record this for posterity if the process has been stable.
5875                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5876                    }
5877                }
5878            }
5879        }
5880        return pss;
5881    }
5882
5883    @Override
5884    public void killApplicationProcess(String processName, int uid) {
5885        if (processName == null) {
5886            return;
5887        }
5888
5889        int callerUid = Binder.getCallingUid();
5890        // Only the system server can kill an application
5891        if (callerUid == Process.SYSTEM_UID) {
5892            synchronized (this) {
5893                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5894                if (app != null && app.thread != null) {
5895                    try {
5896                        app.thread.scheduleSuicide();
5897                    } catch (RemoteException e) {
5898                        // If the other end already died, then our work here is done.
5899                    }
5900                } else {
5901                    Slog.w(TAG, "Process/uid not found attempting kill of "
5902                            + processName + " / " + uid);
5903                }
5904            }
5905        } else {
5906            throw new SecurityException(callerUid + " cannot kill app process: " +
5907                    processName);
5908        }
5909    }
5910
5911    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5912        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5913                false, true, false, false, UserHandle.getUserId(uid), reason);
5914    }
5915
5916    private void finishForceStopPackageLocked(final String packageName, int uid) {
5917        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5918                Uri.fromParts("package", packageName, null));
5919        if (!mProcessesReady) {
5920            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5921                    | Intent.FLAG_RECEIVER_FOREGROUND);
5922        }
5923        intent.putExtra(Intent.EXTRA_UID, uid);
5924        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5925        broadcastIntentLocked(null, null, intent,
5926                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5927                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5928    }
5929
5930
5931    private final boolean killPackageProcessesLocked(String packageName, int appId,
5932            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5933            boolean doit, boolean evenPersistent, String reason) {
5934        ArrayList<ProcessRecord> procs = new ArrayList<>();
5935
5936        // Remove all processes this package may have touched: all with the
5937        // same UID (except for the system or root user), and all whose name
5938        // matches the package name.
5939        final int NP = mProcessNames.getMap().size();
5940        for (int ip=0; ip<NP; ip++) {
5941            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5942            final int NA = apps.size();
5943            for (int ia=0; ia<NA; ia++) {
5944                ProcessRecord app = apps.valueAt(ia);
5945                if (app.persistent && !evenPersistent) {
5946                    // we don't kill persistent processes
5947                    continue;
5948                }
5949                if (app.removed) {
5950                    if (doit) {
5951                        procs.add(app);
5952                    }
5953                    continue;
5954                }
5955
5956                // Skip process if it doesn't meet our oom adj requirement.
5957                if (app.setAdj < minOomAdj) {
5958                    continue;
5959                }
5960
5961                // If no package is specified, we call all processes under the
5962                // give user id.
5963                if (packageName == null) {
5964                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5965                        continue;
5966                    }
5967                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5968                        continue;
5969                    }
5970                // Package has been specified, we want to hit all processes
5971                // that match it.  We need to qualify this by the processes
5972                // that are running under the specified app and user ID.
5973                } else {
5974                    final boolean isDep = app.pkgDeps != null
5975                            && app.pkgDeps.contains(packageName);
5976                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5977                        continue;
5978                    }
5979                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5980                        continue;
5981                    }
5982                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5983                        continue;
5984                    }
5985                }
5986
5987                // Process has passed all conditions, kill it!
5988                if (!doit) {
5989                    return true;
5990                }
5991                app.removed = true;
5992                procs.add(app);
5993            }
5994        }
5995
5996        int N = procs.size();
5997        for (int i=0; i<N; i++) {
5998            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5999        }
6000        updateOomAdjLocked();
6001        return N > 0;
6002    }
6003
6004    private void cleanupDisabledPackageComponentsLocked(
6005            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6006
6007        Set<String> disabledClasses = null;
6008        boolean packageDisabled = false;
6009        IPackageManager pm = AppGlobals.getPackageManager();
6010
6011        if (changedClasses == null) {
6012            // Nothing changed...
6013            return;
6014        }
6015
6016        // Determine enable/disable state of the package and its components.
6017        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6018        for (int i = changedClasses.length - 1; i >= 0; i--) {
6019            final String changedClass = changedClasses[i];
6020
6021            if (changedClass.equals(packageName)) {
6022                try {
6023                    // Entire package setting changed
6024                    enabled = pm.getApplicationEnabledSetting(packageName,
6025                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6026                } catch (Exception e) {
6027                    // No such package/component; probably racing with uninstall.  In any
6028                    // event it means we have nothing further to do here.
6029                    return;
6030                }
6031                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6032                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6033                if (packageDisabled) {
6034                    // Entire package is disabled.
6035                    // No need to continue to check component states.
6036                    disabledClasses = null;
6037                    break;
6038                }
6039            } else {
6040                try {
6041                    enabled = pm.getComponentEnabledSetting(
6042                            new ComponentName(packageName, changedClass),
6043                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6044                } catch (Exception e) {
6045                    // As above, probably racing with uninstall.
6046                    return;
6047                }
6048                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6049                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6050                    if (disabledClasses == null) {
6051                        disabledClasses = new ArraySet<>(changedClasses.length);
6052                    }
6053                    disabledClasses.add(changedClass);
6054                }
6055            }
6056        }
6057
6058        if (!packageDisabled && disabledClasses == null) {
6059            // Nothing to do here...
6060            return;
6061        }
6062
6063        // Clean-up disabled activities.
6064        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6065                packageName, disabledClasses, true, false, userId) && mBooted) {
6066            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6067            mStackSupervisor.scheduleIdleLocked();
6068        }
6069
6070        // Clean-up disabled tasks
6071        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6072
6073        // Clean-up disabled services.
6074        mServices.bringDownDisabledPackageServicesLocked(
6075                packageName, disabledClasses, userId, false, killProcess, true);
6076
6077        // Clean-up disabled providers.
6078        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6079        mProviderMap.collectPackageProvidersLocked(
6080                packageName, disabledClasses, true, false, userId, providers);
6081        for (int i = providers.size() - 1; i >= 0; i--) {
6082            removeDyingProviderLocked(null, providers.get(i), true);
6083        }
6084
6085        // Clean-up disabled broadcast receivers.
6086        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6087            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6088                    packageName, disabledClasses, userId, true);
6089        }
6090
6091    }
6092
6093    final boolean clearBroadcastQueueForUserLocked(int userId) {
6094        boolean didSomething = false;
6095        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6096            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6097                    null, null, userId, true);
6098        }
6099        return didSomething;
6100    }
6101
6102    final boolean forceStopPackageLocked(String packageName, int appId,
6103            boolean callerWillRestart, boolean purgeCache, boolean doit,
6104            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6105        int i;
6106
6107        if (userId == UserHandle.USER_ALL && packageName == null) {
6108            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6109        }
6110
6111        if (appId < 0 && packageName != null) {
6112            try {
6113                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6114                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6115            } catch (RemoteException e) {
6116            }
6117        }
6118
6119        if (doit) {
6120            if (packageName != null) {
6121                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6122                        + " user=" + userId + ": " + reason);
6123            } else {
6124                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6125            }
6126
6127            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6128        }
6129
6130        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6131                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6132                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6133
6134        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6135                packageName, null, doit, evenPersistent, userId)) {
6136            if (!doit) {
6137                return true;
6138            }
6139            didSomething = true;
6140        }
6141
6142        if (mServices.bringDownDisabledPackageServicesLocked(
6143                packageName, null, userId, evenPersistent, true, doit)) {
6144            if (!doit) {
6145                return true;
6146            }
6147            didSomething = true;
6148        }
6149
6150        if (packageName == null) {
6151            // Remove all sticky broadcasts from this user.
6152            mStickyBroadcasts.remove(userId);
6153        }
6154
6155        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6156        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6157                userId, providers)) {
6158            if (!doit) {
6159                return true;
6160            }
6161            didSomething = true;
6162        }
6163        for (i = providers.size() - 1; i >= 0; i--) {
6164            removeDyingProviderLocked(null, providers.get(i), true);
6165        }
6166
6167        // Remove transient permissions granted from/to this package/user
6168        removeUriPermissionsForPackageLocked(packageName, userId, false);
6169
6170        if (doit) {
6171            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6172                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6173                        packageName, null, userId, doit);
6174            }
6175        }
6176
6177        if (packageName == null || uninstalling) {
6178            // Remove pending intents.  For now we only do this when force
6179            // stopping users, because we have some problems when doing this
6180            // for packages -- app widgets are not currently cleaned up for
6181            // such packages, so they can be left with bad pending intents.
6182            if (mIntentSenderRecords.size() > 0) {
6183                Iterator<WeakReference<PendingIntentRecord>> it
6184                        = mIntentSenderRecords.values().iterator();
6185                while (it.hasNext()) {
6186                    WeakReference<PendingIntentRecord> wpir = it.next();
6187                    if (wpir == null) {
6188                        it.remove();
6189                        continue;
6190                    }
6191                    PendingIntentRecord pir = wpir.get();
6192                    if (pir == null) {
6193                        it.remove();
6194                        continue;
6195                    }
6196                    if (packageName == null) {
6197                        // Stopping user, remove all objects for the user.
6198                        if (pir.key.userId != userId) {
6199                            // Not the same user, skip it.
6200                            continue;
6201                        }
6202                    } else {
6203                        if (UserHandle.getAppId(pir.uid) != appId) {
6204                            // Different app id, skip it.
6205                            continue;
6206                        }
6207                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6208                            // Different user, skip it.
6209                            continue;
6210                        }
6211                        if (!pir.key.packageName.equals(packageName)) {
6212                            // Different package, skip it.
6213                            continue;
6214                        }
6215                    }
6216                    if (!doit) {
6217                        return true;
6218                    }
6219                    didSomething = true;
6220                    it.remove();
6221                    pir.canceled = true;
6222                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6223                        pir.key.activity.pendingResults.remove(pir.ref);
6224                    }
6225                }
6226            }
6227        }
6228
6229        if (doit) {
6230            if (purgeCache && packageName != null) {
6231                AttributeCache ac = AttributeCache.instance();
6232                if (ac != null) {
6233                    ac.removePackage(packageName);
6234                }
6235            }
6236            if (mBooted) {
6237                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6238                mStackSupervisor.scheduleIdleLocked();
6239            }
6240        }
6241
6242        return didSomething;
6243    }
6244
6245    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6246        ProcessRecord old = mProcessNames.remove(name, uid);
6247        if (old != null) {
6248            old.uidRecord.numProcs--;
6249            if (old.uidRecord.numProcs == 0) {
6250                // No more processes using this uid, tell clients it is gone.
6251                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6252                        "No more processes in " + old.uidRecord);
6253                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6254                mActiveUids.remove(uid);
6255                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6256            }
6257            old.uidRecord = null;
6258        }
6259        mIsolatedProcesses.remove(uid);
6260        return old;
6261    }
6262
6263    private final void addProcessNameLocked(ProcessRecord proc) {
6264        // We shouldn't already have a process under this name, but just in case we
6265        // need to clean up whatever may be there now.
6266        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6267        if (old == proc && proc.persistent) {
6268            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6269            Slog.w(TAG, "Re-adding persistent process " + proc);
6270        } else if (old != null) {
6271            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6272        }
6273        UidRecord uidRec = mActiveUids.get(proc.uid);
6274        if (uidRec == null) {
6275            uidRec = new UidRecord(proc.uid);
6276            // This is the first appearance of the uid, report it now!
6277            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6278                    "Creating new process uid: " + uidRec);
6279            mActiveUids.put(proc.uid, uidRec);
6280            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6281            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6282        }
6283        proc.uidRecord = uidRec;
6284
6285        // Reset render thread tid if it was already set, so new process can set it again.
6286        proc.renderThreadTid = 0;
6287        uidRec.numProcs++;
6288        mProcessNames.put(proc.processName, proc.uid, proc);
6289        if (proc.isolated) {
6290            mIsolatedProcesses.put(proc.uid, proc);
6291        }
6292    }
6293
6294    boolean removeProcessLocked(ProcessRecord app,
6295            boolean callerWillRestart, boolean allowRestart, String reason) {
6296        final String name = app.processName;
6297        final int uid = app.uid;
6298        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6299            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6300
6301        ProcessRecord old = mProcessNames.get(name, uid);
6302        if (old != app) {
6303            // This process is no longer active, so nothing to do.
6304            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6305            return false;
6306        }
6307        removeProcessNameLocked(name, uid);
6308        if (mHeavyWeightProcess == app) {
6309            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6310                    mHeavyWeightProcess.userId, 0));
6311            mHeavyWeightProcess = null;
6312        }
6313        boolean needRestart = false;
6314        if (app.pid > 0 && app.pid != MY_PID) {
6315            int pid = app.pid;
6316            synchronized (mPidsSelfLocked) {
6317                mPidsSelfLocked.remove(pid);
6318                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6319            }
6320            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6321            if (app.isolated) {
6322                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6323            }
6324            boolean willRestart = false;
6325            if (app.persistent && !app.isolated) {
6326                if (!callerWillRestart) {
6327                    willRestart = true;
6328                } else {
6329                    needRestart = true;
6330                }
6331            }
6332            app.kill(reason, true);
6333            handleAppDiedLocked(app, willRestart, allowRestart);
6334            if (willRestart) {
6335                removeLruProcessLocked(app);
6336                addAppLocked(app.info, false, null /* ABI override */);
6337            }
6338        } else {
6339            mRemovedProcesses.add(app);
6340        }
6341
6342        return needRestart;
6343    }
6344
6345    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6346        cleanupAppInLaunchingProvidersLocked(app, true);
6347        removeProcessLocked(app, false, true, "timeout publishing content providers");
6348    }
6349
6350    private final void processStartTimedOutLocked(ProcessRecord app) {
6351        final int pid = app.pid;
6352        boolean gone = false;
6353        synchronized (mPidsSelfLocked) {
6354            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6355            if (knownApp != null && knownApp.thread == null) {
6356                mPidsSelfLocked.remove(pid);
6357                gone = true;
6358            }
6359        }
6360
6361        if (gone) {
6362            Slog.w(TAG, "Process " + app + " failed to attach");
6363            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6364                    pid, app.uid, app.processName);
6365            removeProcessNameLocked(app.processName, app.uid);
6366            if (mHeavyWeightProcess == app) {
6367                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6368                        mHeavyWeightProcess.userId, 0));
6369                mHeavyWeightProcess = null;
6370            }
6371            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6372            if (app.isolated) {
6373                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6374            }
6375            // Take care of any launching providers waiting for this process.
6376            cleanupAppInLaunchingProvidersLocked(app, true);
6377            // Take care of any services that are waiting for the process.
6378            mServices.processStartTimedOutLocked(app);
6379            app.kill("start timeout", true);
6380            removeLruProcessLocked(app);
6381            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6382                Slog.w(TAG, "Unattached app died before backup, skipping");
6383                try {
6384                    IBackupManager bm = IBackupManager.Stub.asInterface(
6385                            ServiceManager.getService(Context.BACKUP_SERVICE));
6386                    bm.agentDisconnected(app.info.packageName);
6387                } catch (RemoteException e) {
6388                    // Can't happen; the backup manager is local
6389                }
6390            }
6391            if (isPendingBroadcastProcessLocked(pid)) {
6392                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6393                skipPendingBroadcastLocked(pid);
6394            }
6395        } else {
6396            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6397        }
6398    }
6399
6400    private final boolean attachApplicationLocked(IApplicationThread thread,
6401            int pid) {
6402
6403        // Find the application record that is being attached...  either via
6404        // the pid if we are running in multiple processes, or just pull the
6405        // next app record if we are emulating process with anonymous threads.
6406        ProcessRecord app;
6407        if (pid != MY_PID && pid >= 0) {
6408            synchronized (mPidsSelfLocked) {
6409                app = mPidsSelfLocked.get(pid);
6410            }
6411        } else {
6412            app = null;
6413        }
6414
6415        if (app == null) {
6416            Slog.w(TAG, "No pending application record for pid " + pid
6417                    + " (IApplicationThread " + thread + "); dropping process");
6418            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6419            if (pid > 0 && pid != MY_PID) {
6420                Process.killProcessQuiet(pid);
6421                //TODO: killProcessGroup(app.info.uid, pid);
6422            } else {
6423                try {
6424                    thread.scheduleExit();
6425                } catch (Exception e) {
6426                    // Ignore exceptions.
6427                }
6428            }
6429            return false;
6430        }
6431
6432        // If this application record is still attached to a previous
6433        // process, clean it up now.
6434        if (app.thread != null) {
6435            handleAppDiedLocked(app, true, true);
6436        }
6437
6438        // Tell the process all about itself.
6439
6440        if (DEBUG_ALL) Slog.v(
6441                TAG, "Binding process pid " + pid + " to record " + app);
6442
6443        final String processName = app.processName;
6444        try {
6445            AppDeathRecipient adr = new AppDeathRecipient(
6446                    app, pid, thread);
6447            thread.asBinder().linkToDeath(adr, 0);
6448            app.deathRecipient = adr;
6449        } catch (RemoteException e) {
6450            app.resetPackageList(mProcessStats);
6451            startProcessLocked(app, "link fail", processName);
6452            return false;
6453        }
6454
6455        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6456
6457        app.makeActive(thread, mProcessStats);
6458        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6459        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6460        app.forcingToForeground = null;
6461        updateProcessForegroundLocked(app, false, false);
6462        app.hasShownUi = false;
6463        app.debugging = false;
6464        app.cached = false;
6465        app.killedByAm = false;
6466
6467        // We carefully use the same state that PackageManager uses for
6468        // filtering, since we use this flag to decide if we need to install
6469        // providers when user is unlocked later
6470        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6471
6472        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6473
6474        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6475        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6476
6477        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6478            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6479            msg.obj = app;
6480            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6481        }
6482
6483        if (!normalMode) {
6484            Slog.i(TAG, "Launching preboot mode app: " + app);
6485        }
6486
6487        if (DEBUG_ALL) Slog.v(
6488            TAG, "New app record " + app
6489            + " thread=" + thread.asBinder() + " pid=" + pid);
6490        try {
6491            int testMode = IApplicationThread.DEBUG_OFF;
6492            if (mDebugApp != null && mDebugApp.equals(processName)) {
6493                testMode = mWaitForDebugger
6494                    ? IApplicationThread.DEBUG_WAIT
6495                    : IApplicationThread.DEBUG_ON;
6496                app.debugging = true;
6497                if (mDebugTransient) {
6498                    mDebugApp = mOrigDebugApp;
6499                    mWaitForDebugger = mOrigWaitForDebugger;
6500                }
6501            }
6502            String profileFile = app.instrumentationProfileFile;
6503            ParcelFileDescriptor profileFd = null;
6504            int samplingInterval = 0;
6505            boolean profileAutoStop = false;
6506            if (mProfileApp != null && mProfileApp.equals(processName)) {
6507                mProfileProc = app;
6508                profileFile = mProfileFile;
6509                profileFd = mProfileFd;
6510                samplingInterval = mSamplingInterval;
6511                profileAutoStop = mAutoStopProfiler;
6512            }
6513            boolean enableTrackAllocation = false;
6514            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6515                enableTrackAllocation = true;
6516                mTrackAllocationApp = null;
6517            }
6518
6519            // If the app is being launched for restore or full backup, set it up specially
6520            boolean isRestrictedBackupMode = false;
6521            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6522                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6523                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6524                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6525                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6526            }
6527
6528            if (app.instrumentationClass != null) {
6529                notifyPackageUse(app.instrumentationClass.getPackageName(),
6530                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6531            }
6532            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6533                    + processName + " with config " + mConfiguration);
6534            ApplicationInfo appInfo = app.instrumentationInfo != null
6535                    ? app.instrumentationInfo : app.info;
6536            app.compat = compatibilityInfoForPackageLocked(appInfo);
6537            if (profileFd != null) {
6538                profileFd = profileFd.dup();
6539            }
6540            ProfilerInfo profilerInfo = profileFile == null ? null
6541                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6542            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6543                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6544                    app.instrumentationUiAutomationConnection, testMode,
6545                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6546                    isRestrictedBackupMode || !normalMode, app.persistent,
6547                    new Configuration(mConfiguration), app.compat,
6548                    getCommonServicesLocked(app.isolated),
6549                    mCoreSettingsObserver.getCoreSettingsLocked());
6550            updateLruProcessLocked(app, false, null);
6551            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6552        } catch (Exception e) {
6553            // todo: Yikes!  What should we do?  For now we will try to
6554            // start another process, but that could easily get us in
6555            // an infinite loop of restarting processes...
6556            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6557
6558            app.resetPackageList(mProcessStats);
6559            app.unlinkDeathRecipient();
6560            startProcessLocked(app, "bind fail", processName);
6561            return false;
6562        }
6563
6564        // Remove this record from the list of starting applications.
6565        mPersistentStartingProcesses.remove(app);
6566        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6567                "Attach application locked removing on hold: " + app);
6568        mProcessesOnHold.remove(app);
6569
6570        boolean badApp = false;
6571        boolean didSomething = false;
6572
6573        // See if the top visible activity is waiting to run in this process...
6574        if (normalMode) {
6575            try {
6576                if (mStackSupervisor.attachApplicationLocked(app)) {
6577                    didSomething = true;
6578                }
6579            } catch (Exception e) {
6580                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6581                badApp = true;
6582            }
6583        }
6584
6585        // Find any services that should be running in this process...
6586        if (!badApp) {
6587            try {
6588                didSomething |= mServices.attachApplicationLocked(app, processName);
6589            } catch (Exception e) {
6590                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6591                badApp = true;
6592            }
6593        }
6594
6595        // Check if a next-broadcast receiver is in this process...
6596        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6597            try {
6598                didSomething |= sendPendingBroadcastsLocked(app);
6599            } catch (Exception e) {
6600                // If the app died trying to launch the receiver we declare it 'bad'
6601                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6602                badApp = true;
6603            }
6604        }
6605
6606        // Check whether the next backup agent is in this process...
6607        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6608            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6609                    "New app is backup target, launching agent for " + app);
6610            notifyPackageUse(mBackupTarget.appInfo.packageName,
6611                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6612            try {
6613                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6614                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6615                        mBackupTarget.backupMode);
6616            } catch (Exception e) {
6617                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6618                badApp = true;
6619            }
6620        }
6621
6622        if (badApp) {
6623            app.kill("error during init", true);
6624            handleAppDiedLocked(app, false, true);
6625            return false;
6626        }
6627
6628        if (!didSomething) {
6629            updateOomAdjLocked();
6630        }
6631
6632        return true;
6633    }
6634
6635    @Override
6636    public final void attachApplication(IApplicationThread thread) {
6637        synchronized (this) {
6638            int callingPid = Binder.getCallingPid();
6639            final long origId = Binder.clearCallingIdentity();
6640            attachApplicationLocked(thread, callingPid);
6641            Binder.restoreCallingIdentity(origId);
6642        }
6643    }
6644
6645    @Override
6646    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6647        final long origId = Binder.clearCallingIdentity();
6648        synchronized (this) {
6649            ActivityStack stack = ActivityRecord.getStackLocked(token);
6650            if (stack != null) {
6651                ActivityRecord r =
6652                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6653                if (stopProfiling) {
6654                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6655                        try {
6656                            mProfileFd.close();
6657                        } catch (IOException e) {
6658                        }
6659                        clearProfilerLocked();
6660                    }
6661                }
6662            }
6663        }
6664        Binder.restoreCallingIdentity(origId);
6665    }
6666
6667    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6668        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6669                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6670    }
6671
6672    void enableScreenAfterBoot() {
6673        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6674                SystemClock.uptimeMillis());
6675        mWindowManager.enableScreenAfterBoot();
6676
6677        synchronized (this) {
6678            updateEventDispatchingLocked();
6679        }
6680    }
6681
6682    @Override
6683    public void showBootMessage(final CharSequence msg, final boolean always) {
6684        if (Binder.getCallingUid() != Process.myUid()) {
6685            throw new SecurityException();
6686        }
6687        mWindowManager.showBootMessage(msg, always);
6688    }
6689
6690    @Override
6691    public void keyguardWaitingForActivityDrawn() {
6692        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6693        final long token = Binder.clearCallingIdentity();
6694        try {
6695            synchronized (this) {
6696                if (DEBUG_LOCKSCREEN) logLockScreen("");
6697                mWindowManager.keyguardWaitingForActivityDrawn();
6698                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6699                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6700                    updateSleepIfNeededLocked();
6701                }
6702            }
6703        } finally {
6704            Binder.restoreCallingIdentity(token);
6705        }
6706    }
6707
6708    @Override
6709    public void keyguardGoingAway(int flags) {
6710        enforceNotIsolatedCaller("keyguardGoingAway");
6711        final long token = Binder.clearCallingIdentity();
6712        try {
6713            synchronized (this) {
6714                if (DEBUG_LOCKSCREEN) logLockScreen("");
6715                mWindowManager.keyguardGoingAway(flags);
6716                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6717                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6718                    updateSleepIfNeededLocked();
6719
6720                    // Some stack visibility might change (e.g. docked stack)
6721                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6722                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6723                }
6724            }
6725        } finally {
6726            Binder.restoreCallingIdentity(token);
6727        }
6728    }
6729
6730    final void finishBooting() {
6731        synchronized (this) {
6732            if (!mBootAnimationComplete) {
6733                mCallFinishBooting = true;
6734                return;
6735            }
6736            mCallFinishBooting = false;
6737        }
6738
6739        ArraySet<String> completedIsas = new ArraySet<String>();
6740        for (String abi : Build.SUPPORTED_ABIS) {
6741            Process.establishZygoteConnectionForAbi(abi);
6742            final String instructionSet = VMRuntime.getInstructionSet(abi);
6743            if (!completedIsas.contains(instructionSet)) {
6744                try {
6745                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6746                } catch (InstallerException e) {
6747                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6748                            e.getMessage() +")");
6749                }
6750                completedIsas.add(instructionSet);
6751            }
6752        }
6753
6754        IntentFilter pkgFilter = new IntentFilter();
6755        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6756        pkgFilter.addDataScheme("package");
6757        mContext.registerReceiver(new BroadcastReceiver() {
6758            @Override
6759            public void onReceive(Context context, Intent intent) {
6760                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6761                if (pkgs != null) {
6762                    for (String pkg : pkgs) {
6763                        synchronized (ActivityManagerService.this) {
6764                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6765                                    0, "query restart")) {
6766                                setResultCode(Activity.RESULT_OK);
6767                                return;
6768                            }
6769                        }
6770                    }
6771                }
6772            }
6773        }, pkgFilter);
6774
6775        IntentFilter dumpheapFilter = new IntentFilter();
6776        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6777        mContext.registerReceiver(new BroadcastReceiver() {
6778            @Override
6779            public void onReceive(Context context, Intent intent) {
6780                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6781                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6782                } else {
6783                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6784                }
6785            }
6786        }, dumpheapFilter);
6787
6788        // Let system services know.
6789        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6790
6791        synchronized (this) {
6792            // Ensure that any processes we had put on hold are now started
6793            // up.
6794            final int NP = mProcessesOnHold.size();
6795            if (NP > 0) {
6796                ArrayList<ProcessRecord> procs =
6797                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6798                for (int ip=0; ip<NP; ip++) {
6799                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6800                            + procs.get(ip));
6801                    startProcessLocked(procs.get(ip), "on-hold", null);
6802                }
6803            }
6804
6805            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6806                // Start looking for apps that are abusing wake locks.
6807                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6808                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6809                // Tell anyone interested that we are done booting!
6810                SystemProperties.set("sys.boot_completed", "1");
6811
6812                // And trigger dev.bootcomplete if we are not showing encryption progress
6813                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6814                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6815                    SystemProperties.set("dev.bootcomplete", "1");
6816                }
6817                mUserController.sendBootCompletedLocked(
6818                        new IIntentReceiver.Stub() {
6819                            @Override
6820                            public void performReceive(Intent intent, int resultCode,
6821                                    String data, Bundle extras, boolean ordered,
6822                                    boolean sticky, int sendingUser) {
6823                                synchronized (ActivityManagerService.this) {
6824                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6825                                            true, false);
6826                                }
6827                            }
6828                        });
6829                scheduleStartProfilesLocked();
6830            }
6831        }
6832    }
6833
6834    @Override
6835    public void bootAnimationComplete() {
6836        final boolean callFinishBooting;
6837        synchronized (this) {
6838            callFinishBooting = mCallFinishBooting;
6839            mBootAnimationComplete = true;
6840        }
6841        if (callFinishBooting) {
6842            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6843            finishBooting();
6844            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6845        }
6846    }
6847
6848    final void ensureBootCompleted() {
6849        boolean booting;
6850        boolean enableScreen;
6851        synchronized (this) {
6852            booting = mBooting;
6853            mBooting = false;
6854            enableScreen = !mBooted;
6855            mBooted = true;
6856        }
6857
6858        if (booting) {
6859            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6860            finishBooting();
6861            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6862        }
6863
6864        if (enableScreen) {
6865            enableScreenAfterBoot();
6866        }
6867    }
6868
6869    @Override
6870    public final void activityResumed(IBinder token) {
6871        final long origId = Binder.clearCallingIdentity();
6872        synchronized(this) {
6873            ActivityStack stack = ActivityRecord.getStackLocked(token);
6874            if (stack != null) {
6875                stack.activityResumedLocked(token);
6876            }
6877        }
6878        Binder.restoreCallingIdentity(origId);
6879    }
6880
6881    @Override
6882    public final void activityPaused(IBinder token) {
6883        final long origId = Binder.clearCallingIdentity();
6884        synchronized(this) {
6885            ActivityStack stack = ActivityRecord.getStackLocked(token);
6886            if (stack != null) {
6887                stack.activityPausedLocked(token, false);
6888            }
6889        }
6890        Binder.restoreCallingIdentity(origId);
6891    }
6892
6893    @Override
6894    public final void activityStopped(IBinder token, Bundle icicle,
6895            PersistableBundle persistentState, CharSequence description) {
6896        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6897
6898        // Refuse possible leaked file descriptors
6899        if (icicle != null && icicle.hasFileDescriptors()) {
6900            throw new IllegalArgumentException("File descriptors passed in Bundle");
6901        }
6902
6903        final long origId = Binder.clearCallingIdentity();
6904
6905        synchronized (this) {
6906            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6907            if (r != null) {
6908                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6909            }
6910        }
6911
6912        trimApplications();
6913
6914        Binder.restoreCallingIdentity(origId);
6915    }
6916
6917    @Override
6918    public final void activityDestroyed(IBinder token) {
6919        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6920        synchronized (this) {
6921            ActivityStack stack = ActivityRecord.getStackLocked(token);
6922            if (stack != null) {
6923                stack.activityDestroyedLocked(token, "activityDestroyed");
6924            }
6925        }
6926    }
6927
6928    @Override
6929    public final void activityRelaunched(IBinder token) {
6930        final long origId = Binder.clearCallingIdentity();
6931        synchronized (this) {
6932            mStackSupervisor.activityRelaunchedLocked(token);
6933        }
6934        Binder.restoreCallingIdentity(origId);
6935    }
6936
6937    @Override
6938    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6939            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6940        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6941                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6942        synchronized (this) {
6943            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6944            if (record == null) {
6945                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6946                        + "found for: " + token);
6947            }
6948            record.setSizeConfigurations(horizontalSizeConfiguration,
6949                    verticalSizeConfigurations, smallestSizeConfigurations);
6950        }
6951    }
6952
6953    @Override
6954    public final void backgroundResourcesReleased(IBinder token) {
6955        final long origId = Binder.clearCallingIdentity();
6956        try {
6957            synchronized (this) {
6958                ActivityStack stack = ActivityRecord.getStackLocked(token);
6959                if (stack != null) {
6960                    stack.backgroundResourcesReleased();
6961                }
6962            }
6963        } finally {
6964            Binder.restoreCallingIdentity(origId);
6965        }
6966    }
6967
6968    @Override
6969    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6970        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6971    }
6972
6973    @Override
6974    public final void notifyEnterAnimationComplete(IBinder token) {
6975        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6976    }
6977
6978    @Override
6979    public String getCallingPackage(IBinder token) {
6980        synchronized (this) {
6981            ActivityRecord r = getCallingRecordLocked(token);
6982            return r != null ? r.info.packageName : null;
6983        }
6984    }
6985
6986    @Override
6987    public ComponentName getCallingActivity(IBinder token) {
6988        synchronized (this) {
6989            ActivityRecord r = getCallingRecordLocked(token);
6990            return r != null ? r.intent.getComponent() : null;
6991        }
6992    }
6993
6994    private ActivityRecord getCallingRecordLocked(IBinder token) {
6995        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6996        if (r == null) {
6997            return null;
6998        }
6999        return r.resultTo;
7000    }
7001
7002    @Override
7003    public ComponentName getActivityClassForToken(IBinder token) {
7004        synchronized(this) {
7005            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7006            if (r == null) {
7007                return null;
7008            }
7009            return r.intent.getComponent();
7010        }
7011    }
7012
7013    @Override
7014    public String getPackageForToken(IBinder token) {
7015        synchronized(this) {
7016            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7017            if (r == null) {
7018                return null;
7019            }
7020            return r.packageName;
7021        }
7022    }
7023
7024    @Override
7025    public boolean isRootVoiceInteraction(IBinder token) {
7026        synchronized(this) {
7027            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7028            if (r == null) {
7029                return false;
7030            }
7031            return r.rootVoiceInteraction;
7032        }
7033    }
7034
7035    @Override
7036    public IIntentSender getIntentSender(int type,
7037            String packageName, IBinder token, String resultWho,
7038            int requestCode, Intent[] intents, String[] resolvedTypes,
7039            int flags, Bundle bOptions, int userId) {
7040        enforceNotIsolatedCaller("getIntentSender");
7041        // Refuse possible leaked file descriptors
7042        if (intents != null) {
7043            if (intents.length < 1) {
7044                throw new IllegalArgumentException("Intents array length must be >= 1");
7045            }
7046            for (int i=0; i<intents.length; i++) {
7047                Intent intent = intents[i];
7048                if (intent != null) {
7049                    if (intent.hasFileDescriptors()) {
7050                        throw new IllegalArgumentException("File descriptors passed in Intent");
7051                    }
7052                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7053                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7054                        throw new IllegalArgumentException(
7055                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7056                    }
7057                    intents[i] = new Intent(intent);
7058                }
7059            }
7060            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7061                throw new IllegalArgumentException(
7062                        "Intent array length does not match resolvedTypes length");
7063            }
7064        }
7065        if (bOptions != null) {
7066            if (bOptions.hasFileDescriptors()) {
7067                throw new IllegalArgumentException("File descriptors passed in options");
7068            }
7069        }
7070
7071        synchronized(this) {
7072            int callingUid = Binder.getCallingUid();
7073            int origUserId = userId;
7074            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7075                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7076                    ALLOW_NON_FULL, "getIntentSender", null);
7077            if (origUserId == UserHandle.USER_CURRENT) {
7078                // We don't want to evaluate this until the pending intent is
7079                // actually executed.  However, we do want to always do the
7080                // security checking for it above.
7081                userId = UserHandle.USER_CURRENT;
7082            }
7083            try {
7084                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7085                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7086                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7087                    if (!UserHandle.isSameApp(callingUid, uid)) {
7088                        String msg = "Permission Denial: getIntentSender() from pid="
7089                            + Binder.getCallingPid()
7090                            + ", uid=" + Binder.getCallingUid()
7091                            + ", (need uid=" + uid + ")"
7092                            + " is not allowed to send as package " + packageName;
7093                        Slog.w(TAG, msg);
7094                        throw new SecurityException(msg);
7095                    }
7096                }
7097
7098                return getIntentSenderLocked(type, packageName, callingUid, userId,
7099                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7100
7101            } catch (RemoteException e) {
7102                throw new SecurityException(e);
7103            }
7104        }
7105    }
7106
7107    IIntentSender getIntentSenderLocked(int type, String packageName,
7108            int callingUid, int userId, IBinder token, String resultWho,
7109            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7110            Bundle bOptions) {
7111        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7112        ActivityRecord activity = null;
7113        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7114            activity = ActivityRecord.isInStackLocked(token);
7115            if (activity == null) {
7116                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7117                return null;
7118            }
7119            if (activity.finishing) {
7120                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7121                return null;
7122            }
7123        }
7124
7125        // We're going to be splicing together extras before sending, so we're
7126        // okay poking into any contained extras.
7127        if (intents != null) {
7128            for (int i = 0; i < intents.length; i++) {
7129                intents[i].setDefusable(true);
7130            }
7131        }
7132        Bundle.setDefusable(bOptions, true);
7133
7134        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7135        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7136        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7137        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7138                |PendingIntent.FLAG_UPDATE_CURRENT);
7139
7140        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7141                type, packageName, activity, resultWho,
7142                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7143        WeakReference<PendingIntentRecord> ref;
7144        ref = mIntentSenderRecords.get(key);
7145        PendingIntentRecord rec = ref != null ? ref.get() : null;
7146        if (rec != null) {
7147            if (!cancelCurrent) {
7148                if (updateCurrent) {
7149                    if (rec.key.requestIntent != null) {
7150                        rec.key.requestIntent.replaceExtras(intents != null ?
7151                                intents[intents.length - 1] : null);
7152                    }
7153                    if (intents != null) {
7154                        intents[intents.length-1] = rec.key.requestIntent;
7155                        rec.key.allIntents = intents;
7156                        rec.key.allResolvedTypes = resolvedTypes;
7157                    } else {
7158                        rec.key.allIntents = null;
7159                        rec.key.allResolvedTypes = null;
7160                    }
7161                }
7162                return rec;
7163            }
7164            rec.canceled = true;
7165            mIntentSenderRecords.remove(key);
7166        }
7167        if (noCreate) {
7168            return rec;
7169        }
7170        rec = new PendingIntentRecord(this, key, callingUid);
7171        mIntentSenderRecords.put(key, rec.ref);
7172        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7173            if (activity.pendingResults == null) {
7174                activity.pendingResults
7175                        = new HashSet<WeakReference<PendingIntentRecord>>();
7176            }
7177            activity.pendingResults.add(rec.ref);
7178        }
7179        return rec;
7180    }
7181
7182    @Override
7183    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7184            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7185        if (target instanceof PendingIntentRecord) {
7186            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7187                    finishedReceiver, requiredPermission, options);
7188        } else {
7189            if (intent == null) {
7190                // Weird case: someone has given us their own custom IIntentSender, and now
7191                // they have someone else trying to send to it but of course this isn't
7192                // really a PendingIntent, so there is no base Intent, and the caller isn't
7193                // supplying an Intent... but we never want to dispatch a null Intent to
7194                // a receiver, so um...  let's make something up.
7195                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7196                intent = new Intent(Intent.ACTION_MAIN);
7197            }
7198            try {
7199                target.send(code, intent, resolvedType, null, requiredPermission, options);
7200            } catch (RemoteException e) {
7201            }
7202            // Platform code can rely on getting a result back when the send is done, but if
7203            // this intent sender is from outside of the system we can't rely on it doing that.
7204            // So instead we don't give it the result receiver, and instead just directly
7205            // report the finish immediately.
7206            if (finishedReceiver != null) {
7207                try {
7208                    finishedReceiver.performReceive(intent, 0,
7209                            null, null, false, false, UserHandle.getCallingUserId());
7210                } catch (RemoteException e) {
7211                }
7212            }
7213            return 0;
7214        }
7215    }
7216
7217    /**
7218     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7219     *
7220     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7221     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7222     */
7223    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7224        if (DEBUG_WHITELISTS) {
7225            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7226                    + targetUid + ", " + duration + ")");
7227        }
7228        synchronized (mPidsSelfLocked) {
7229            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7230            if (pr == null) {
7231                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7232                return;
7233            }
7234            if (!pr.whitelistManager) {
7235                if (DEBUG_WHITELISTS) {
7236                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7237                            + callerPid + " is not allowed");
7238                }
7239                return;
7240            }
7241        }
7242
7243        final long token = Binder.clearCallingIdentity();
7244        try {
7245            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7246                    true, "pe from uid:" + callerUid);
7247        } finally {
7248            Binder.restoreCallingIdentity(token);
7249        }
7250    }
7251
7252    @Override
7253    public void cancelIntentSender(IIntentSender sender) {
7254        if (!(sender instanceof PendingIntentRecord)) {
7255            return;
7256        }
7257        synchronized(this) {
7258            PendingIntentRecord rec = (PendingIntentRecord)sender;
7259            try {
7260                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7261                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7262                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7263                    String msg = "Permission Denial: cancelIntentSender() from pid="
7264                        + Binder.getCallingPid()
7265                        + ", uid=" + Binder.getCallingUid()
7266                        + " is not allowed to cancel packges "
7267                        + rec.key.packageName;
7268                    Slog.w(TAG, msg);
7269                    throw new SecurityException(msg);
7270                }
7271            } catch (RemoteException e) {
7272                throw new SecurityException(e);
7273            }
7274            cancelIntentSenderLocked(rec, true);
7275        }
7276    }
7277
7278    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7279        rec.canceled = true;
7280        mIntentSenderRecords.remove(rec.key);
7281        if (cleanActivity && rec.key.activity != null) {
7282            rec.key.activity.pendingResults.remove(rec.ref);
7283        }
7284    }
7285
7286    @Override
7287    public String getPackageForIntentSender(IIntentSender pendingResult) {
7288        if (!(pendingResult instanceof PendingIntentRecord)) {
7289            return null;
7290        }
7291        try {
7292            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7293            return res.key.packageName;
7294        } catch (ClassCastException e) {
7295        }
7296        return null;
7297    }
7298
7299    @Override
7300    public int getUidForIntentSender(IIntentSender sender) {
7301        if (sender instanceof PendingIntentRecord) {
7302            try {
7303                PendingIntentRecord res = (PendingIntentRecord)sender;
7304                return res.uid;
7305            } catch (ClassCastException e) {
7306            }
7307        }
7308        return -1;
7309    }
7310
7311    @Override
7312    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7313        if (!(pendingResult instanceof PendingIntentRecord)) {
7314            return false;
7315        }
7316        try {
7317            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7318            if (res.key.allIntents == null) {
7319                return false;
7320            }
7321            for (int i=0; i<res.key.allIntents.length; i++) {
7322                Intent intent = res.key.allIntents[i];
7323                if (intent.getPackage() != null && intent.getComponent() != null) {
7324                    return false;
7325                }
7326            }
7327            return true;
7328        } catch (ClassCastException e) {
7329        }
7330        return false;
7331    }
7332
7333    @Override
7334    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7335        if (!(pendingResult instanceof PendingIntentRecord)) {
7336            return false;
7337        }
7338        try {
7339            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7340            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7341                return true;
7342            }
7343            return false;
7344        } catch (ClassCastException e) {
7345        }
7346        return false;
7347    }
7348
7349    @Override
7350    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7351        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7352                "getIntentForIntentSender()");
7353        if (!(pendingResult instanceof PendingIntentRecord)) {
7354            return null;
7355        }
7356        try {
7357            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7358            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7359        } catch (ClassCastException e) {
7360        }
7361        return null;
7362    }
7363
7364    @Override
7365    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7366        if (!(pendingResult instanceof PendingIntentRecord)) {
7367            return null;
7368        }
7369        try {
7370            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7371            synchronized (this) {
7372                return getTagForIntentSenderLocked(res, prefix);
7373            }
7374        } catch (ClassCastException e) {
7375        }
7376        return null;
7377    }
7378
7379    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7380        final Intent intent = res.key.requestIntent;
7381        if (intent != null) {
7382            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7383                    || res.lastTagPrefix.equals(prefix))) {
7384                return res.lastTag;
7385            }
7386            res.lastTagPrefix = prefix;
7387            final StringBuilder sb = new StringBuilder(128);
7388            if (prefix != null) {
7389                sb.append(prefix);
7390            }
7391            if (intent.getAction() != null) {
7392                sb.append(intent.getAction());
7393            } else if (intent.getComponent() != null) {
7394                intent.getComponent().appendShortString(sb);
7395            } else {
7396                sb.append("?");
7397            }
7398            return res.lastTag = sb.toString();
7399        }
7400        return null;
7401    }
7402
7403    @Override
7404    public void setProcessLimit(int max) {
7405        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7406                "setProcessLimit()");
7407        synchronized (this) {
7408            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7409            mProcessLimitOverride = max;
7410        }
7411        trimApplications();
7412    }
7413
7414    @Override
7415    public int getProcessLimit() {
7416        synchronized (this) {
7417            return mProcessLimitOverride;
7418        }
7419    }
7420
7421    void foregroundTokenDied(ForegroundToken token) {
7422        synchronized (ActivityManagerService.this) {
7423            synchronized (mPidsSelfLocked) {
7424                ForegroundToken cur
7425                    = mForegroundProcesses.get(token.pid);
7426                if (cur != token) {
7427                    return;
7428                }
7429                mForegroundProcesses.remove(token.pid);
7430                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7431                if (pr == null) {
7432                    return;
7433                }
7434                pr.forcingToForeground = null;
7435                updateProcessForegroundLocked(pr, false, false);
7436            }
7437            updateOomAdjLocked();
7438        }
7439    }
7440
7441    @Override
7442    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7443        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7444                "setProcessForeground()");
7445        synchronized(this) {
7446            boolean changed = false;
7447
7448            synchronized (mPidsSelfLocked) {
7449                ProcessRecord pr = mPidsSelfLocked.get(pid);
7450                if (pr == null && isForeground) {
7451                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7452                    return;
7453                }
7454                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7455                if (oldToken != null) {
7456                    oldToken.token.unlinkToDeath(oldToken, 0);
7457                    mForegroundProcesses.remove(pid);
7458                    if (pr != null) {
7459                        pr.forcingToForeground = null;
7460                    }
7461                    changed = true;
7462                }
7463                if (isForeground && token != null) {
7464                    ForegroundToken newToken = new ForegroundToken() {
7465                        @Override
7466                        public void binderDied() {
7467                            foregroundTokenDied(this);
7468                        }
7469                    };
7470                    newToken.pid = pid;
7471                    newToken.token = token;
7472                    try {
7473                        token.linkToDeath(newToken, 0);
7474                        mForegroundProcesses.put(pid, newToken);
7475                        pr.forcingToForeground = token;
7476                        changed = true;
7477                    } catch (RemoteException e) {
7478                        // If the process died while doing this, we will later
7479                        // do the cleanup with the process death link.
7480                    }
7481                }
7482            }
7483
7484            if (changed) {
7485                updateOomAdjLocked();
7486            }
7487        }
7488    }
7489
7490    @Override
7491    public boolean isAppForeground(int uid) throws RemoteException {
7492        synchronized (this) {
7493            UidRecord uidRec = mActiveUids.get(uid);
7494            if (uidRec == null || uidRec.idle) {
7495                return false;
7496            }
7497            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7498        }
7499    }
7500
7501    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7502    // be guarded by permission checking.
7503    int getUidState(int uid) {
7504        synchronized (this) {
7505            UidRecord uidRec = mActiveUids.get(uid);
7506            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7507        }
7508    }
7509
7510    @Override
7511    public boolean isInMultiWindowMode(IBinder token) {
7512        final long origId = Binder.clearCallingIdentity();
7513        try {
7514            synchronized(this) {
7515                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7516                if (r == null) {
7517                    return false;
7518                }
7519                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7520                return !r.task.mFullscreen;
7521            }
7522        } finally {
7523            Binder.restoreCallingIdentity(origId);
7524        }
7525    }
7526
7527    @Override
7528    public boolean isInPictureInPictureMode(IBinder token) {
7529        final long origId = Binder.clearCallingIdentity();
7530        try {
7531            synchronized(this) {
7532                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7533                if (stack == null) {
7534                    return false;
7535                }
7536                return stack.mStackId == PINNED_STACK_ID;
7537            }
7538        } finally {
7539            Binder.restoreCallingIdentity(origId);
7540        }
7541    }
7542
7543    @Override
7544    public void enterPictureInPictureMode(IBinder token) {
7545        final long origId = Binder.clearCallingIdentity();
7546        try {
7547            synchronized(this) {
7548                if (!mSupportsPictureInPicture) {
7549                    throw new IllegalStateException("enterPictureInPictureMode: "
7550                            + "Device doesn't support picture-in-picture mode.");
7551                }
7552
7553                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7554
7555                if (r == null) {
7556                    throw new IllegalStateException("enterPictureInPictureMode: "
7557                            + "Can't find activity for token=" + token);
7558                }
7559
7560                if (!r.supportsPictureInPicture()) {
7561                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7562                            + "Picture-In-Picture not supported for r=" + r);
7563                }
7564
7565                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7566                // current bounds.
7567                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7568                final Rect bounds = (pinnedStack != null)
7569                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7570
7571                mStackSupervisor.moveActivityToPinnedStackLocked(
7572                        r, "enterPictureInPictureMode", bounds);
7573            }
7574        } finally {
7575            Binder.restoreCallingIdentity(origId);
7576        }
7577    }
7578
7579    // =========================================================
7580    // PROCESS INFO
7581    // =========================================================
7582
7583    static class ProcessInfoService extends IProcessInfoService.Stub {
7584        final ActivityManagerService mActivityManagerService;
7585        ProcessInfoService(ActivityManagerService activityManagerService) {
7586            mActivityManagerService = activityManagerService;
7587        }
7588
7589        @Override
7590        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7591            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7592                    /*in*/ pids, /*out*/ states, null);
7593        }
7594
7595        @Override
7596        public void getProcessStatesAndOomScoresFromPids(
7597                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7598            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7599                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7600        }
7601    }
7602
7603    /**
7604     * For each PID in the given input array, write the current process state
7605     * for that process into the states array, or -1 to indicate that no
7606     * process with the given PID exists. If scores array is provided, write
7607     * the oom score for the process into the scores array, with INVALID_ADJ
7608     * indicating the PID doesn't exist.
7609     */
7610    public void getProcessStatesAndOomScoresForPIDs(
7611            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7612        if (scores != null) {
7613            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7614                    "getProcessStatesAndOomScoresForPIDs()");
7615        }
7616
7617        if (pids == null) {
7618            throw new NullPointerException("pids");
7619        } else if (states == null) {
7620            throw new NullPointerException("states");
7621        } else if (pids.length != states.length) {
7622            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7623        } else if (scores != null && pids.length != scores.length) {
7624            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7625        }
7626
7627        synchronized (mPidsSelfLocked) {
7628            for (int i = 0; i < pids.length; i++) {
7629                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7630                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7631                        pr.curProcState;
7632                if (scores != null) {
7633                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7634                }
7635            }
7636        }
7637    }
7638
7639    // =========================================================
7640    // PERMISSIONS
7641    // =========================================================
7642
7643    static class PermissionController extends IPermissionController.Stub {
7644        ActivityManagerService mActivityManagerService;
7645        PermissionController(ActivityManagerService activityManagerService) {
7646            mActivityManagerService = activityManagerService;
7647        }
7648
7649        @Override
7650        public boolean checkPermission(String permission, int pid, int uid) {
7651            return mActivityManagerService.checkPermission(permission, pid,
7652                    uid) == PackageManager.PERMISSION_GRANTED;
7653        }
7654
7655        @Override
7656        public String[] getPackagesForUid(int uid) {
7657            return mActivityManagerService.mContext.getPackageManager()
7658                    .getPackagesForUid(uid);
7659        }
7660
7661        @Override
7662        public boolean isRuntimePermission(String permission) {
7663            try {
7664                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7665                        .getPermissionInfo(permission, 0);
7666                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7667            } catch (NameNotFoundException nnfe) {
7668                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7669            }
7670            return false;
7671        }
7672    }
7673
7674    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7675        @Override
7676        public int checkComponentPermission(String permission, int pid, int uid,
7677                int owningUid, boolean exported) {
7678            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7679                    owningUid, exported);
7680        }
7681
7682        @Override
7683        public Object getAMSLock() {
7684            return ActivityManagerService.this;
7685        }
7686    }
7687
7688    /**
7689     * This can be called with or without the global lock held.
7690     */
7691    int checkComponentPermission(String permission, int pid, int uid,
7692            int owningUid, boolean exported) {
7693        if (pid == MY_PID) {
7694            return PackageManager.PERMISSION_GRANTED;
7695        }
7696        return ActivityManager.checkComponentPermission(permission, uid,
7697                owningUid, exported);
7698    }
7699
7700    /**
7701     * As the only public entry point for permissions checking, this method
7702     * can enforce the semantic that requesting a check on a null global
7703     * permission is automatically denied.  (Internally a null permission
7704     * string is used when calling {@link #checkComponentPermission} in cases
7705     * when only uid-based security is needed.)
7706     *
7707     * This can be called with or without the global lock held.
7708     */
7709    @Override
7710    public int checkPermission(String permission, int pid, int uid) {
7711        if (permission == null) {
7712            return PackageManager.PERMISSION_DENIED;
7713        }
7714        return checkComponentPermission(permission, pid, uid, -1, true);
7715    }
7716
7717    @Override
7718    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7719        if (permission == null) {
7720            return PackageManager.PERMISSION_DENIED;
7721        }
7722
7723        // We might be performing an operation on behalf of an indirect binder
7724        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7725        // client identity accordingly before proceeding.
7726        Identity tlsIdentity = sCallerIdentity.get();
7727        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7728            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7729                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7730            uid = tlsIdentity.uid;
7731            pid = tlsIdentity.pid;
7732        }
7733
7734        return checkComponentPermission(permission, pid, uid, -1, true);
7735    }
7736
7737    /**
7738     * Binder IPC calls go through the public entry point.
7739     * This can be called with or without the global lock held.
7740     */
7741    int checkCallingPermission(String permission) {
7742        return checkPermission(permission,
7743                Binder.getCallingPid(),
7744                UserHandle.getAppId(Binder.getCallingUid()));
7745    }
7746
7747    /**
7748     * This can be called with or without the global lock held.
7749     */
7750    void enforceCallingPermission(String permission, String func) {
7751        if (checkCallingPermission(permission)
7752                == PackageManager.PERMISSION_GRANTED) {
7753            return;
7754        }
7755
7756        String msg = "Permission Denial: " + func + " from pid="
7757                + Binder.getCallingPid()
7758                + ", uid=" + Binder.getCallingUid()
7759                + " requires " + permission;
7760        Slog.w(TAG, msg);
7761        throw new SecurityException(msg);
7762    }
7763
7764    /**
7765     * Determine if UID is holding permissions required to access {@link Uri} in
7766     * the given {@link ProviderInfo}. Final permission checking is always done
7767     * in {@link ContentProvider}.
7768     */
7769    private final boolean checkHoldingPermissionsLocked(
7770            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7771        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7772                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7773        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7774            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7775                    != PERMISSION_GRANTED) {
7776                return false;
7777            }
7778        }
7779        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7780    }
7781
7782    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7783            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7784        if (pi.applicationInfo.uid == uid) {
7785            return true;
7786        } else if (!pi.exported) {
7787            return false;
7788        }
7789
7790        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7791        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7792        try {
7793            // check if target holds top-level <provider> permissions
7794            if (!readMet && pi.readPermission != null && considerUidPermissions
7795                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7796                readMet = true;
7797            }
7798            if (!writeMet && pi.writePermission != null && considerUidPermissions
7799                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7800                writeMet = true;
7801            }
7802
7803            // track if unprotected read/write is allowed; any denied
7804            // <path-permission> below removes this ability
7805            boolean allowDefaultRead = pi.readPermission == null;
7806            boolean allowDefaultWrite = pi.writePermission == null;
7807
7808            // check if target holds any <path-permission> that match uri
7809            final PathPermission[] pps = pi.pathPermissions;
7810            if (pps != null) {
7811                final String path = grantUri.uri.getPath();
7812                int i = pps.length;
7813                while (i > 0 && (!readMet || !writeMet)) {
7814                    i--;
7815                    PathPermission pp = pps[i];
7816                    if (pp.match(path)) {
7817                        if (!readMet) {
7818                            final String pprperm = pp.getReadPermission();
7819                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7820                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7821                                    + ": match=" + pp.match(path)
7822                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7823                            if (pprperm != null) {
7824                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7825                                        == PERMISSION_GRANTED) {
7826                                    readMet = true;
7827                                } else {
7828                                    allowDefaultRead = false;
7829                                }
7830                            }
7831                        }
7832                        if (!writeMet) {
7833                            final String ppwperm = pp.getWritePermission();
7834                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7835                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7836                                    + ": match=" + pp.match(path)
7837                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7838                            if (ppwperm != null) {
7839                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7840                                        == PERMISSION_GRANTED) {
7841                                    writeMet = true;
7842                                } else {
7843                                    allowDefaultWrite = false;
7844                                }
7845                            }
7846                        }
7847                    }
7848                }
7849            }
7850
7851            // grant unprotected <provider> read/write, if not blocked by
7852            // <path-permission> above
7853            if (allowDefaultRead) readMet = true;
7854            if (allowDefaultWrite) writeMet = true;
7855
7856        } catch (RemoteException e) {
7857            return false;
7858        }
7859
7860        return readMet && writeMet;
7861    }
7862
7863    public int getAppStartMode(int uid, String packageName) {
7864        synchronized (this) {
7865            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7866        }
7867    }
7868
7869    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7870            boolean allowWhenForeground) {
7871        UidRecord uidRec = mActiveUids.get(uid);
7872        if (!mLenientBackgroundCheck) {
7873            if (!allowWhenForeground || uidRec == null
7874                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7875                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7876                        packageName) != AppOpsManager.MODE_ALLOWED) {
7877                    return ActivityManager.APP_START_MODE_DELAYED;
7878                }
7879            }
7880
7881        } else if (uidRec == null || uidRec.idle) {
7882            if (callingPid >= 0) {
7883                ProcessRecord proc;
7884                synchronized (mPidsSelfLocked) {
7885                    proc = mPidsSelfLocked.get(callingPid);
7886                }
7887                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7888                    // Whoever is instigating this is in the foreground, so we will allow it
7889                    // to go through.
7890                    return ActivityManager.APP_START_MODE_NORMAL;
7891                }
7892            }
7893            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7894                    != AppOpsManager.MODE_ALLOWED) {
7895                return ActivityManager.APP_START_MODE_DELAYED;
7896            }
7897        }
7898        return ActivityManager.APP_START_MODE_NORMAL;
7899    }
7900
7901    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7902        ProviderInfo pi = null;
7903        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7904        if (cpr != null) {
7905            pi = cpr.info;
7906        } else {
7907            try {
7908                pi = AppGlobals.getPackageManager().resolveContentProvider(
7909                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7910                        userHandle);
7911            } catch (RemoteException ex) {
7912            }
7913        }
7914        return pi;
7915    }
7916
7917    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7918        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7919        if (targetUris != null) {
7920            return targetUris.get(grantUri);
7921        }
7922        return null;
7923    }
7924
7925    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7926            String targetPkg, int targetUid, GrantUri grantUri) {
7927        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7928        if (targetUris == null) {
7929            targetUris = Maps.newArrayMap();
7930            mGrantedUriPermissions.put(targetUid, targetUris);
7931        }
7932
7933        UriPermission perm = targetUris.get(grantUri);
7934        if (perm == null) {
7935            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7936            targetUris.put(grantUri, perm);
7937        }
7938
7939        return perm;
7940    }
7941
7942    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7943            final int modeFlags) {
7944        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7945        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7946                : UriPermission.STRENGTH_OWNED;
7947
7948        // Root gets to do everything.
7949        if (uid == 0) {
7950            return true;
7951        }
7952
7953        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7954        if (perms == null) return false;
7955
7956        // First look for exact match
7957        final UriPermission exactPerm = perms.get(grantUri);
7958        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7959            return true;
7960        }
7961
7962        // No exact match, look for prefixes
7963        final int N = perms.size();
7964        for (int i = 0; i < N; i++) {
7965            final UriPermission perm = perms.valueAt(i);
7966            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7967                    && perm.getStrength(modeFlags) >= minStrength) {
7968                return true;
7969            }
7970        }
7971
7972        return false;
7973    }
7974
7975    /**
7976     * @param uri This uri must NOT contain an embedded userId.
7977     * @param userId The userId in which the uri is to be resolved.
7978     */
7979    @Override
7980    public int checkUriPermission(Uri uri, int pid, int uid,
7981            final int modeFlags, int userId, IBinder callerToken) {
7982        enforceNotIsolatedCaller("checkUriPermission");
7983
7984        // Another redirected-binder-call permissions check as in
7985        // {@link checkPermissionWithToken}.
7986        Identity tlsIdentity = sCallerIdentity.get();
7987        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7988            uid = tlsIdentity.uid;
7989            pid = tlsIdentity.pid;
7990        }
7991
7992        // Our own process gets to do everything.
7993        if (pid == MY_PID) {
7994            return PackageManager.PERMISSION_GRANTED;
7995        }
7996        synchronized (this) {
7997            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7998                    ? PackageManager.PERMISSION_GRANTED
7999                    : PackageManager.PERMISSION_DENIED;
8000        }
8001    }
8002
8003    /**
8004     * Check if the targetPkg can be granted permission to access uri by
8005     * the callingUid using the given modeFlags.  Throws a security exception
8006     * if callingUid is not allowed to do this.  Returns the uid of the target
8007     * if the URI permission grant should be performed; returns -1 if it is not
8008     * needed (for example targetPkg already has permission to access the URI).
8009     * If you already know the uid of the target, you can supply it in
8010     * lastTargetUid else set that to -1.
8011     */
8012    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8013            final int modeFlags, int lastTargetUid) {
8014        if (!Intent.isAccessUriMode(modeFlags)) {
8015            return -1;
8016        }
8017
8018        if (targetPkg != null) {
8019            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8020                    "Checking grant " + targetPkg + " permission to " + grantUri);
8021        }
8022
8023        final IPackageManager pm = AppGlobals.getPackageManager();
8024
8025        // If this is not a content: uri, we can't do anything with it.
8026        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8027            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8028                    "Can't grant URI permission for non-content URI: " + grantUri);
8029            return -1;
8030        }
8031
8032        final String authority = grantUri.uri.getAuthority();
8033        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8034                MATCH_DEBUG_TRIAGED_MISSING);
8035        if (pi == null) {
8036            Slog.w(TAG, "No content provider found for permission check: " +
8037                    grantUri.uri.toSafeString());
8038            return -1;
8039        }
8040
8041        int targetUid = lastTargetUid;
8042        if (targetUid < 0 && targetPkg != null) {
8043            try {
8044                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8045                        UserHandle.getUserId(callingUid));
8046                if (targetUid < 0) {
8047                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8048                            "Can't grant URI permission no uid for: " + targetPkg);
8049                    return -1;
8050                }
8051            } catch (RemoteException ex) {
8052                return -1;
8053            }
8054        }
8055
8056        if (targetUid >= 0) {
8057            // First...  does the target actually need this permission?
8058            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8059                // No need to grant the target this permission.
8060                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8061                        "Target " + targetPkg + " already has full permission to " + grantUri);
8062                return -1;
8063            }
8064        } else {
8065            // First...  there is no target package, so can anyone access it?
8066            boolean allowed = pi.exported;
8067            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8068                if (pi.readPermission != null) {
8069                    allowed = false;
8070                }
8071            }
8072            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8073                if (pi.writePermission != null) {
8074                    allowed = false;
8075                }
8076            }
8077            if (allowed) {
8078                return -1;
8079            }
8080        }
8081
8082        /* There is a special cross user grant if:
8083         * - The target is on another user.
8084         * - Apps on the current user can access the uri without any uid permissions.
8085         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8086         * grant uri permissions.
8087         */
8088        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8089                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8090                modeFlags, false /*without considering the uid permissions*/);
8091
8092        // Second...  is the provider allowing granting of URI permissions?
8093        if (!specialCrossUserGrant) {
8094            if (!pi.grantUriPermissions) {
8095                throw new SecurityException("Provider " + pi.packageName
8096                        + "/" + pi.name
8097                        + " does not allow granting of Uri permissions (uri "
8098                        + grantUri + ")");
8099            }
8100            if (pi.uriPermissionPatterns != null) {
8101                final int N = pi.uriPermissionPatterns.length;
8102                boolean allowed = false;
8103                for (int i=0; i<N; i++) {
8104                    if (pi.uriPermissionPatterns[i] != null
8105                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8106                        allowed = true;
8107                        break;
8108                    }
8109                }
8110                if (!allowed) {
8111                    throw new SecurityException("Provider " + pi.packageName
8112                            + "/" + pi.name
8113                            + " does not allow granting of permission to path of Uri "
8114                            + grantUri);
8115                }
8116            }
8117        }
8118
8119        // Third...  does the caller itself have permission to access
8120        // this uri?
8121        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8122            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8123                // Require they hold a strong enough Uri permission
8124                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8125                    throw new SecurityException("Uid " + callingUid
8126                            + " does not have permission to uri " + grantUri);
8127                }
8128            }
8129        }
8130        return targetUid;
8131    }
8132
8133    /**
8134     * @param uri This uri must NOT contain an embedded userId.
8135     * @param userId The userId in which the uri is to be resolved.
8136     */
8137    @Override
8138    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8139            final int modeFlags, int userId) {
8140        enforceNotIsolatedCaller("checkGrantUriPermission");
8141        synchronized(this) {
8142            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8143                    new GrantUri(userId, uri, false), modeFlags, -1);
8144        }
8145    }
8146
8147    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8148            final int modeFlags, UriPermissionOwner owner) {
8149        if (!Intent.isAccessUriMode(modeFlags)) {
8150            return;
8151        }
8152
8153        // So here we are: the caller has the assumed permission
8154        // to the uri, and the target doesn't.  Let's now give this to
8155        // the target.
8156
8157        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8159
8160        final String authority = grantUri.uri.getAuthority();
8161        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8162                MATCH_DEBUG_TRIAGED_MISSING);
8163        if (pi == null) {
8164            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8165            return;
8166        }
8167
8168        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8169            grantUri.prefix = true;
8170        }
8171        final UriPermission perm = findOrCreateUriPermissionLocked(
8172                pi.packageName, targetPkg, targetUid, grantUri);
8173        perm.grantModes(modeFlags, owner);
8174    }
8175
8176    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8177            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8178        if (targetPkg == null) {
8179            throw new NullPointerException("targetPkg");
8180        }
8181        int targetUid;
8182        final IPackageManager pm = AppGlobals.getPackageManager();
8183        try {
8184            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8185        } catch (RemoteException ex) {
8186            return;
8187        }
8188
8189        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8190                targetUid);
8191        if (targetUid < 0) {
8192            return;
8193        }
8194
8195        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8196                owner);
8197    }
8198
8199    static class NeededUriGrants extends ArrayList<GrantUri> {
8200        final String targetPkg;
8201        final int targetUid;
8202        final int flags;
8203
8204        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8205            this.targetPkg = targetPkg;
8206            this.targetUid = targetUid;
8207            this.flags = flags;
8208        }
8209    }
8210
8211    /**
8212     * Like checkGrantUriPermissionLocked, but takes an Intent.
8213     */
8214    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8215            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8216        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8218                + " clip=" + (intent != null ? intent.getClipData() : null)
8219                + " from " + intent + "; flags=0x"
8220                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8221
8222        if (targetPkg == null) {
8223            throw new NullPointerException("targetPkg");
8224        }
8225
8226        if (intent == null) {
8227            return null;
8228        }
8229        Uri data = intent.getData();
8230        ClipData clip = intent.getClipData();
8231        if (data == null && clip == null) {
8232            return null;
8233        }
8234        // Default userId for uris in the intent (if they don't specify it themselves)
8235        int contentUserHint = intent.getContentUserHint();
8236        if (contentUserHint == UserHandle.USER_CURRENT) {
8237            contentUserHint = UserHandle.getUserId(callingUid);
8238        }
8239        final IPackageManager pm = AppGlobals.getPackageManager();
8240        int targetUid;
8241        if (needed != null) {
8242            targetUid = needed.targetUid;
8243        } else {
8244            try {
8245                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8246                        targetUserId);
8247            } catch (RemoteException ex) {
8248                return null;
8249            }
8250            if (targetUid < 0) {
8251                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8252                        "Can't grant URI permission no uid for: " + targetPkg
8253                        + " on user " + targetUserId);
8254                return null;
8255            }
8256        }
8257        if (data != null) {
8258            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8259            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8260                    targetUid);
8261            if (targetUid > 0) {
8262                if (needed == null) {
8263                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8264                }
8265                needed.add(grantUri);
8266            }
8267        }
8268        if (clip != null) {
8269            for (int i=0; i<clip.getItemCount(); i++) {
8270                Uri uri = clip.getItemAt(i).getUri();
8271                if (uri != null) {
8272                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8273                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8274                            targetUid);
8275                    if (targetUid > 0) {
8276                        if (needed == null) {
8277                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8278                        }
8279                        needed.add(grantUri);
8280                    }
8281                } else {
8282                    Intent clipIntent = clip.getItemAt(i).getIntent();
8283                    if (clipIntent != null) {
8284                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8285                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8286                        if (newNeeded != null) {
8287                            needed = newNeeded;
8288                        }
8289                    }
8290                }
8291            }
8292        }
8293
8294        return needed;
8295    }
8296
8297    /**
8298     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8299     */
8300    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8301            UriPermissionOwner owner) {
8302        if (needed != null) {
8303            for (int i=0; i<needed.size(); i++) {
8304                GrantUri grantUri = needed.get(i);
8305                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8306                        grantUri, needed.flags, owner);
8307            }
8308        }
8309    }
8310
8311    void grantUriPermissionFromIntentLocked(int callingUid,
8312            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8313        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8314                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8315        if (needed == null) {
8316            return;
8317        }
8318
8319        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8320    }
8321
8322    /**
8323     * @param uri This uri must NOT contain an embedded userId.
8324     * @param userId The userId in which the uri is to be resolved.
8325     */
8326    @Override
8327    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8328            final int modeFlags, int userId) {
8329        enforceNotIsolatedCaller("grantUriPermission");
8330        GrantUri grantUri = new GrantUri(userId, uri, false);
8331        synchronized(this) {
8332            final ProcessRecord r = getRecordForAppLocked(caller);
8333            if (r == null) {
8334                throw new SecurityException("Unable to find app for caller "
8335                        + caller
8336                        + " when granting permission to uri " + grantUri);
8337            }
8338            if (targetPkg == null) {
8339                throw new IllegalArgumentException("null target");
8340            }
8341            if (grantUri == null) {
8342                throw new IllegalArgumentException("null uri");
8343            }
8344
8345            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8346                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8347                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8348                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8349
8350            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8351                    UserHandle.getUserId(r.uid));
8352        }
8353    }
8354
8355    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8356        if (perm.modeFlags == 0) {
8357            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8358                    perm.targetUid);
8359            if (perms != null) {
8360                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8361                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8362
8363                perms.remove(perm.uri);
8364                if (perms.isEmpty()) {
8365                    mGrantedUriPermissions.remove(perm.targetUid);
8366                }
8367            }
8368        }
8369    }
8370
8371    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8372        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8373                "Revoking all granted permissions to " + grantUri);
8374
8375        final IPackageManager pm = AppGlobals.getPackageManager();
8376        final String authority = grantUri.uri.getAuthority();
8377        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8378                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8379        if (pi == null) {
8380            Slog.w(TAG, "No content provider found for permission revoke: "
8381                    + grantUri.toSafeString());
8382            return;
8383        }
8384
8385        // Does the caller have this permission on the URI?
8386        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8387            // If they don't have direct access to the URI, then revoke any
8388            // ownerless URI permissions that have been granted to them.
8389            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8390            if (perms != null) {
8391                boolean persistChanged = false;
8392                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8393                    final UriPermission perm = it.next();
8394                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8395                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8396                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8397                                "Revoking non-owned " + perm.targetUid
8398                                + " permission to " + perm.uri);
8399                        persistChanged |= perm.revokeModes(
8400                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8401                        if (perm.modeFlags == 0) {
8402                            it.remove();
8403                        }
8404                    }
8405                }
8406                if (perms.isEmpty()) {
8407                    mGrantedUriPermissions.remove(callingUid);
8408                }
8409                if (persistChanged) {
8410                    schedulePersistUriGrants();
8411                }
8412            }
8413            return;
8414        }
8415
8416        boolean persistChanged = false;
8417
8418        // Go through all of the permissions and remove any that match.
8419        int N = mGrantedUriPermissions.size();
8420        for (int i = 0; i < N; i++) {
8421            final int targetUid = mGrantedUriPermissions.keyAt(i);
8422            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8423
8424            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8425                final UriPermission perm = it.next();
8426                if (perm.uri.sourceUserId == grantUri.sourceUserId
8427                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8428                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8429                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8430                    persistChanged |= perm.revokeModes(
8431                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8432                    if (perm.modeFlags == 0) {
8433                        it.remove();
8434                    }
8435                }
8436            }
8437
8438            if (perms.isEmpty()) {
8439                mGrantedUriPermissions.remove(targetUid);
8440                N--;
8441                i--;
8442            }
8443        }
8444
8445        if (persistChanged) {
8446            schedulePersistUriGrants();
8447        }
8448    }
8449
8450    /**
8451     * @param uri This uri must NOT contain an embedded userId.
8452     * @param userId The userId in which the uri is to be resolved.
8453     */
8454    @Override
8455    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8456            int userId) {
8457        enforceNotIsolatedCaller("revokeUriPermission");
8458        synchronized(this) {
8459            final ProcessRecord r = getRecordForAppLocked(caller);
8460            if (r == null) {
8461                throw new SecurityException("Unable to find app for caller "
8462                        + caller
8463                        + " when revoking permission to uri " + uri);
8464            }
8465            if (uri == null) {
8466                Slog.w(TAG, "revokeUriPermission: null uri");
8467                return;
8468            }
8469
8470            if (!Intent.isAccessUriMode(modeFlags)) {
8471                return;
8472            }
8473
8474            final String authority = uri.getAuthority();
8475            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8476                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8477            if (pi == null) {
8478                Slog.w(TAG, "No content provider found for permission revoke: "
8479                        + uri.toSafeString());
8480                return;
8481            }
8482
8483            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8484        }
8485    }
8486
8487    /**
8488     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8489     * given package.
8490     *
8491     * @param packageName Package name to match, or {@code null} to apply to all
8492     *            packages.
8493     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8494     *            to all users.
8495     * @param persistable If persistable grants should be removed.
8496     */
8497    private void removeUriPermissionsForPackageLocked(
8498            String packageName, int userHandle, boolean persistable) {
8499        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8500            throw new IllegalArgumentException("Must narrow by either package or user");
8501        }
8502
8503        boolean persistChanged = false;
8504
8505        int N = mGrantedUriPermissions.size();
8506        for (int i = 0; i < N; i++) {
8507            final int targetUid = mGrantedUriPermissions.keyAt(i);
8508            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8509
8510            // Only inspect grants matching user
8511            if (userHandle == UserHandle.USER_ALL
8512                    || userHandle == UserHandle.getUserId(targetUid)) {
8513                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8514                    final UriPermission perm = it.next();
8515
8516                    // Only inspect grants matching package
8517                    if (packageName == null || perm.sourcePkg.equals(packageName)
8518                            || perm.targetPkg.equals(packageName)) {
8519                        persistChanged |= perm.revokeModes(persistable
8520                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8521
8522                        // Only remove when no modes remain; any persisted grants
8523                        // will keep this alive.
8524                        if (perm.modeFlags == 0) {
8525                            it.remove();
8526                        }
8527                    }
8528                }
8529
8530                if (perms.isEmpty()) {
8531                    mGrantedUriPermissions.remove(targetUid);
8532                    N--;
8533                    i--;
8534                }
8535            }
8536        }
8537
8538        if (persistChanged) {
8539            schedulePersistUriGrants();
8540        }
8541    }
8542
8543    @Override
8544    public IBinder newUriPermissionOwner(String name) {
8545        enforceNotIsolatedCaller("newUriPermissionOwner");
8546        synchronized(this) {
8547            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8548            return owner.getExternalTokenLocked();
8549        }
8550    }
8551
8552    @Override
8553    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8554        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8555        synchronized(this) {
8556            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8557            if (r == null) {
8558                throw new IllegalArgumentException("Activity does not exist; token="
8559                        + activityToken);
8560            }
8561            return r.getUriPermissionsLocked().getExternalTokenLocked();
8562        }
8563    }
8564    /**
8565     * @param uri This uri must NOT contain an embedded userId.
8566     * @param sourceUserId The userId in which the uri is to be resolved.
8567     * @param targetUserId The userId of the app that receives the grant.
8568     */
8569    @Override
8570    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8571            final int modeFlags, int sourceUserId, int targetUserId) {
8572        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8573                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8574                "grantUriPermissionFromOwner", null);
8575        synchronized(this) {
8576            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8577            if (owner == null) {
8578                throw new IllegalArgumentException("Unknown owner: " + token);
8579            }
8580            if (fromUid != Binder.getCallingUid()) {
8581                if (Binder.getCallingUid() != Process.myUid()) {
8582                    // Only system code can grant URI permissions on behalf
8583                    // of other users.
8584                    throw new SecurityException("nice try");
8585                }
8586            }
8587            if (targetPkg == null) {
8588                throw new IllegalArgumentException("null target");
8589            }
8590            if (uri == null) {
8591                throw new IllegalArgumentException("null uri");
8592            }
8593
8594            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8595                    modeFlags, owner, targetUserId);
8596        }
8597    }
8598
8599    /**
8600     * @param uri This uri must NOT contain an embedded userId.
8601     * @param userId The userId in which the uri is to be resolved.
8602     */
8603    @Override
8604    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8605        synchronized(this) {
8606            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8607            if (owner == null) {
8608                throw new IllegalArgumentException("Unknown owner: " + token);
8609            }
8610
8611            if (uri == null) {
8612                owner.removeUriPermissionsLocked(mode);
8613            } else {
8614                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8615                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8616            }
8617        }
8618    }
8619
8620    private void schedulePersistUriGrants() {
8621        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8622            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8623                    10 * DateUtils.SECOND_IN_MILLIS);
8624        }
8625    }
8626
8627    private void writeGrantedUriPermissions() {
8628        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8629
8630        // Snapshot permissions so we can persist without lock
8631        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8632        synchronized (this) {
8633            final int size = mGrantedUriPermissions.size();
8634            for (int i = 0; i < size; i++) {
8635                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8636                for (UriPermission perm : perms.values()) {
8637                    if (perm.persistedModeFlags != 0) {
8638                        persist.add(perm.snapshot());
8639                    }
8640                }
8641            }
8642        }
8643
8644        FileOutputStream fos = null;
8645        try {
8646            fos = mGrantFile.startWrite();
8647
8648            XmlSerializer out = new FastXmlSerializer();
8649            out.setOutput(fos, StandardCharsets.UTF_8.name());
8650            out.startDocument(null, true);
8651            out.startTag(null, TAG_URI_GRANTS);
8652            for (UriPermission.Snapshot perm : persist) {
8653                out.startTag(null, TAG_URI_GRANT);
8654                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8655                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8656                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8657                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8658                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8659                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8660                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8661                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8662                out.endTag(null, TAG_URI_GRANT);
8663            }
8664            out.endTag(null, TAG_URI_GRANTS);
8665            out.endDocument();
8666
8667            mGrantFile.finishWrite(fos);
8668        } catch (IOException e) {
8669            if (fos != null) {
8670                mGrantFile.failWrite(fos);
8671            }
8672        }
8673    }
8674
8675    private void readGrantedUriPermissionsLocked() {
8676        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8677
8678        final long now = System.currentTimeMillis();
8679
8680        FileInputStream fis = null;
8681        try {
8682            fis = mGrantFile.openRead();
8683            final XmlPullParser in = Xml.newPullParser();
8684            in.setInput(fis, StandardCharsets.UTF_8.name());
8685
8686            int type;
8687            while ((type = in.next()) != END_DOCUMENT) {
8688                final String tag = in.getName();
8689                if (type == START_TAG) {
8690                    if (TAG_URI_GRANT.equals(tag)) {
8691                        final int sourceUserId;
8692                        final int targetUserId;
8693                        final int userHandle = readIntAttribute(in,
8694                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8695                        if (userHandle != UserHandle.USER_NULL) {
8696                            // For backwards compatibility.
8697                            sourceUserId = userHandle;
8698                            targetUserId = userHandle;
8699                        } else {
8700                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8701                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8702                        }
8703                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8704                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8705                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8706                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8707                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8708                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8709
8710                        // Sanity check that provider still belongs to source package
8711                        // Both direct boot aware and unaware packages are fine as we
8712                        // will do filtering at query time to avoid multiple parsing.
8713                        final ProviderInfo pi = getProviderInfoLocked(
8714                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8715                                        | MATCH_DIRECT_BOOT_UNAWARE);
8716                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8717                            int targetUid = -1;
8718                            try {
8719                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8720                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8721                            } catch (RemoteException e) {
8722                            }
8723                            if (targetUid != -1) {
8724                                final UriPermission perm = findOrCreateUriPermissionLocked(
8725                                        sourcePkg, targetPkg, targetUid,
8726                                        new GrantUri(sourceUserId, uri, prefix));
8727                                perm.initPersistedModes(modeFlags, createdTime);
8728                            }
8729                        } else {
8730                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8731                                    + " but instead found " + pi);
8732                        }
8733                    }
8734                }
8735            }
8736        } catch (FileNotFoundException e) {
8737            // Missing grants is okay
8738        } catch (IOException e) {
8739            Slog.wtf(TAG, "Failed reading Uri grants", e);
8740        } catch (XmlPullParserException e) {
8741            Slog.wtf(TAG, "Failed reading Uri grants", e);
8742        } finally {
8743            IoUtils.closeQuietly(fis);
8744        }
8745    }
8746
8747    /**
8748     * @param uri This uri must NOT contain an embedded userId.
8749     * @param userId The userId in which the uri is to be resolved.
8750     */
8751    @Override
8752    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8753        enforceNotIsolatedCaller("takePersistableUriPermission");
8754
8755        Preconditions.checkFlagsArgument(modeFlags,
8756                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8757
8758        synchronized (this) {
8759            final int callingUid = Binder.getCallingUid();
8760            boolean persistChanged = false;
8761            GrantUri grantUri = new GrantUri(userId, uri, false);
8762
8763            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8764                    new GrantUri(userId, uri, false));
8765            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8766                    new GrantUri(userId, uri, true));
8767
8768            final boolean exactValid = (exactPerm != null)
8769                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8770            final boolean prefixValid = (prefixPerm != null)
8771                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8772
8773            if (!(exactValid || prefixValid)) {
8774                throw new SecurityException("No persistable permission grants found for UID "
8775                        + callingUid + " and Uri " + grantUri.toSafeString());
8776            }
8777
8778            if (exactValid) {
8779                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8780            }
8781            if (prefixValid) {
8782                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8783            }
8784
8785            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8786
8787            if (persistChanged) {
8788                schedulePersistUriGrants();
8789            }
8790        }
8791    }
8792
8793    /**
8794     * @param uri This uri must NOT contain an embedded userId.
8795     * @param userId The userId in which the uri is to be resolved.
8796     */
8797    @Override
8798    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8799        enforceNotIsolatedCaller("releasePersistableUriPermission");
8800
8801        Preconditions.checkFlagsArgument(modeFlags,
8802                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8803
8804        synchronized (this) {
8805            final int callingUid = Binder.getCallingUid();
8806            boolean persistChanged = false;
8807
8808            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8809                    new GrantUri(userId, uri, false));
8810            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8811                    new GrantUri(userId, uri, true));
8812            if (exactPerm == null && prefixPerm == null) {
8813                throw new SecurityException("No permission grants found for UID " + callingUid
8814                        + " and Uri " + uri.toSafeString());
8815            }
8816
8817            if (exactPerm != null) {
8818                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8819                removeUriPermissionIfNeededLocked(exactPerm);
8820            }
8821            if (prefixPerm != null) {
8822                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8823                removeUriPermissionIfNeededLocked(prefixPerm);
8824            }
8825
8826            if (persistChanged) {
8827                schedulePersistUriGrants();
8828            }
8829        }
8830    }
8831
8832    /**
8833     * Prune any older {@link UriPermission} for the given UID until outstanding
8834     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8835     *
8836     * @return if any mutations occured that require persisting.
8837     */
8838    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8839        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8840        if (perms == null) return false;
8841        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8842
8843        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8844        for (UriPermission perm : perms.values()) {
8845            if (perm.persistedModeFlags != 0) {
8846                persisted.add(perm);
8847            }
8848        }
8849
8850        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8851        if (trimCount <= 0) return false;
8852
8853        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8854        for (int i = 0; i < trimCount; i++) {
8855            final UriPermission perm = persisted.get(i);
8856
8857            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8858                    "Trimming grant created at " + perm.persistedCreateTime);
8859
8860            perm.releasePersistableModes(~0);
8861            removeUriPermissionIfNeededLocked(perm);
8862        }
8863
8864        return true;
8865    }
8866
8867    @Override
8868    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8869            String packageName, boolean incoming) {
8870        enforceNotIsolatedCaller("getPersistedUriPermissions");
8871        Preconditions.checkNotNull(packageName, "packageName");
8872
8873        final int callingUid = Binder.getCallingUid();
8874        final int callingUserId = UserHandle.getUserId(callingUid);
8875        final IPackageManager pm = AppGlobals.getPackageManager();
8876        try {
8877            final int packageUid = pm.getPackageUid(packageName,
8878                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8879            if (packageUid != callingUid) {
8880                throw new SecurityException(
8881                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8882            }
8883        } catch (RemoteException e) {
8884            throw new SecurityException("Failed to verify package name ownership");
8885        }
8886
8887        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8888        synchronized (this) {
8889            if (incoming) {
8890                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8891                        callingUid);
8892                if (perms == null) {
8893                    Slog.w(TAG, "No permission grants found for " + packageName);
8894                } else {
8895                    for (UriPermission perm : perms.values()) {
8896                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8897                            result.add(perm.buildPersistedPublicApiObject());
8898                        }
8899                    }
8900                }
8901            } else {
8902                final int size = mGrantedUriPermissions.size();
8903                for (int i = 0; i < size; i++) {
8904                    final ArrayMap<GrantUri, UriPermission> perms =
8905                            mGrantedUriPermissions.valueAt(i);
8906                    for (UriPermission perm : perms.values()) {
8907                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8908                            result.add(perm.buildPersistedPublicApiObject());
8909                        }
8910                    }
8911                }
8912            }
8913        }
8914        return new ParceledListSlice<android.content.UriPermission>(result);
8915    }
8916
8917    @Override
8918    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8919            String packageName, int userId) {
8920        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8921                "getGrantedUriPermissions");
8922
8923        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8924        synchronized (this) {
8925            final int size = mGrantedUriPermissions.size();
8926            for (int i = 0; i < size; i++) {
8927                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8928                for (UriPermission perm : perms.values()) {
8929                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8930                            && perm.persistedModeFlags != 0) {
8931                        result.add(perm.buildPersistedPublicApiObject());
8932                    }
8933                }
8934            }
8935        }
8936        return new ParceledListSlice<android.content.UriPermission>(result);
8937    }
8938
8939    @Override
8940    public void clearGrantedUriPermissions(String packageName, int userId) {
8941        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8942                "clearGrantedUriPermissions");
8943        removeUriPermissionsForPackageLocked(packageName, userId, true);
8944    }
8945
8946    @Override
8947    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8948        synchronized (this) {
8949            ProcessRecord app =
8950                who != null ? getRecordForAppLocked(who) : null;
8951            if (app == null) return;
8952
8953            Message msg = Message.obtain();
8954            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8955            msg.obj = app;
8956            msg.arg1 = waiting ? 1 : 0;
8957            mUiHandler.sendMessage(msg);
8958        }
8959    }
8960
8961    @Override
8962    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8963        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8964        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8965        outInfo.availMem = Process.getFreeMemory();
8966        outInfo.totalMem = Process.getTotalMemory();
8967        outInfo.threshold = homeAppMem;
8968        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8969        outInfo.hiddenAppThreshold = cachedAppMem;
8970        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8971                ProcessList.SERVICE_ADJ);
8972        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8973                ProcessList.VISIBLE_APP_ADJ);
8974        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8975                ProcessList.FOREGROUND_APP_ADJ);
8976    }
8977
8978    // =========================================================
8979    // TASK MANAGEMENT
8980    // =========================================================
8981
8982    @Override
8983    public List<IAppTask> getAppTasks(String callingPackage) {
8984        int callingUid = Binder.getCallingUid();
8985        long ident = Binder.clearCallingIdentity();
8986
8987        synchronized(this) {
8988            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8989            try {
8990                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8991
8992                final int N = mRecentTasks.size();
8993                for (int i = 0; i < N; i++) {
8994                    TaskRecord tr = mRecentTasks.get(i);
8995                    // Skip tasks that do not match the caller.  We don't need to verify
8996                    // callingPackage, because we are also limiting to callingUid and know
8997                    // that will limit to the correct security sandbox.
8998                    if (tr.effectiveUid != callingUid) {
8999                        continue;
9000                    }
9001                    Intent intent = tr.getBaseIntent();
9002                    if (intent == null ||
9003                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9004                        continue;
9005                    }
9006                    ActivityManager.RecentTaskInfo taskInfo =
9007                            createRecentTaskInfoFromTaskRecord(tr);
9008                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9009                    list.add(taskImpl);
9010                }
9011            } finally {
9012                Binder.restoreCallingIdentity(ident);
9013            }
9014            return list;
9015        }
9016    }
9017
9018    @Override
9019    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9020        final int callingUid = Binder.getCallingUid();
9021        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9022
9023        synchronized(this) {
9024            if (DEBUG_ALL) Slog.v(
9025                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9026
9027            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9028                    callingUid);
9029
9030            // TODO: Improve with MRU list from all ActivityStacks.
9031            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9032        }
9033
9034        return list;
9035    }
9036
9037    /**
9038     * Creates a new RecentTaskInfo from a TaskRecord.
9039     */
9040    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9041        // Update the task description to reflect any changes in the task stack
9042        tr.updateTaskDescription();
9043
9044        // Compose the recent task info
9045        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9046        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9047        rti.persistentId = tr.taskId;
9048        rti.baseIntent = new Intent(tr.getBaseIntent());
9049        rti.origActivity = tr.origActivity;
9050        rti.realActivity = tr.realActivity;
9051        rti.description = tr.lastDescription;
9052        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9053        rti.userId = tr.userId;
9054        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9055        rti.firstActiveTime = tr.firstActiveTime;
9056        rti.lastActiveTime = tr.lastActiveTime;
9057        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9058        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9059        rti.numActivities = 0;
9060        if (tr.mBounds != null) {
9061            rti.bounds = new Rect(tr.mBounds);
9062        }
9063        rti.isDockable = tr.canGoInDockedStack();
9064        rti.resizeMode = tr.mResizeMode;
9065
9066        ActivityRecord base = null;
9067        ActivityRecord top = null;
9068        ActivityRecord tmp;
9069
9070        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9071            tmp = tr.mActivities.get(i);
9072            if (tmp.finishing) {
9073                continue;
9074            }
9075            base = tmp;
9076            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9077                top = base;
9078            }
9079            rti.numActivities++;
9080        }
9081
9082        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9083        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9084
9085        return rti;
9086    }
9087
9088    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9089        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9090                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9091        if (!allowed) {
9092            if (checkPermission(android.Manifest.permission.GET_TASKS,
9093                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9094                // Temporary compatibility: some existing apps on the system image may
9095                // still be requesting the old permission and not switched to the new
9096                // one; if so, we'll still allow them full access.  This means we need
9097                // to see if they are holding the old permission and are a system app.
9098                try {
9099                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9100                        allowed = true;
9101                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9102                                + " is using old GET_TASKS but privileged; allowing");
9103                    }
9104                } catch (RemoteException e) {
9105                }
9106            }
9107        }
9108        if (!allowed) {
9109            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9110                    + " does not hold REAL_GET_TASKS; limiting output");
9111        }
9112        return allowed;
9113    }
9114
9115    @Override
9116    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9117            int userId) {
9118        final int callingUid = Binder.getCallingUid();
9119        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9120                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9121
9122        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9123        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9124        synchronized (this) {
9125            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9126                    callingUid);
9127            final boolean detailed = checkCallingPermission(
9128                    android.Manifest.permission.GET_DETAILED_TASKS)
9129                    == PackageManager.PERMISSION_GRANTED;
9130
9131            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9132                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9133                return ParceledListSlice.emptyList();
9134            }
9135            mRecentTasks.loadUserRecentsLocked(userId);
9136
9137            final int recentsCount = mRecentTasks.size();
9138            ArrayList<ActivityManager.RecentTaskInfo> res =
9139                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9140
9141            final Set<Integer> includedUsers;
9142            if (includeProfiles) {
9143                includedUsers = mUserController.getProfileIds(userId);
9144            } else {
9145                includedUsers = new HashSet<>();
9146            }
9147            includedUsers.add(Integer.valueOf(userId));
9148
9149            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9150                TaskRecord tr = mRecentTasks.get(i);
9151                // Only add calling user or related users recent tasks
9152                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9153                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9154                    continue;
9155                }
9156
9157                if (tr.realActivitySuspended) {
9158                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9159                    continue;
9160                }
9161
9162                // Return the entry if desired by the caller.  We always return
9163                // the first entry, because callers always expect this to be the
9164                // foreground app.  We may filter others if the caller has
9165                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9166                // we should exclude the entry.
9167
9168                if (i == 0
9169                        || withExcluded
9170                        || (tr.intent == null)
9171                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9172                                == 0)) {
9173                    if (!allowed) {
9174                        // If the caller doesn't have the GET_TASKS permission, then only
9175                        // allow them to see a small subset of tasks -- their own and home.
9176                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9177                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9178                            continue;
9179                        }
9180                    }
9181                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9182                        if (tr.stack != null && tr.stack.isHomeStack()) {
9183                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9184                                    "Skipping, home stack task: " + tr);
9185                            continue;
9186                        }
9187                    }
9188                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9189                        final ActivityStack stack = tr.stack;
9190                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9191                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9192                                    "Skipping, top task in docked stack: " + tr);
9193                            continue;
9194                        }
9195                    }
9196                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9197                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9198                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9199                                    "Skipping, pinned stack task: " + tr);
9200                            continue;
9201                        }
9202                    }
9203                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9204                        // Don't include auto remove tasks that are finished or finishing.
9205                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9206                                "Skipping, auto-remove without activity: " + tr);
9207                        continue;
9208                    }
9209                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9210                            && !tr.isAvailable) {
9211                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9212                                "Skipping, unavail real act: " + tr);
9213                        continue;
9214                    }
9215
9216                    if (!tr.mUserSetupComplete) {
9217                        // Don't include task launched while user is not done setting-up.
9218                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9219                                "Skipping, user setup not complete: " + tr);
9220                        continue;
9221                    }
9222
9223                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9224                    if (!detailed) {
9225                        rti.baseIntent.replaceExtras((Bundle)null);
9226                    }
9227
9228                    res.add(rti);
9229                    maxNum--;
9230                }
9231            }
9232            return new ParceledListSlice<>(res);
9233        }
9234    }
9235
9236    @Override
9237    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9238        synchronized (this) {
9239            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9240                    "getTaskThumbnail()");
9241            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9242                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9243            if (tr != null) {
9244                return tr.getTaskThumbnailLocked();
9245            }
9246        }
9247        return null;
9248    }
9249
9250    @Override
9251    public int addAppTask(IBinder activityToken, Intent intent,
9252            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9253        final int callingUid = Binder.getCallingUid();
9254        final long callingIdent = Binder.clearCallingIdentity();
9255
9256        try {
9257            synchronized (this) {
9258                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9259                if (r == null) {
9260                    throw new IllegalArgumentException("Activity does not exist; token="
9261                            + activityToken);
9262                }
9263                ComponentName comp = intent.getComponent();
9264                if (comp == null) {
9265                    throw new IllegalArgumentException("Intent " + intent
9266                            + " must specify explicit component");
9267                }
9268                if (thumbnail.getWidth() != mThumbnailWidth
9269                        || thumbnail.getHeight() != mThumbnailHeight) {
9270                    throw new IllegalArgumentException("Bad thumbnail size: got "
9271                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9272                            + mThumbnailWidth + "x" + mThumbnailHeight);
9273                }
9274                if (intent.getSelector() != null) {
9275                    intent.setSelector(null);
9276                }
9277                if (intent.getSourceBounds() != null) {
9278                    intent.setSourceBounds(null);
9279                }
9280                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9281                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9282                        // The caller has added this as an auto-remove task...  that makes no
9283                        // sense, so turn off auto-remove.
9284                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9285                    }
9286                }
9287                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9288                    mLastAddedTaskActivity = null;
9289                }
9290                ActivityInfo ainfo = mLastAddedTaskActivity;
9291                if (ainfo == null) {
9292                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9293                            comp, 0, UserHandle.getUserId(callingUid));
9294                    if (ainfo.applicationInfo.uid != callingUid) {
9295                        throw new SecurityException(
9296                                "Can't add task for another application: target uid="
9297                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9298                    }
9299                }
9300
9301                // Use the full screen as the context for the task thumbnail
9302                final Point displaySize = new Point();
9303                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9304                r.task.stack.getDisplaySize(displaySize);
9305                thumbnailInfo.taskWidth = displaySize.x;
9306                thumbnailInfo.taskHeight = displaySize.y;
9307                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9308
9309                TaskRecord task = new TaskRecord(this,
9310                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9311                        ainfo, intent, description, thumbnailInfo);
9312
9313                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9314                if (trimIdx >= 0) {
9315                    // If this would have caused a trim, then we'll abort because that
9316                    // means it would be added at the end of the list but then just removed.
9317                    return INVALID_TASK_ID;
9318                }
9319
9320                final int N = mRecentTasks.size();
9321                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9322                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9323                    tr.removedFromRecents();
9324                }
9325
9326                task.inRecents = true;
9327                mRecentTasks.add(task);
9328                r.task.stack.addTask(task, false, "addAppTask");
9329
9330                task.setLastThumbnailLocked(thumbnail);
9331                task.freeLastThumbnail();
9332
9333                return task.taskId;
9334            }
9335        } finally {
9336            Binder.restoreCallingIdentity(callingIdent);
9337        }
9338    }
9339
9340    @Override
9341    public Point getAppTaskThumbnailSize() {
9342        synchronized (this) {
9343            return new Point(mThumbnailWidth,  mThumbnailHeight);
9344        }
9345    }
9346
9347    @Override
9348    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9349        synchronized (this) {
9350            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9351            if (r != null) {
9352                r.setTaskDescription(td);
9353                r.task.updateTaskDescription();
9354            }
9355        }
9356    }
9357
9358    @Override
9359    public void setTaskResizeable(int taskId, int resizeableMode) {
9360        synchronized (this) {
9361            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9362                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9363            if (task == null) {
9364                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9365                return;
9366            }
9367            if (task.mResizeMode != resizeableMode) {
9368                task.mResizeMode = resizeableMode;
9369                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9370                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9371                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9372            }
9373        }
9374    }
9375
9376    @Override
9377    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9378        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9379        long ident = Binder.clearCallingIdentity();
9380        try {
9381            synchronized (this) {
9382                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9383                if (task == null) {
9384                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9385                    return;
9386                }
9387                int stackId = task.stack.mStackId;
9388                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9389                // in crop windows resize mode or if the task size is affected by the docked stack
9390                // changing size. No need to update configuration.
9391                if (bounds != null && task.inCropWindowsResizeMode()
9392                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9393                    mWindowManager.scrollTask(task.taskId, bounds);
9394                    return;
9395                }
9396
9397                // Place the task in the right stack if it isn't there already based on
9398                // the requested bounds.
9399                // The stack transition logic is:
9400                // - a null bounds on a freeform task moves that task to fullscreen
9401                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9402                //   that task to freeform
9403                // - otherwise the task is not moved
9404                if (!StackId.isTaskResizeAllowed(stackId)) {
9405                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9406                }
9407                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9408                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9409                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9410                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9411                }
9412                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9413                if (stackId != task.stack.mStackId) {
9414                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9415                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9416                    preserveWindow = false;
9417                }
9418
9419                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9420                        false /* deferResume */);
9421            }
9422        } finally {
9423            Binder.restoreCallingIdentity(ident);
9424        }
9425    }
9426
9427    @Override
9428    public Rect getTaskBounds(int taskId) {
9429        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9430        long ident = Binder.clearCallingIdentity();
9431        Rect rect = new Rect();
9432        try {
9433            synchronized (this) {
9434                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9435                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9436                if (task == null) {
9437                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9438                    return rect;
9439                }
9440                if (task.stack != null) {
9441                    // Return the bounds from window manager since it will be adjusted for various
9442                    // things like the presense of a docked stack for tasks that aren't resizeable.
9443                    mWindowManager.getTaskBounds(task.taskId, rect);
9444                } else {
9445                    // Task isn't in window manager yet since it isn't associated with a stack.
9446                    // Return the persist value from activity manager
9447                    if (task.mBounds != null) {
9448                        rect.set(task.mBounds);
9449                    } else if (task.mLastNonFullscreenBounds != null) {
9450                        rect.set(task.mLastNonFullscreenBounds);
9451                    }
9452                }
9453            }
9454        } finally {
9455            Binder.restoreCallingIdentity(ident);
9456        }
9457        return rect;
9458    }
9459
9460    @Override
9461    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9462        if (userId != UserHandle.getCallingUserId()) {
9463            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9464                    "getTaskDescriptionIcon");
9465        }
9466        final File passedIconFile = new File(filePath);
9467        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9468                passedIconFile.getName());
9469        if (!legitIconFile.getPath().equals(filePath)
9470                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9471            throw new IllegalArgumentException("Bad file path: " + filePath
9472                    + " passed for userId " + userId);
9473        }
9474        return mRecentTasks.getTaskDescriptionIcon(filePath);
9475    }
9476
9477    @Override
9478    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9479            throws RemoteException {
9480        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9481                opts.getCustomInPlaceResId() == 0) {
9482            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9483                    "with valid animation");
9484        }
9485        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9486        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9487                opts.getCustomInPlaceResId());
9488        mWindowManager.executeAppTransition();
9489    }
9490
9491    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9492            boolean removeFromRecents) {
9493        if (removeFromRecents) {
9494            mRecentTasks.remove(tr);
9495            tr.removedFromRecents();
9496        }
9497        ComponentName component = tr.getBaseIntent().getComponent();
9498        if (component == null) {
9499            Slog.w(TAG, "No component for base intent of task: " + tr);
9500            return;
9501        }
9502
9503        // Find any running services associated with this app and stop if needed.
9504        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9505
9506        if (!killProcess) {
9507            return;
9508        }
9509
9510        // Determine if the process(es) for this task should be killed.
9511        final String pkg = component.getPackageName();
9512        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9513        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9514        for (int i = 0; i < pmap.size(); i++) {
9515
9516            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9517            for (int j = 0; j < uids.size(); j++) {
9518                ProcessRecord proc = uids.valueAt(j);
9519                if (proc.userId != tr.userId) {
9520                    // Don't kill process for a different user.
9521                    continue;
9522                }
9523                if (proc == mHomeProcess) {
9524                    // Don't kill the home process along with tasks from the same package.
9525                    continue;
9526                }
9527                if (!proc.pkgList.containsKey(pkg)) {
9528                    // Don't kill process that is not associated with this task.
9529                    continue;
9530                }
9531
9532                for (int k = 0; k < proc.activities.size(); k++) {
9533                    TaskRecord otherTask = proc.activities.get(k).task;
9534                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9535                        // Don't kill process(es) that has an activity in a different task that is
9536                        // also in recents.
9537                        return;
9538                    }
9539                }
9540
9541                if (proc.foregroundServices) {
9542                    // Don't kill process(es) with foreground service.
9543                    return;
9544                }
9545
9546                // Add process to kill list.
9547                procsToKill.add(proc);
9548            }
9549        }
9550
9551        // Kill the running processes.
9552        for (int i = 0; i < procsToKill.size(); i++) {
9553            ProcessRecord pr = procsToKill.get(i);
9554            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9555                    && pr.curReceiver == null) {
9556                pr.kill("remove task", true);
9557            } else {
9558                // We delay killing processes that are not in the background or running a receiver.
9559                pr.waitingToKill = "remove task";
9560            }
9561        }
9562    }
9563
9564    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9565        // Remove all tasks with activities in the specified package from the list of recent tasks
9566        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9567            TaskRecord tr = mRecentTasks.get(i);
9568            if (tr.userId != userId) continue;
9569
9570            ComponentName cn = tr.intent.getComponent();
9571            if (cn != null && cn.getPackageName().equals(packageName)) {
9572                // If the package name matches, remove the task.
9573                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9574            }
9575        }
9576    }
9577
9578    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9579            int userId) {
9580
9581        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9582            TaskRecord tr = mRecentTasks.get(i);
9583            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9584                continue;
9585            }
9586
9587            ComponentName cn = tr.intent.getComponent();
9588            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9589                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9590            if (sameComponent) {
9591                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9592            }
9593        }
9594    }
9595
9596    /**
9597     * Removes the task with the specified task id.
9598     *
9599     * @param taskId Identifier of the task to be removed.
9600     * @param killProcess Kill any process associated with the task if possible.
9601     * @param removeFromRecents Whether to also remove the task from recents.
9602     * @return Returns true if the given task was found and removed.
9603     */
9604    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9605            boolean removeFromRecents) {
9606        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9607                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9608        if (tr != null) {
9609            tr.removeTaskActivitiesLocked();
9610            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9611            if (tr.isPersistable) {
9612                notifyTaskPersisterLocked(null, true);
9613            }
9614            return true;
9615        }
9616        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9617        return false;
9618    }
9619
9620    @Override
9621    public void removeStack(int stackId) {
9622        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9623        if (stackId == HOME_STACK_ID) {
9624            throw new IllegalArgumentException("Removing home stack is not allowed.");
9625        }
9626
9627        synchronized (this) {
9628            final long ident = Binder.clearCallingIdentity();
9629            try {
9630                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9631                if (stack == null) {
9632                    return;
9633                }
9634                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9635                for (int i = tasks.size() - 1; i >= 0; i--) {
9636                    removeTaskByIdLocked(
9637                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9638                }
9639            } finally {
9640                Binder.restoreCallingIdentity(ident);
9641            }
9642        }
9643    }
9644
9645    @Override
9646    public boolean removeTask(int taskId) {
9647        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9648        synchronized (this) {
9649            final long ident = Binder.clearCallingIdentity();
9650            try {
9651                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9652            } finally {
9653                Binder.restoreCallingIdentity(ident);
9654            }
9655        }
9656    }
9657
9658    /**
9659     * TODO: Add mController hook
9660     */
9661    @Override
9662    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9663        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9664
9665        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9666        synchronized(this) {
9667            moveTaskToFrontLocked(taskId, flags, bOptions);
9668        }
9669    }
9670
9671    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9672        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9673
9674        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9675                Binder.getCallingUid(), -1, -1, "Task to front")) {
9676            ActivityOptions.abort(options);
9677            return;
9678        }
9679        final long origId = Binder.clearCallingIdentity();
9680        try {
9681            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9682            if (task == null) {
9683                Slog.d(TAG, "Could not find task for id: "+ taskId);
9684                return;
9685            }
9686            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9687                mStackSupervisor.showLockTaskToast();
9688                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9689                return;
9690            }
9691            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9692            if (prev != null && prev.isRecentsActivity()) {
9693                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9694            }
9695            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9696                    false /* forceNonResizable */);
9697        } finally {
9698            Binder.restoreCallingIdentity(origId);
9699        }
9700        ActivityOptions.abort(options);
9701    }
9702
9703    /**
9704     * Moves an activity, and all of the other activities within the same task, to the bottom
9705     * of the history stack.  The activity's order within the task is unchanged.
9706     *
9707     * @param token A reference to the activity we wish to move
9708     * @param nonRoot If false then this only works if the activity is the root
9709     *                of a task; if true it will work for any activity in a task.
9710     * @return Returns true if the move completed, false if not.
9711     */
9712    @Override
9713    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9714        enforceNotIsolatedCaller("moveActivityTaskToBack");
9715        synchronized(this) {
9716            final long origId = Binder.clearCallingIdentity();
9717            try {
9718                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9719                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9720                if (task != null) {
9721                    if (mStackSupervisor.isLockedTask(task)) {
9722                        mStackSupervisor.showLockTaskToast();
9723                        return false;
9724                    }
9725                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9726                }
9727            } finally {
9728                Binder.restoreCallingIdentity(origId);
9729            }
9730        }
9731        return false;
9732    }
9733
9734    @Override
9735    public void moveTaskBackwards(int task) {
9736        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9737                "moveTaskBackwards()");
9738
9739        synchronized(this) {
9740            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9741                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9742                return;
9743            }
9744            final long origId = Binder.clearCallingIdentity();
9745            moveTaskBackwardsLocked(task);
9746            Binder.restoreCallingIdentity(origId);
9747        }
9748    }
9749
9750    private final void moveTaskBackwardsLocked(int task) {
9751        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9752    }
9753
9754    @Override
9755    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9756            IActivityContainerCallback callback) throws RemoteException {
9757        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9758        synchronized (this) {
9759            if (parentActivityToken == null) {
9760                throw new IllegalArgumentException("parent token must not be null");
9761            }
9762            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9763            if (r == null) {
9764                return null;
9765            }
9766            if (callback == null) {
9767                throw new IllegalArgumentException("callback must not be null");
9768            }
9769            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9770        }
9771    }
9772
9773    @Override
9774    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9775        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9776        synchronized (this) {
9777            mStackSupervisor.deleteActivityContainer(container);
9778        }
9779    }
9780
9781    @Override
9782    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9783        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9784        synchronized (this) {
9785            final int stackId = mStackSupervisor.getNextStackId();
9786            final ActivityStack stack =
9787                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9788            if (stack == null) {
9789                return null;
9790            }
9791            return stack.mActivityContainer;
9792        }
9793    }
9794
9795    @Override
9796    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9797        synchronized (this) {
9798            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9799            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9800                return stack.mActivityContainer.getDisplayId();
9801            }
9802            return Display.DEFAULT_DISPLAY;
9803        }
9804    }
9805
9806    @Override
9807    public int getActivityStackId(IBinder token) throws RemoteException {
9808        synchronized (this) {
9809            ActivityStack stack = ActivityRecord.getStackLocked(token);
9810            if (stack == null) {
9811                return INVALID_STACK_ID;
9812            }
9813            return stack.mStackId;
9814        }
9815    }
9816
9817    @Override
9818    public void exitFreeformMode(IBinder token) throws RemoteException {
9819        synchronized (this) {
9820            long ident = Binder.clearCallingIdentity();
9821            try {
9822                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9823                if (r == null) {
9824                    throw new IllegalArgumentException(
9825                            "exitFreeformMode: No activity record matching token=" + token);
9826                }
9827                final ActivityStack stack = r.getStackLocked(token);
9828                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9829                    throw new IllegalStateException(
9830                            "exitFreeformMode: You can only go fullscreen from freeform.");
9831                }
9832                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9833                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9834                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9835            } finally {
9836                Binder.restoreCallingIdentity(ident);
9837            }
9838        }
9839    }
9840
9841    @Override
9842    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9843        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9844        if (stackId == HOME_STACK_ID) {
9845            throw new IllegalArgumentException(
9846                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9847        }
9848        synchronized (this) {
9849            long ident = Binder.clearCallingIdentity();
9850            try {
9851                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9852                        + " to stackId=" + stackId + " toTop=" + toTop);
9853                if (stackId == DOCKED_STACK_ID) {
9854                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9855                            null /* initialBounds */);
9856                }
9857                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9858                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9859                if (result && stackId == DOCKED_STACK_ID) {
9860                    // If task moved to docked stack - show recents if needed.
9861                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9862                            "moveTaskToDockedStack");
9863                }
9864            } finally {
9865                Binder.restoreCallingIdentity(ident);
9866            }
9867        }
9868    }
9869
9870    @Override
9871    public void swapDockedAndFullscreenStack() throws RemoteException {
9872        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9873        synchronized (this) {
9874            long ident = Binder.clearCallingIdentity();
9875            try {
9876                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9877                        FULLSCREEN_WORKSPACE_STACK_ID);
9878                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9879                        : null;
9880                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9881                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9882                        : null;
9883                if (topTask == null || tasks == null || tasks.size() == 0) {
9884                    Slog.w(TAG,
9885                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9886                    return;
9887                }
9888
9889                // TODO: App transition
9890                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9891
9892                // Defer the resume so resume/pausing while moving stacks is dangerous.
9893                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9894                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9895                        ANIMATE, true /* deferResume */);
9896                final int size = tasks.size();
9897                for (int i = 0; i < size; i++) {
9898                    final int id = tasks.get(i).taskId;
9899                    if (id == topTask.taskId) {
9900                        continue;
9901                    }
9902                    mStackSupervisor.moveTaskToStackLocked(id,
9903                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9904                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9905                }
9906
9907                // Because we deferred the resume, to avoid conflicts with stack switches while
9908                // resuming, we need to do it after all the tasks are moved.
9909                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9910                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9911
9912                mWindowManager.executeAppTransition();
9913            } finally {
9914                Binder.restoreCallingIdentity(ident);
9915            }
9916        }
9917    }
9918
9919    /**
9920     * Moves the input task to the docked stack.
9921     *
9922     * @param taskId Id of task to move.
9923     * @param createMode The mode the docked stack should be created in if it doesn't exist
9924     *                   already. See
9925     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9926     *                   and
9927     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9928     * @param toTop If the task and stack should be moved to the top.
9929     * @param animate Whether we should play an animation for the moving the task
9930     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9931     *                      docked stack. Pass {@code null} to use default bounds.
9932     */
9933    @Override
9934    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9935            Rect initialBounds, boolean moveHomeStackFront) {
9936        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9937        synchronized (this) {
9938            long ident = Binder.clearCallingIdentity();
9939            try {
9940                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9941                        + " to createMode=" + createMode + " toTop=" + toTop);
9942                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9943                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9944                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9945                        animate, DEFER_RESUME);
9946                if (moved) {
9947                    if (moveHomeStackFront) {
9948                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9949                    }
9950                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9951                }
9952                return moved;
9953            } finally {
9954                Binder.restoreCallingIdentity(ident);
9955            }
9956        }
9957    }
9958
9959    /**
9960     * Moves the top activity in the input stackId to the pinned stack.
9961     *
9962     * @param stackId Id of stack to move the top activity to pinned stack.
9963     * @param bounds Bounds to use for pinned stack.
9964     *
9965     * @return True if the top activity of the input stack was successfully moved to the pinned
9966     *          stack.
9967     */
9968    @Override
9969    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9970        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9971        synchronized (this) {
9972            if (!mSupportsPictureInPicture) {
9973                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9974                        + "Device doesn't support picture-in-pciture mode");
9975            }
9976
9977            long ident = Binder.clearCallingIdentity();
9978            try {
9979                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9980            } finally {
9981                Binder.restoreCallingIdentity(ident);
9982            }
9983        }
9984    }
9985
9986    @Override
9987    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9988            boolean preserveWindows, boolean animate, int animationDuration) {
9989        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9990        long ident = Binder.clearCallingIdentity();
9991        try {
9992            synchronized (this) {
9993                if (animate) {
9994                    if (stackId == PINNED_STACK_ID) {
9995                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9996                    } else {
9997                        throw new IllegalArgumentException("Stack: " + stackId
9998                                + " doesn't support animated resize.");
9999                    }
10000                } else {
10001                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10002                            null /* tempTaskInsetBounds */, preserveWindows,
10003                            allowResizeInDockedMode, !DEFER_RESUME);
10004                }
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    @Override
10012    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10013            Rect tempDockedTaskInsetBounds,
10014            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10015        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10016                "resizeDockedStack()");
10017        long ident = Binder.clearCallingIdentity();
10018        try {
10019            synchronized (this) {
10020                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10021                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10022                        PRESERVE_WINDOWS);
10023            }
10024        } finally {
10025            Binder.restoreCallingIdentity(ident);
10026        }
10027    }
10028
10029    @Override
10030    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10031        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10032                "resizePinnedStack()");
10033        final long ident = Binder.clearCallingIdentity();
10034        try {
10035            synchronized (this) {
10036                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10037            }
10038        } finally {
10039            Binder.restoreCallingIdentity(ident);
10040        }
10041    }
10042
10043    @Override
10044    public void positionTaskInStack(int taskId, int stackId, int position) {
10045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10046        if (stackId == HOME_STACK_ID) {
10047            throw new IllegalArgumentException(
10048                    "positionTaskInStack: Attempt to change the position of task "
10049                    + taskId + " in/to home stack");
10050        }
10051        synchronized (this) {
10052            long ident = Binder.clearCallingIdentity();
10053            try {
10054                if (DEBUG_STACK) Slog.d(TAG_STACK,
10055                        "positionTaskInStack: positioning task=" + taskId
10056                        + " in stackId=" + stackId + " at position=" + position);
10057                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10058            } finally {
10059                Binder.restoreCallingIdentity(ident);
10060            }
10061        }
10062    }
10063
10064    @Override
10065    public List<StackInfo> getAllStackInfos() {
10066        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10067        long ident = Binder.clearCallingIdentity();
10068        try {
10069            synchronized (this) {
10070                return mStackSupervisor.getAllStackInfosLocked();
10071            }
10072        } finally {
10073            Binder.restoreCallingIdentity(ident);
10074        }
10075    }
10076
10077    @Override
10078    public StackInfo getStackInfo(int stackId) {
10079        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10080        long ident = Binder.clearCallingIdentity();
10081        try {
10082            synchronized (this) {
10083                return mStackSupervisor.getStackInfoLocked(stackId);
10084            }
10085        } finally {
10086            Binder.restoreCallingIdentity(ident);
10087        }
10088    }
10089
10090    @Override
10091    public boolean isInHomeStack(int taskId) {
10092        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10093        long ident = Binder.clearCallingIdentity();
10094        try {
10095            synchronized (this) {
10096                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10097                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10098                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10099            }
10100        } finally {
10101            Binder.restoreCallingIdentity(ident);
10102        }
10103    }
10104
10105    @Override
10106    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10107        synchronized(this) {
10108            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10109        }
10110    }
10111
10112    @Override
10113    public void updateDeviceOwner(String packageName) {
10114        final int callingUid = Binder.getCallingUid();
10115        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10116            throw new SecurityException("updateDeviceOwner called from non-system process");
10117        }
10118        synchronized (this) {
10119            mDeviceOwnerName = packageName;
10120        }
10121    }
10122
10123    @Override
10124    public void updateLockTaskPackages(int userId, String[] packages) {
10125        final int callingUid = Binder.getCallingUid();
10126        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10127            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10128                    "updateLockTaskPackages()");
10129        }
10130        synchronized (this) {
10131            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10132                    Arrays.toString(packages));
10133            mLockTaskPackages.put(userId, packages);
10134            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10135        }
10136    }
10137
10138
10139    void startLockTaskModeLocked(TaskRecord task) {
10140        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10141        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10142            return;
10143        }
10144
10145        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10146        // is initiated by system after the pinning request was shown and locked mode is initiated
10147        // by an authorized app directly
10148        final int callingUid = Binder.getCallingUid();
10149        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10150        long ident = Binder.clearCallingIdentity();
10151        try {
10152            if (!isSystemInitiated) {
10153                task.mLockTaskUid = callingUid;
10154                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10155                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10156                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10157                    StatusBarManagerInternal statusBarManager =
10158                            LocalServices.getService(StatusBarManagerInternal.class);
10159                    if (statusBarManager != null) {
10160                        statusBarManager.showScreenPinningRequest(task.taskId);
10161                    }
10162                    return;
10163                }
10164
10165                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10166                if (stack == null || task != stack.topTask()) {
10167                    throw new IllegalArgumentException("Invalid task, not in foreground");
10168                }
10169            }
10170            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10171                    "Locking fully");
10172            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10173                    ActivityManager.LOCK_TASK_MODE_PINNED :
10174                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10175                    "startLockTask", true);
10176        } finally {
10177            Binder.restoreCallingIdentity(ident);
10178        }
10179    }
10180
10181    @Override
10182    public void startLockTaskMode(int taskId) {
10183        synchronized (this) {
10184            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10185            if (task != null) {
10186                startLockTaskModeLocked(task);
10187            }
10188        }
10189    }
10190
10191    @Override
10192    public void startLockTaskMode(IBinder token) {
10193        synchronized (this) {
10194            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10195            if (r == null) {
10196                return;
10197            }
10198            final TaskRecord task = r.task;
10199            if (task != null) {
10200                startLockTaskModeLocked(task);
10201            }
10202        }
10203    }
10204
10205    @Override
10206    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10207        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10208        // This makes inner call to look as if it was initiated by system.
10209        long ident = Binder.clearCallingIdentity();
10210        try {
10211            synchronized (this) {
10212                startLockTaskMode(taskId);
10213            }
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    @Override
10220    public void stopLockTaskMode() {
10221        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10222        if (lockTask == null) {
10223            // Our work here is done.
10224            return;
10225        }
10226
10227        final int callingUid = Binder.getCallingUid();
10228        final int lockTaskUid = lockTask.mLockTaskUid;
10229        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10230        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10231            // Done.
10232            return;
10233        } else {
10234            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10235            // It is possible lockTaskMode was started by the system process because
10236            // android:lockTaskMode is set to a locking value in the application manifest
10237            // instead of the app calling startLockTaskMode. In this case
10238            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10239            // {@link TaskRecord.effectiveUid} instead. Also caller with
10240            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10241            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10242                    && callingUid != lockTaskUid
10243                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10244                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10245                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10246            }
10247        }
10248        long ident = Binder.clearCallingIdentity();
10249        try {
10250            Log.d(TAG, "stopLockTaskMode");
10251            // Stop lock task
10252            synchronized (this) {
10253                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10254                        "stopLockTask", true);
10255            }
10256            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10257            if (tm != null) {
10258                tm.showInCallScreen(false);
10259            }
10260        } finally {
10261            Binder.restoreCallingIdentity(ident);
10262        }
10263    }
10264
10265    /**
10266     * This API should be called by SystemUI only when user perform certain action to dismiss
10267     * lock task mode. We should only dismiss pinned lock task mode in this case.
10268     */
10269    @Override
10270    public void stopSystemLockTaskMode() throws RemoteException {
10271        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10272            stopLockTaskMode();
10273        } else {
10274            mStackSupervisor.showLockTaskToast();
10275        }
10276    }
10277
10278    @Override
10279    public boolean isInLockTaskMode() {
10280        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10281    }
10282
10283    @Override
10284    public int getLockTaskModeState() {
10285        synchronized (this) {
10286            return mStackSupervisor.getLockTaskModeState();
10287        }
10288    }
10289
10290    @Override
10291    public void showLockTaskEscapeMessage(IBinder token) {
10292        synchronized (this) {
10293            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10294            if (r == null) {
10295                return;
10296            }
10297            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10298        }
10299    }
10300
10301    // =========================================================
10302    // CONTENT PROVIDERS
10303    // =========================================================
10304
10305    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10306        List<ProviderInfo> providers = null;
10307        try {
10308            providers = AppGlobals.getPackageManager()
10309                    .queryContentProviders(app.processName, app.uid,
10310                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10311                                    | MATCH_DEBUG_TRIAGED_MISSING)
10312                    .getList();
10313        } catch (RemoteException ex) {
10314        }
10315        if (DEBUG_MU) Slog.v(TAG_MU,
10316                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10317        int userId = app.userId;
10318        if (providers != null) {
10319            int N = providers.size();
10320            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10321            for (int i=0; i<N; i++) {
10322                // TODO: keep logic in sync with installEncryptionUnawareProviders
10323                ProviderInfo cpi =
10324                    (ProviderInfo)providers.get(i);
10325                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10326                        cpi.name, cpi.flags);
10327                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10328                    // This is a singleton provider, but a user besides the
10329                    // default user is asking to initialize a process it runs
10330                    // in...  well, no, it doesn't actually run in this process,
10331                    // it runs in the process of the default user.  Get rid of it.
10332                    providers.remove(i);
10333                    N--;
10334                    i--;
10335                    continue;
10336                }
10337
10338                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10339                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10340                if (cpr == null) {
10341                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10342                    mProviderMap.putProviderByClass(comp, cpr);
10343                }
10344                if (DEBUG_MU) Slog.v(TAG_MU,
10345                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10346                app.pubProviders.put(cpi.name, cpr);
10347                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10348                    // Don't add this if it is a platform component that is marked
10349                    // to run in multiple processes, because this is actually
10350                    // part of the framework so doesn't make sense to track as a
10351                    // separate apk in the process.
10352                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10353                            mProcessStats);
10354                }
10355                notifyPackageUse(cpi.applicationInfo.packageName,
10356                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10357            }
10358        }
10359        return providers;
10360    }
10361
10362    /**
10363     * Check if {@link ProcessRecord} has a possible chance at accessing the
10364     * given {@link ProviderInfo}. Final permission checking is always done
10365     * in {@link ContentProvider}.
10366     */
10367    private final String checkContentProviderPermissionLocked(
10368            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10369        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10370        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10371        boolean checkedGrants = false;
10372        if (checkUser) {
10373            // Looking for cross-user grants before enforcing the typical cross-users permissions
10374            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10375            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10376                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10377                    return null;
10378                }
10379                checkedGrants = true;
10380            }
10381            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10382                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10383            if (userId != tmpTargetUserId) {
10384                // When we actually went to determine the final targer user ID, this ended
10385                // up different than our initial check for the authority.  This is because
10386                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10387                // SELF.  So we need to re-check the grants again.
10388                checkedGrants = false;
10389            }
10390        }
10391        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10392                cpi.applicationInfo.uid, cpi.exported)
10393                == PackageManager.PERMISSION_GRANTED) {
10394            return null;
10395        }
10396        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10397                cpi.applicationInfo.uid, cpi.exported)
10398                == PackageManager.PERMISSION_GRANTED) {
10399            return null;
10400        }
10401
10402        PathPermission[] pps = cpi.pathPermissions;
10403        if (pps != null) {
10404            int i = pps.length;
10405            while (i > 0) {
10406                i--;
10407                PathPermission pp = pps[i];
10408                String pprperm = pp.getReadPermission();
10409                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10410                        cpi.applicationInfo.uid, cpi.exported)
10411                        == PackageManager.PERMISSION_GRANTED) {
10412                    return null;
10413                }
10414                String ppwperm = pp.getWritePermission();
10415                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10416                        cpi.applicationInfo.uid, cpi.exported)
10417                        == PackageManager.PERMISSION_GRANTED) {
10418                    return null;
10419                }
10420            }
10421        }
10422        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10423            return null;
10424        }
10425
10426        String msg;
10427        if (!cpi.exported) {
10428            msg = "Permission Denial: opening provider " + cpi.name
10429                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10430                    + ", uid=" + callingUid + ") that is not exported from uid "
10431                    + cpi.applicationInfo.uid;
10432        } else {
10433            msg = "Permission Denial: opening provider " + cpi.name
10434                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10435                    + ", uid=" + callingUid + ") requires "
10436                    + cpi.readPermission + " or " + cpi.writePermission;
10437        }
10438        Slog.w(TAG, msg);
10439        return msg;
10440    }
10441
10442    /**
10443     * Returns if the ContentProvider has granted a uri to callingUid
10444     */
10445    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10446        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10447        if (perms != null) {
10448            for (int i=perms.size()-1; i>=0; i--) {
10449                GrantUri grantUri = perms.keyAt(i);
10450                if (grantUri.sourceUserId == userId || !checkUser) {
10451                    if (matchesProvider(grantUri.uri, cpi)) {
10452                        return true;
10453                    }
10454                }
10455            }
10456        }
10457        return false;
10458    }
10459
10460    /**
10461     * Returns true if the uri authority is one of the authorities specified in the provider.
10462     */
10463    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10464        String uriAuth = uri.getAuthority();
10465        String cpiAuth = cpi.authority;
10466        if (cpiAuth.indexOf(';') == -1) {
10467            return cpiAuth.equals(uriAuth);
10468        }
10469        String[] cpiAuths = cpiAuth.split(";");
10470        int length = cpiAuths.length;
10471        for (int i = 0; i < length; i++) {
10472            if (cpiAuths[i].equals(uriAuth)) return true;
10473        }
10474        return false;
10475    }
10476
10477    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10478            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10479        if (r != null) {
10480            for (int i=0; i<r.conProviders.size(); i++) {
10481                ContentProviderConnection conn = r.conProviders.get(i);
10482                if (conn.provider == cpr) {
10483                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10484                            "Adding provider requested by "
10485                            + r.processName + " from process "
10486                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10487                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10488                    if (stable) {
10489                        conn.stableCount++;
10490                        conn.numStableIncs++;
10491                    } else {
10492                        conn.unstableCount++;
10493                        conn.numUnstableIncs++;
10494                    }
10495                    return conn;
10496                }
10497            }
10498            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10499            if (stable) {
10500                conn.stableCount = 1;
10501                conn.numStableIncs = 1;
10502            } else {
10503                conn.unstableCount = 1;
10504                conn.numUnstableIncs = 1;
10505            }
10506            cpr.connections.add(conn);
10507            r.conProviders.add(conn);
10508            startAssociationLocked(r.uid, r.processName, r.curProcState,
10509                    cpr.uid, cpr.name, cpr.info.processName);
10510            return conn;
10511        }
10512        cpr.addExternalProcessHandleLocked(externalProcessToken);
10513        return null;
10514    }
10515
10516    boolean decProviderCountLocked(ContentProviderConnection conn,
10517            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10518        if (conn != null) {
10519            cpr = conn.provider;
10520            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10521                    "Removing provider requested by "
10522                    + conn.client.processName + " from process "
10523                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10524                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10525            if (stable) {
10526                conn.stableCount--;
10527            } else {
10528                conn.unstableCount--;
10529            }
10530            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10531                cpr.connections.remove(conn);
10532                conn.client.conProviders.remove(conn);
10533                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10534                    // The client is more important than last activity -- note the time this
10535                    // is happening, so we keep the old provider process around a bit as last
10536                    // activity to avoid thrashing it.
10537                    if (cpr.proc != null) {
10538                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10539                    }
10540                }
10541                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10542                return true;
10543            }
10544            return false;
10545        }
10546        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10547        return false;
10548    }
10549
10550    private void checkTime(long startTime, String where) {
10551        long now = SystemClock.uptimeMillis();
10552        if ((now-startTime) > 50) {
10553            // If we are taking more than 50ms, log about it.
10554            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10555        }
10556    }
10557
10558    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10559            PROC_SPACE_TERM,
10560            PROC_SPACE_TERM|PROC_PARENS,
10561            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10562    };
10563
10564    private final long[] mProcessStateStatsLongs = new long[1];
10565
10566    boolean isProcessAliveLocked(ProcessRecord proc) {
10567        if (proc.procStatFile == null) {
10568            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10569        }
10570        mProcessStateStatsLongs[0] = 0;
10571        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10572                mProcessStateStatsLongs, null)) {
10573            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10574            return false;
10575        }
10576        final long state = mProcessStateStatsLongs[0];
10577        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10578                + (char)state);
10579        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10580    }
10581
10582    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10583            String name, IBinder token, boolean stable, int userId) {
10584        ContentProviderRecord cpr;
10585        ContentProviderConnection conn = null;
10586        ProviderInfo cpi = null;
10587
10588        synchronized(this) {
10589            long startTime = SystemClock.uptimeMillis();
10590
10591            ProcessRecord r = null;
10592            if (caller != null) {
10593                r = getRecordForAppLocked(caller);
10594                if (r == null) {
10595                    throw new SecurityException(
10596                            "Unable to find app for caller " + caller
10597                          + " (pid=" + Binder.getCallingPid()
10598                          + ") when getting content provider " + name);
10599                }
10600            }
10601
10602            boolean checkCrossUser = true;
10603
10604            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10605
10606            // First check if this content provider has been published...
10607            cpr = mProviderMap.getProviderByName(name, userId);
10608            // If that didn't work, check if it exists for user 0 and then
10609            // verify that it's a singleton provider before using it.
10610            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10611                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10612                if (cpr != null) {
10613                    cpi = cpr.info;
10614                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10615                            cpi.name, cpi.flags)
10616                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10617                        userId = UserHandle.USER_SYSTEM;
10618                        checkCrossUser = false;
10619                    } else {
10620                        cpr = null;
10621                        cpi = null;
10622                    }
10623                }
10624            }
10625
10626            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10627            if (providerRunning) {
10628                cpi = cpr.info;
10629                String msg;
10630                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10631                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10632                        != null) {
10633                    throw new SecurityException(msg);
10634                }
10635                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10636
10637                if (r != null && cpr.canRunHere(r)) {
10638                    // This provider has been published or is in the process
10639                    // of being published...  but it is also allowed to run
10640                    // in the caller's process, so don't make a connection
10641                    // and just let the caller instantiate its own instance.
10642                    ContentProviderHolder holder = cpr.newHolder(null);
10643                    // don't give caller the provider object, it needs
10644                    // to make its own.
10645                    holder.provider = null;
10646                    return holder;
10647                }
10648
10649                final long origId = Binder.clearCallingIdentity();
10650
10651                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10652
10653                // In this case the provider instance already exists, so we can
10654                // return it right away.
10655                conn = incProviderCountLocked(r, cpr, token, stable);
10656                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10657                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10658                        // If this is a perceptible app accessing the provider,
10659                        // make sure to count it as being accessed and thus
10660                        // back up on the LRU list.  This is good because
10661                        // content providers are often expensive to start.
10662                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10663                        updateLruProcessLocked(cpr.proc, false, null);
10664                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10665                    }
10666                }
10667
10668                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10669                final int verifiedAdj = cpr.proc.verifiedAdj;
10670                boolean success = updateOomAdjLocked(cpr.proc);
10671                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10672                // if the process has been successfully adjusted.  So to reduce races with
10673                // it, we will check whether the process still exists.  Note that this doesn't
10674                // completely get rid of races with LMK killing the process, but should make
10675                // them much smaller.
10676                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10677                    success = false;
10678                }
10679                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10680                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10681                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10682                // NOTE: there is still a race here where a signal could be
10683                // pending on the process even though we managed to update its
10684                // adj level.  Not sure what to do about this, but at least
10685                // the race is now smaller.
10686                if (!success) {
10687                    // Uh oh...  it looks like the provider's process
10688                    // has been killed on us.  We need to wait for a new
10689                    // process to be started, and make sure its death
10690                    // doesn't kill our process.
10691                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10692                            + " is crashing; detaching " + r);
10693                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10694                    checkTime(startTime, "getContentProviderImpl: before appDied");
10695                    appDiedLocked(cpr.proc);
10696                    checkTime(startTime, "getContentProviderImpl: after appDied");
10697                    if (!lastRef) {
10698                        // This wasn't the last ref our process had on
10699                        // the provider...  we have now been killed, bail.
10700                        return null;
10701                    }
10702                    providerRunning = false;
10703                    conn = null;
10704                } else {
10705                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10706                }
10707
10708                Binder.restoreCallingIdentity(origId);
10709            }
10710
10711            if (!providerRunning) {
10712                try {
10713                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10714                    cpi = AppGlobals.getPackageManager().
10715                        resolveContentProvider(name,
10716                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10717                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10718                } catch (RemoteException ex) {
10719                }
10720                if (cpi == null) {
10721                    return null;
10722                }
10723                // If the provider is a singleton AND
10724                // (it's a call within the same user || the provider is a
10725                // privileged app)
10726                // Then allow connecting to the singleton provider
10727                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10728                        cpi.name, cpi.flags)
10729                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10730                if (singleton) {
10731                    userId = UserHandle.USER_SYSTEM;
10732                }
10733                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10734                checkTime(startTime, "getContentProviderImpl: got app info for user");
10735
10736                String msg;
10737                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10738                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10739                        != null) {
10740                    throw new SecurityException(msg);
10741                }
10742                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10743
10744                if (!mProcessesReady
10745                        && !cpi.processName.equals("system")) {
10746                    // If this content provider does not run in the system
10747                    // process, and the system is not yet ready to run other
10748                    // processes, then fail fast instead of hanging.
10749                    throw new IllegalArgumentException(
10750                            "Attempt to launch content provider before system ready");
10751                }
10752
10753                // Make sure that the user who owns this provider is running.  If not,
10754                // we don't want to allow it to run.
10755                if (!mUserController.isUserRunningLocked(userId, 0)) {
10756                    Slog.w(TAG, "Unable to launch app "
10757                            + cpi.applicationInfo.packageName + "/"
10758                            + cpi.applicationInfo.uid + " for provider "
10759                            + name + ": user " + userId + " is stopped");
10760                    return null;
10761                }
10762
10763                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10764                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10765                cpr = mProviderMap.getProviderByClass(comp, userId);
10766                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10767                final boolean firstClass = cpr == null;
10768                if (firstClass) {
10769                    final long ident = Binder.clearCallingIdentity();
10770
10771                    // If permissions need a review before any of the app components can run,
10772                    // we return no provider and launch a review activity if the calling app
10773                    // is in the foreground.
10774                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10775                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10776                            return null;
10777                        }
10778                    }
10779
10780                    try {
10781                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10782                        ApplicationInfo ai =
10783                            AppGlobals.getPackageManager().
10784                                getApplicationInfo(
10785                                        cpi.applicationInfo.packageName,
10786                                        STOCK_PM_FLAGS, userId);
10787                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10788                        if (ai == null) {
10789                            Slog.w(TAG, "No package info for content provider "
10790                                    + cpi.name);
10791                            return null;
10792                        }
10793                        ai = getAppInfoForUser(ai, userId);
10794                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10795                    } catch (RemoteException ex) {
10796                        // pm is in same process, this will never happen.
10797                    } finally {
10798                        Binder.restoreCallingIdentity(ident);
10799                    }
10800                }
10801
10802                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10803
10804                if (r != null && cpr.canRunHere(r)) {
10805                    // If this is a multiprocess provider, then just return its
10806                    // info and allow the caller to instantiate it.  Only do
10807                    // this if the provider is the same user as the caller's
10808                    // process, or can run as root (so can be in any process).
10809                    return cpr.newHolder(null);
10810                }
10811
10812                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10813                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10814                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10815
10816                // This is single process, and our app is now connecting to it.
10817                // See if we are already in the process of launching this
10818                // provider.
10819                final int N = mLaunchingProviders.size();
10820                int i;
10821                for (i = 0; i < N; i++) {
10822                    if (mLaunchingProviders.get(i) == cpr) {
10823                        break;
10824                    }
10825                }
10826
10827                // If the provider is not already being launched, then get it
10828                // started.
10829                if (i >= N) {
10830                    final long origId = Binder.clearCallingIdentity();
10831
10832                    try {
10833                        // Content provider is now in use, its package can't be stopped.
10834                        try {
10835                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10836                            AppGlobals.getPackageManager().setPackageStoppedState(
10837                                    cpr.appInfo.packageName, false, userId);
10838                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10839                        } catch (RemoteException e) {
10840                        } catch (IllegalArgumentException e) {
10841                            Slog.w(TAG, "Failed trying to unstop package "
10842                                    + cpr.appInfo.packageName + ": " + e);
10843                        }
10844
10845                        // Use existing process if already started
10846                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10847                        ProcessRecord proc = getProcessRecordLocked(
10848                                cpi.processName, cpr.appInfo.uid, false);
10849                        if (proc != null && proc.thread != null && !proc.killed) {
10850                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10851                                    "Installing in existing process " + proc);
10852                            if (!proc.pubProviders.containsKey(cpi.name)) {
10853                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10854                                proc.pubProviders.put(cpi.name, cpr);
10855                                try {
10856                                    proc.thread.scheduleInstallProvider(cpi);
10857                                } catch (RemoteException e) {
10858                                }
10859                            }
10860                        } else {
10861                            checkTime(startTime, "getContentProviderImpl: before start process");
10862                            proc = startProcessLocked(cpi.processName,
10863                                    cpr.appInfo, false, 0, "content provider",
10864                                    new ComponentName(cpi.applicationInfo.packageName,
10865                                            cpi.name), false, false, false);
10866                            checkTime(startTime, "getContentProviderImpl: after start process");
10867                            if (proc == null) {
10868                                Slog.w(TAG, "Unable to launch app "
10869                                        + cpi.applicationInfo.packageName + "/"
10870                                        + cpi.applicationInfo.uid + " for provider "
10871                                        + name + ": process is bad");
10872                                return null;
10873                            }
10874                        }
10875                        cpr.launchingApp = proc;
10876                        mLaunchingProviders.add(cpr);
10877                    } finally {
10878                        Binder.restoreCallingIdentity(origId);
10879                    }
10880                }
10881
10882                checkTime(startTime, "getContentProviderImpl: updating data structures");
10883
10884                // Make sure the provider is published (the same provider class
10885                // may be published under multiple names).
10886                if (firstClass) {
10887                    mProviderMap.putProviderByClass(comp, cpr);
10888                }
10889
10890                mProviderMap.putProviderByName(name, cpr);
10891                conn = incProviderCountLocked(r, cpr, token, stable);
10892                if (conn != null) {
10893                    conn.waiting = true;
10894                }
10895            }
10896            checkTime(startTime, "getContentProviderImpl: done!");
10897        }
10898
10899        // Wait for the provider to be published...
10900        synchronized (cpr) {
10901            while (cpr.provider == null) {
10902                if (cpr.launchingApp == null) {
10903                    Slog.w(TAG, "Unable to launch app "
10904                            + cpi.applicationInfo.packageName + "/"
10905                            + cpi.applicationInfo.uid + " for provider "
10906                            + name + ": launching app became null");
10907                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10908                            UserHandle.getUserId(cpi.applicationInfo.uid),
10909                            cpi.applicationInfo.packageName,
10910                            cpi.applicationInfo.uid, name);
10911                    return null;
10912                }
10913                try {
10914                    if (DEBUG_MU) Slog.v(TAG_MU,
10915                            "Waiting to start provider " + cpr
10916                            + " launchingApp=" + cpr.launchingApp);
10917                    if (conn != null) {
10918                        conn.waiting = true;
10919                    }
10920                    cpr.wait();
10921                } catch (InterruptedException ex) {
10922                } finally {
10923                    if (conn != null) {
10924                        conn.waiting = false;
10925                    }
10926                }
10927            }
10928        }
10929        return cpr != null ? cpr.newHolder(conn) : null;
10930    }
10931
10932    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10933            ProcessRecord r, final int userId) {
10934        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10935                cpi.packageName, userId)) {
10936
10937            final boolean callerForeground = r == null || r.setSchedGroup
10938                    != ProcessList.SCHED_GROUP_BACKGROUND;
10939
10940            // Show a permission review UI only for starting from a foreground app
10941            if (!callerForeground) {
10942                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10943                        + cpi.packageName + " requires a permissions review");
10944                return false;
10945            }
10946
10947            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10948            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10949                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10950            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10951
10952            if (DEBUG_PERMISSIONS_REVIEW) {
10953                Slog.i(TAG, "u" + userId + " Launching permission review "
10954                        + "for package " + cpi.packageName);
10955            }
10956
10957            final UserHandle userHandle = new UserHandle(userId);
10958            mHandler.post(new Runnable() {
10959                @Override
10960                public void run() {
10961                    mContext.startActivityAsUser(intent, userHandle);
10962                }
10963            });
10964
10965            return false;
10966        }
10967
10968        return true;
10969    }
10970
10971    PackageManagerInternal getPackageManagerInternalLocked() {
10972        if (mPackageManagerInt == null) {
10973            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10974        }
10975        return mPackageManagerInt;
10976    }
10977
10978    @Override
10979    public final ContentProviderHolder getContentProvider(
10980            IApplicationThread caller, String name, int userId, boolean stable) {
10981        enforceNotIsolatedCaller("getContentProvider");
10982        if (caller == null) {
10983            String msg = "null IApplicationThread when getting content provider "
10984                    + name;
10985            Slog.w(TAG, msg);
10986            throw new SecurityException(msg);
10987        }
10988        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10989        // with cross-user grant.
10990        return getContentProviderImpl(caller, name, null, stable, userId);
10991    }
10992
10993    public ContentProviderHolder getContentProviderExternal(
10994            String name, int userId, IBinder token) {
10995        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10996            "Do not have permission in call getContentProviderExternal()");
10997        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10998                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10999        return getContentProviderExternalUnchecked(name, token, userId);
11000    }
11001
11002    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11003            IBinder token, int userId) {
11004        return getContentProviderImpl(null, name, token, true, userId);
11005    }
11006
11007    /**
11008     * Drop a content provider from a ProcessRecord's bookkeeping
11009     */
11010    public void removeContentProvider(IBinder connection, boolean stable) {
11011        enforceNotIsolatedCaller("removeContentProvider");
11012        long ident = Binder.clearCallingIdentity();
11013        try {
11014            synchronized (this) {
11015                ContentProviderConnection conn;
11016                try {
11017                    conn = (ContentProviderConnection)connection;
11018                } catch (ClassCastException e) {
11019                    String msg ="removeContentProvider: " + connection
11020                            + " not a ContentProviderConnection";
11021                    Slog.w(TAG, msg);
11022                    throw new IllegalArgumentException(msg);
11023                }
11024                if (conn == null) {
11025                    throw new NullPointerException("connection is null");
11026                }
11027                if (decProviderCountLocked(conn, null, null, stable)) {
11028                    updateOomAdjLocked();
11029                }
11030            }
11031        } finally {
11032            Binder.restoreCallingIdentity(ident);
11033        }
11034    }
11035
11036    public void removeContentProviderExternal(String name, IBinder token) {
11037        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11038            "Do not have permission in call removeContentProviderExternal()");
11039        int userId = UserHandle.getCallingUserId();
11040        long ident = Binder.clearCallingIdentity();
11041        try {
11042            removeContentProviderExternalUnchecked(name, token, userId);
11043        } finally {
11044            Binder.restoreCallingIdentity(ident);
11045        }
11046    }
11047
11048    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11049        synchronized (this) {
11050            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11051            if(cpr == null) {
11052                //remove from mProvidersByClass
11053                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11054                return;
11055            }
11056
11057            //update content provider record entry info
11058            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11059            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11060            if (localCpr.hasExternalProcessHandles()) {
11061                if (localCpr.removeExternalProcessHandleLocked(token)) {
11062                    updateOomAdjLocked();
11063                } else {
11064                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11065                            + " with no external reference for token: "
11066                            + token + ".");
11067                }
11068            } else {
11069                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11070                        + " with no external references.");
11071            }
11072        }
11073    }
11074
11075    public final void publishContentProviders(IApplicationThread caller,
11076            List<ContentProviderHolder> providers) {
11077        if (providers == null) {
11078            return;
11079        }
11080
11081        enforceNotIsolatedCaller("publishContentProviders");
11082        synchronized (this) {
11083            final ProcessRecord r = getRecordForAppLocked(caller);
11084            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11085            if (r == null) {
11086                throw new SecurityException(
11087                        "Unable to find app for caller " + caller
11088                      + " (pid=" + Binder.getCallingPid()
11089                      + ") when publishing content providers");
11090            }
11091
11092            final long origId = Binder.clearCallingIdentity();
11093
11094            final int N = providers.size();
11095            for (int i = 0; i < N; i++) {
11096                ContentProviderHolder src = providers.get(i);
11097                if (src == null || src.info == null || src.provider == null) {
11098                    continue;
11099                }
11100                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11101                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11102                if (dst != null) {
11103                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11104                    mProviderMap.putProviderByClass(comp, dst);
11105                    String names[] = dst.info.authority.split(";");
11106                    for (int j = 0; j < names.length; j++) {
11107                        mProviderMap.putProviderByName(names[j], dst);
11108                    }
11109
11110                    int launchingCount = mLaunchingProviders.size();
11111                    int j;
11112                    boolean wasInLaunchingProviders = false;
11113                    for (j = 0; j < launchingCount; j++) {
11114                        if (mLaunchingProviders.get(j) == dst) {
11115                            mLaunchingProviders.remove(j);
11116                            wasInLaunchingProviders = true;
11117                            j--;
11118                            launchingCount--;
11119                        }
11120                    }
11121                    if (wasInLaunchingProviders) {
11122                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11123                    }
11124                    synchronized (dst) {
11125                        dst.provider = src.provider;
11126                        dst.proc = r;
11127                        dst.notifyAll();
11128                    }
11129                    updateOomAdjLocked(r);
11130                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11131                            src.info.authority);
11132                }
11133            }
11134
11135            Binder.restoreCallingIdentity(origId);
11136        }
11137    }
11138
11139    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11140        ContentProviderConnection conn;
11141        try {
11142            conn = (ContentProviderConnection)connection;
11143        } catch (ClassCastException e) {
11144            String msg ="refContentProvider: " + connection
11145                    + " not a ContentProviderConnection";
11146            Slog.w(TAG, msg);
11147            throw new IllegalArgumentException(msg);
11148        }
11149        if (conn == null) {
11150            throw new NullPointerException("connection is null");
11151        }
11152
11153        synchronized (this) {
11154            if (stable > 0) {
11155                conn.numStableIncs += stable;
11156            }
11157            stable = conn.stableCount + stable;
11158            if (stable < 0) {
11159                throw new IllegalStateException("stableCount < 0: " + stable);
11160            }
11161
11162            if (unstable > 0) {
11163                conn.numUnstableIncs += unstable;
11164            }
11165            unstable = conn.unstableCount + unstable;
11166            if (unstable < 0) {
11167                throw new IllegalStateException("unstableCount < 0: " + unstable);
11168            }
11169
11170            if ((stable+unstable) <= 0) {
11171                throw new IllegalStateException("ref counts can't go to zero here: stable="
11172                        + stable + " unstable=" + unstable);
11173            }
11174            conn.stableCount = stable;
11175            conn.unstableCount = unstable;
11176            return !conn.dead;
11177        }
11178    }
11179
11180    public void unstableProviderDied(IBinder connection) {
11181        ContentProviderConnection conn;
11182        try {
11183            conn = (ContentProviderConnection)connection;
11184        } catch (ClassCastException e) {
11185            String msg ="refContentProvider: " + connection
11186                    + " not a ContentProviderConnection";
11187            Slog.w(TAG, msg);
11188            throw new IllegalArgumentException(msg);
11189        }
11190        if (conn == null) {
11191            throw new NullPointerException("connection is null");
11192        }
11193
11194        // Safely retrieve the content provider associated with the connection.
11195        IContentProvider provider;
11196        synchronized (this) {
11197            provider = conn.provider.provider;
11198        }
11199
11200        if (provider == null) {
11201            // Um, yeah, we're way ahead of you.
11202            return;
11203        }
11204
11205        // Make sure the caller is being honest with us.
11206        if (provider.asBinder().pingBinder()) {
11207            // Er, no, still looks good to us.
11208            synchronized (this) {
11209                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11210                        + " says " + conn + " died, but we don't agree");
11211                return;
11212            }
11213        }
11214
11215        // Well look at that!  It's dead!
11216        synchronized (this) {
11217            if (conn.provider.provider != provider) {
11218                // But something changed...  good enough.
11219                return;
11220            }
11221
11222            ProcessRecord proc = conn.provider.proc;
11223            if (proc == null || proc.thread == null) {
11224                // Seems like the process is already cleaned up.
11225                return;
11226            }
11227
11228            // As far as we're concerned, this is just like receiving a
11229            // death notification...  just a bit prematurely.
11230            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11231                    + ") early provider death");
11232            final long ident = Binder.clearCallingIdentity();
11233            try {
11234                appDiedLocked(proc);
11235            } finally {
11236                Binder.restoreCallingIdentity(ident);
11237            }
11238        }
11239    }
11240
11241    @Override
11242    public void appNotRespondingViaProvider(IBinder connection) {
11243        enforceCallingPermission(
11244                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11245
11246        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11247        if (conn == null) {
11248            Slog.w(TAG, "ContentProviderConnection is null");
11249            return;
11250        }
11251
11252        final ProcessRecord host = conn.provider.proc;
11253        if (host == null) {
11254            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11255            return;
11256        }
11257
11258        mHandler.post(new Runnable() {
11259            @Override
11260            public void run() {
11261                mAppErrors.appNotResponding(host, null, null, false,
11262                        "ContentProvider not responding");
11263            }
11264        });
11265    }
11266
11267    public final void installSystemProviders() {
11268        List<ProviderInfo> providers;
11269        synchronized (this) {
11270            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11271            providers = generateApplicationProvidersLocked(app);
11272            if (providers != null) {
11273                for (int i=providers.size()-1; i>=0; i--) {
11274                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11275                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11276                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11277                                + ": not system .apk");
11278                        providers.remove(i);
11279                    }
11280                }
11281            }
11282        }
11283        if (providers != null) {
11284            mSystemThread.installSystemProviders(providers);
11285        }
11286
11287        mCoreSettingsObserver = new CoreSettingsObserver(this);
11288        mFontScaleSettingObserver = new FontScaleSettingObserver();
11289
11290        //mUsageStatsService.monitorPackages();
11291    }
11292
11293    private void startPersistentApps(int matchFlags) {
11294        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11295
11296        synchronized (this) {
11297            try {
11298                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11299                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11300                for (ApplicationInfo app : apps) {
11301                    if (!"android".equals(app.packageName)) {
11302                        addAppLocked(app, false, null /* ABI override */);
11303                    }
11304                }
11305            } catch (RemoteException ex) {
11306            }
11307        }
11308    }
11309
11310    /**
11311     * When a user is unlocked, we need to install encryption-unaware providers
11312     * belonging to any running apps.
11313     */
11314    private void installEncryptionUnawareProviders(int userId) {
11315        // We're only interested in providers that are encryption unaware, and
11316        // we don't care about uninstalled apps, since there's no way they're
11317        // running at this point.
11318        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11319
11320        synchronized (this) {
11321            final int NP = mProcessNames.getMap().size();
11322            for (int ip = 0; ip < NP; ip++) {
11323                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11324                final int NA = apps.size();
11325                for (int ia = 0; ia < NA; ia++) {
11326                    final ProcessRecord app = apps.valueAt(ia);
11327                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11328
11329                    final int NG = app.pkgList.size();
11330                    for (int ig = 0; ig < NG; ig++) {
11331                        try {
11332                            final String pkgName = app.pkgList.keyAt(ig);
11333                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11334                                    .getPackageInfo(pkgName, matchFlags, userId);
11335                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11336                                for (ProviderInfo pi : pkgInfo.providers) {
11337                                    // TODO: keep in sync with generateApplicationProvidersLocked
11338                                    final boolean processMatch = Objects.equals(pi.processName,
11339                                            app.processName) || pi.multiprocess;
11340                                    final boolean userMatch = isSingleton(pi.processName,
11341                                            pi.applicationInfo, pi.name, pi.flags)
11342                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11343                                    if (processMatch && userMatch) {
11344                                        Log.v(TAG, "Installing " + pi);
11345                                        app.thread.scheduleInstallProvider(pi);
11346                                    } else {
11347                                        Log.v(TAG, "Skipping " + pi);
11348                                    }
11349                                }
11350                            }
11351                        } catch (RemoteException ignored) {
11352                        }
11353                    }
11354                }
11355            }
11356        }
11357    }
11358
11359    /**
11360     * Allows apps to retrieve the MIME type of a URI.
11361     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11362     * users, then it does not need permission to access the ContentProvider.
11363     * Either, it needs cross-user uri grants.
11364     *
11365     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11366     *
11367     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11368     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11369     */
11370    public String getProviderMimeType(Uri uri, int userId) {
11371        enforceNotIsolatedCaller("getProviderMimeType");
11372        final String name = uri.getAuthority();
11373        int callingUid = Binder.getCallingUid();
11374        int callingPid = Binder.getCallingPid();
11375        long ident = 0;
11376        boolean clearedIdentity = false;
11377        synchronized (this) {
11378            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11379        }
11380        if (canClearIdentity(callingPid, callingUid, userId)) {
11381            clearedIdentity = true;
11382            ident = Binder.clearCallingIdentity();
11383        }
11384        ContentProviderHolder holder = null;
11385        try {
11386            holder = getContentProviderExternalUnchecked(name, null, userId);
11387            if (holder != null) {
11388                return holder.provider.getType(uri);
11389            }
11390        } catch (RemoteException e) {
11391            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11392            return null;
11393        } catch (Exception e) {
11394            Log.w(TAG, "Exception while determining type of " + uri, e);
11395            return null;
11396        } finally {
11397            // We need to clear the identity to call removeContentProviderExternalUnchecked
11398            if (!clearedIdentity) {
11399                ident = Binder.clearCallingIdentity();
11400            }
11401            try {
11402                if (holder != null) {
11403                    removeContentProviderExternalUnchecked(name, null, userId);
11404                }
11405            } finally {
11406                Binder.restoreCallingIdentity(ident);
11407            }
11408        }
11409
11410        return null;
11411    }
11412
11413    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11414        if (UserHandle.getUserId(callingUid) == userId) {
11415            return true;
11416        }
11417        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11418                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11419                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11420                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11421                return true;
11422        }
11423        return false;
11424    }
11425
11426    // =========================================================
11427    // GLOBAL MANAGEMENT
11428    // =========================================================
11429
11430    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11431            boolean isolated, int isolatedUid) {
11432        String proc = customProcess != null ? customProcess : info.processName;
11433        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11434        final int userId = UserHandle.getUserId(info.uid);
11435        int uid = info.uid;
11436        if (isolated) {
11437            if (isolatedUid == 0) {
11438                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11439                while (true) {
11440                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11441                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11442                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11443                    }
11444                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11445                    mNextIsolatedProcessUid++;
11446                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11447                        // No process for this uid, use it.
11448                        break;
11449                    }
11450                    stepsLeft--;
11451                    if (stepsLeft <= 0) {
11452                        return null;
11453                    }
11454                }
11455            } else {
11456                // Special case for startIsolatedProcess (internal only), where
11457                // the uid of the isolated process is specified by the caller.
11458                uid = isolatedUid;
11459            }
11460        }
11461        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11462        if (!mBooted && !mBooting
11463                && userId == UserHandle.USER_SYSTEM
11464                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11465            r.persistent = true;
11466        }
11467        addProcessNameLocked(r);
11468        return r;
11469    }
11470
11471    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11472            String abiOverride) {
11473        ProcessRecord app;
11474        if (!isolated) {
11475            app = getProcessRecordLocked(info.processName, info.uid, true);
11476        } else {
11477            app = null;
11478        }
11479
11480        if (app == null) {
11481            app = newProcessRecordLocked(info, null, isolated, 0);
11482            updateLruProcessLocked(app, false, null);
11483            updateOomAdjLocked();
11484        }
11485
11486        // This package really, really can not be stopped.
11487        try {
11488            AppGlobals.getPackageManager().setPackageStoppedState(
11489                    info.packageName, false, UserHandle.getUserId(app.uid));
11490        } catch (RemoteException e) {
11491        } catch (IllegalArgumentException e) {
11492            Slog.w(TAG, "Failed trying to unstop package "
11493                    + info.packageName + ": " + e);
11494        }
11495
11496        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11497            app.persistent = true;
11498            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11499        }
11500        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11501            mPersistentStartingProcesses.add(app);
11502            startProcessLocked(app, "added application", app.processName, abiOverride,
11503                    null /* entryPoint */, null /* entryPointArgs */);
11504        }
11505
11506        return app;
11507    }
11508
11509    public void unhandledBack() {
11510        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11511                "unhandledBack()");
11512
11513        synchronized(this) {
11514            final long origId = Binder.clearCallingIdentity();
11515            try {
11516                getFocusedStack().unhandledBackLocked();
11517            } finally {
11518                Binder.restoreCallingIdentity(origId);
11519            }
11520        }
11521    }
11522
11523    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11524        enforceNotIsolatedCaller("openContentUri");
11525        final int userId = UserHandle.getCallingUserId();
11526        String name = uri.getAuthority();
11527        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11528        ParcelFileDescriptor pfd = null;
11529        if (cph != null) {
11530            // We record the binder invoker's uid in thread-local storage before
11531            // going to the content provider to open the file.  Later, in the code
11532            // that handles all permissions checks, we look for this uid and use
11533            // that rather than the Activity Manager's own uid.  The effect is that
11534            // we do the check against the caller's permissions even though it looks
11535            // to the content provider like the Activity Manager itself is making
11536            // the request.
11537            Binder token = new Binder();
11538            sCallerIdentity.set(new Identity(
11539                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11540            try {
11541                pfd = cph.provider.openFile(null, uri, "r", null, token);
11542            } catch (FileNotFoundException e) {
11543                // do nothing; pfd will be returned null
11544            } finally {
11545                // Ensure that whatever happens, we clean up the identity state
11546                sCallerIdentity.remove();
11547                // Ensure we're done with the provider.
11548                removeContentProviderExternalUnchecked(name, null, userId);
11549            }
11550        } else {
11551            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11552        }
11553        return pfd;
11554    }
11555
11556    // Actually is sleeping or shutting down or whatever else in the future
11557    // is an inactive state.
11558    boolean isSleepingOrShuttingDownLocked() {
11559        return isSleepingLocked() || mShuttingDown;
11560    }
11561
11562    boolean isShuttingDownLocked() {
11563        return mShuttingDown;
11564    }
11565
11566    boolean isSleepingLocked() {
11567        return mSleeping;
11568    }
11569
11570    void onWakefulnessChanged(int wakefulness) {
11571        synchronized(this) {
11572            mWakefulness = wakefulness;
11573            updateSleepIfNeededLocked();
11574        }
11575    }
11576
11577    void finishRunningVoiceLocked() {
11578        if (mRunningVoice != null) {
11579            mRunningVoice = null;
11580            mVoiceWakeLock.release();
11581            updateSleepIfNeededLocked();
11582        }
11583    }
11584
11585    void startTimeTrackingFocusedActivityLocked() {
11586        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11587            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11588        }
11589    }
11590
11591    void updateSleepIfNeededLocked() {
11592        if (mSleeping && !shouldSleepLocked()) {
11593            mSleeping = false;
11594            startTimeTrackingFocusedActivityLocked();
11595            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11596            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11597            updateOomAdjLocked();
11598        } else if (!mSleeping && shouldSleepLocked()) {
11599            mSleeping = true;
11600            if (mCurAppTimeTracker != null) {
11601                mCurAppTimeTracker.stop();
11602            }
11603            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11604            mStackSupervisor.goingToSleepLocked();
11605            updateOomAdjLocked();
11606
11607            // Initialize the wake times of all processes.
11608            checkExcessivePowerUsageLocked(false);
11609            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11610            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11611            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11612        }
11613    }
11614
11615    private boolean shouldSleepLocked() {
11616        // Resume applications while running a voice interactor.
11617        if (mRunningVoice != null) {
11618            return false;
11619        }
11620
11621        // TODO: Transform the lock screen state into a sleep token instead.
11622        switch (mWakefulness) {
11623            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11624            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11625            case PowerManagerInternal.WAKEFULNESS_DOZING:
11626                // Pause applications whenever the lock screen is shown or any sleep
11627                // tokens have been acquired.
11628                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11629            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11630            default:
11631                // If we're asleep then pause applications unconditionally.
11632                return true;
11633        }
11634    }
11635
11636    /** Pokes the task persister. */
11637    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11638        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11639    }
11640
11641    /** Notifies all listeners when the task stack has changed. */
11642    void notifyTaskStackChangedLocked() {
11643        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11644        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11645        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11646        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11647    }
11648
11649    /** Notifies all listeners when an Activity is pinned. */
11650    void notifyActivityPinnedLocked() {
11651        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11652        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11653    }
11654
11655    /**
11656     * Notifies all listeners when an attempt was made to start an an activity that is already
11657     * running in the pinned stack and the activity was not actually started, but the task is
11658     * either brought to the front or a new Intent is delivered to it.
11659     */
11660    void notifyPinnedActivityRestartAttemptLocked() {
11661        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11662        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11663    }
11664
11665    /** Notifies all listeners when the pinned stack animation ends. */
11666    @Override
11667    public void notifyPinnedStackAnimationEnded() {
11668        synchronized (this) {
11669            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11670            mHandler.obtainMessage(
11671                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11672        }
11673    }
11674
11675    @Override
11676    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11677        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11678    }
11679
11680    @Override
11681    public boolean shutdown(int timeout) {
11682        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11683                != PackageManager.PERMISSION_GRANTED) {
11684            throw new SecurityException("Requires permission "
11685                    + android.Manifest.permission.SHUTDOWN);
11686        }
11687
11688        boolean timedout = false;
11689
11690        synchronized(this) {
11691            mShuttingDown = true;
11692            updateEventDispatchingLocked();
11693            timedout = mStackSupervisor.shutdownLocked(timeout);
11694        }
11695
11696        mAppOpsService.shutdown();
11697        if (mUsageStatsService != null) {
11698            mUsageStatsService.prepareShutdown();
11699        }
11700        mBatteryStatsService.shutdown();
11701        synchronized (this) {
11702            mProcessStats.shutdownLocked();
11703            notifyTaskPersisterLocked(null, true);
11704        }
11705
11706        return timedout;
11707    }
11708
11709    public final void activitySlept(IBinder token) {
11710        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11711
11712        final long origId = Binder.clearCallingIdentity();
11713
11714        synchronized (this) {
11715            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11716            if (r != null) {
11717                mStackSupervisor.activitySleptLocked(r);
11718            }
11719        }
11720
11721        Binder.restoreCallingIdentity(origId);
11722    }
11723
11724    private String lockScreenShownToString() {
11725        switch (mLockScreenShown) {
11726            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11727            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11728            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11729            default: return "Unknown=" + mLockScreenShown;
11730        }
11731    }
11732
11733    void logLockScreen(String msg) {
11734        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11735                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11736                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11737                + " mSleeping=" + mSleeping);
11738    }
11739
11740    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11741        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11742        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11743        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11744            boolean wasRunningVoice = mRunningVoice != null;
11745            mRunningVoice = session;
11746            if (!wasRunningVoice) {
11747                mVoiceWakeLock.acquire();
11748                updateSleepIfNeededLocked();
11749            }
11750        }
11751    }
11752
11753    private void updateEventDispatchingLocked() {
11754        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11755    }
11756
11757    public void setLockScreenShown(boolean showing, boolean occluded) {
11758        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11759                != PackageManager.PERMISSION_GRANTED) {
11760            throw new SecurityException("Requires permission "
11761                    + android.Manifest.permission.DEVICE_POWER);
11762        }
11763
11764        synchronized(this) {
11765            long ident = Binder.clearCallingIdentity();
11766            try {
11767                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11768                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11769                if (showing && occluded) {
11770                    // The lock screen is currently showing, but is occluded by a window that can
11771                    // show on top of the lock screen. In this can we want to dismiss the docked
11772                    // stack since it will be complicated/risky to try to put the activity on top
11773                    // of the lock screen in the right fullscreen configuration.
11774                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11775                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11776                }
11777
11778                updateSleepIfNeededLocked();
11779            } finally {
11780                Binder.restoreCallingIdentity(ident);
11781            }
11782        }
11783    }
11784
11785    @Override
11786    public void notifyLockedProfile(@UserIdInt int userId) {
11787        try {
11788            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11789                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11790            }
11791        } catch (RemoteException ex) {
11792            throw new SecurityException("Fail to check is caller a privileged app", ex);
11793        }
11794
11795        synchronized (this) {
11796            if (mStackSupervisor.isUserLockedProfile(userId)) {
11797                final long ident = Binder.clearCallingIdentity();
11798                try {
11799                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11800                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11801                        // If there is no device lock, we will show the profile's credential page.
11802                        mActivityStarter.showConfirmDeviceCredential(userId);
11803                    } else {
11804                        // Showing launcher to avoid user entering credential twice.
11805                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11806                    }
11807                } finally {
11808                    Binder.restoreCallingIdentity(ident);
11809                }
11810            }
11811        }
11812    }
11813
11814    @Override
11815    public void startConfirmDeviceCredentialIntent(Intent intent) {
11816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11817        synchronized (this) {
11818            final long ident = Binder.clearCallingIdentity();
11819            try {
11820                mActivityStarter.startConfirmCredentialIntent(intent);
11821            } finally {
11822                Binder.restoreCallingIdentity(ident);
11823            }
11824        }
11825    }
11826
11827    @Override
11828    public void stopAppSwitches() {
11829        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11830                != PackageManager.PERMISSION_GRANTED) {
11831            throw new SecurityException("viewquires permission "
11832                    + android.Manifest.permission.STOP_APP_SWITCHES);
11833        }
11834
11835        synchronized(this) {
11836            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11837                    + APP_SWITCH_DELAY_TIME;
11838            mDidAppSwitch = false;
11839            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11840            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11841            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11842        }
11843    }
11844
11845    public void resumeAppSwitches() {
11846        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11847                != PackageManager.PERMISSION_GRANTED) {
11848            throw new SecurityException("Requires permission "
11849                    + android.Manifest.permission.STOP_APP_SWITCHES);
11850        }
11851
11852        synchronized(this) {
11853            // Note that we don't execute any pending app switches... we will
11854            // let those wait until either the timeout, or the next start
11855            // activity request.
11856            mAppSwitchesAllowedTime = 0;
11857        }
11858    }
11859
11860    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11861            int callingPid, int callingUid, String name) {
11862        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11863            return true;
11864        }
11865
11866        int perm = checkComponentPermission(
11867                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11868                sourceUid, -1, true);
11869        if (perm == PackageManager.PERMISSION_GRANTED) {
11870            return true;
11871        }
11872
11873        // If the actual IPC caller is different from the logical source, then
11874        // also see if they are allowed to control app switches.
11875        if (callingUid != -1 && callingUid != sourceUid) {
11876            perm = checkComponentPermission(
11877                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11878                    callingUid, -1, true);
11879            if (perm == PackageManager.PERMISSION_GRANTED) {
11880                return true;
11881            }
11882        }
11883
11884        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11885        return false;
11886    }
11887
11888    public void setDebugApp(String packageName, boolean waitForDebugger,
11889            boolean persistent) {
11890        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11891                "setDebugApp()");
11892
11893        long ident = Binder.clearCallingIdentity();
11894        try {
11895            // Note that this is not really thread safe if there are multiple
11896            // callers into it at the same time, but that's not a situation we
11897            // care about.
11898            if (persistent) {
11899                final ContentResolver resolver = mContext.getContentResolver();
11900                Settings.Global.putString(
11901                    resolver, Settings.Global.DEBUG_APP,
11902                    packageName);
11903                Settings.Global.putInt(
11904                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11905                    waitForDebugger ? 1 : 0);
11906            }
11907
11908            synchronized (this) {
11909                if (!persistent) {
11910                    mOrigDebugApp = mDebugApp;
11911                    mOrigWaitForDebugger = mWaitForDebugger;
11912                }
11913                mDebugApp = packageName;
11914                mWaitForDebugger = waitForDebugger;
11915                mDebugTransient = !persistent;
11916                if (packageName != null) {
11917                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11918                            false, UserHandle.USER_ALL, "set debug app");
11919                }
11920            }
11921        } finally {
11922            Binder.restoreCallingIdentity(ident);
11923        }
11924    }
11925
11926    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11927        synchronized (this) {
11928            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11929            if (!isDebuggable) {
11930                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11931                    throw new SecurityException("Process not debuggable: " + app.packageName);
11932                }
11933            }
11934
11935            mTrackAllocationApp = processName;
11936        }
11937    }
11938
11939    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11940        synchronized (this) {
11941            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11942            if (!isDebuggable) {
11943                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11944                    throw new SecurityException("Process not debuggable: " + app.packageName);
11945                }
11946            }
11947            mProfileApp = processName;
11948            mProfileFile = profilerInfo.profileFile;
11949            if (mProfileFd != null) {
11950                try {
11951                    mProfileFd.close();
11952                } catch (IOException e) {
11953                }
11954                mProfileFd = null;
11955            }
11956            mProfileFd = profilerInfo.profileFd;
11957            mSamplingInterval = profilerInfo.samplingInterval;
11958            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11959            mProfileType = 0;
11960        }
11961    }
11962
11963    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11964        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11965        if (!isDebuggable) {
11966            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11967                throw new SecurityException("Process not debuggable: " + app.packageName);
11968            }
11969        }
11970        mNativeDebuggingApp = processName;
11971    }
11972
11973    @Override
11974    public void setAlwaysFinish(boolean enabled) {
11975        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11976                "setAlwaysFinish()");
11977
11978        long ident = Binder.clearCallingIdentity();
11979        try {
11980            Settings.Global.putInt(
11981                    mContext.getContentResolver(),
11982                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11983
11984            synchronized (this) {
11985                mAlwaysFinishActivities = enabled;
11986            }
11987        } finally {
11988            Binder.restoreCallingIdentity(ident);
11989        }
11990    }
11991
11992    @Override
11993    public void setLenientBackgroundCheck(boolean enabled) {
11994        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11995                "setLenientBackgroundCheck()");
11996
11997        long ident = Binder.clearCallingIdentity();
11998        try {
11999            Settings.Global.putInt(
12000                    mContext.getContentResolver(),
12001                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12002
12003            synchronized (this) {
12004                mLenientBackgroundCheck = enabled;
12005            }
12006        } finally {
12007            Binder.restoreCallingIdentity(ident);
12008        }
12009    }
12010
12011    @Override
12012    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12013        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12014                "setActivityController()");
12015        synchronized (this) {
12016            mController = controller;
12017            mControllerIsAMonkey = imAMonkey;
12018            Watchdog.getInstance().setActivityController(controller);
12019        }
12020    }
12021
12022    @Override
12023    public void setUserIsMonkey(boolean userIsMonkey) {
12024        synchronized (this) {
12025            synchronized (mPidsSelfLocked) {
12026                final int callingPid = Binder.getCallingPid();
12027                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12028                if (precessRecord == null) {
12029                    throw new SecurityException("Unknown process: " + callingPid);
12030                }
12031                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12032                    throw new SecurityException("Only an instrumentation process "
12033                            + "with a UiAutomation can call setUserIsMonkey");
12034                }
12035            }
12036            mUserIsMonkey = userIsMonkey;
12037        }
12038    }
12039
12040    @Override
12041    public boolean isUserAMonkey() {
12042        synchronized (this) {
12043            // If there is a controller also implies the user is a monkey.
12044            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12045        }
12046    }
12047
12048    public void requestBugReport(int bugreportType) {
12049        String service = null;
12050        switch (bugreportType) {
12051            case ActivityManager.BUGREPORT_OPTION_FULL:
12052                service = "bugreport";
12053                break;
12054            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12055                service = "bugreportplus";
12056                break;
12057            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12058                service = "bugreportremote";
12059                break;
12060            case ActivityManager.BUGREPORT_OPTION_WEAR:
12061                service = "bugreportwear";
12062                break;
12063        }
12064        if (service == null) {
12065            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12066                    + bugreportType);
12067        }
12068        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12069        SystemProperties.set("ctl.start", service);
12070    }
12071
12072    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12073        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12074    }
12075
12076    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12077        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12078            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12079        }
12080        return KEY_DISPATCHING_TIMEOUT;
12081    }
12082
12083    @Override
12084    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12085        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12086                != PackageManager.PERMISSION_GRANTED) {
12087            throw new SecurityException("Requires permission "
12088                    + android.Manifest.permission.FILTER_EVENTS);
12089        }
12090        ProcessRecord proc;
12091        long timeout;
12092        synchronized (this) {
12093            synchronized (mPidsSelfLocked) {
12094                proc = mPidsSelfLocked.get(pid);
12095            }
12096            timeout = getInputDispatchingTimeoutLocked(proc);
12097        }
12098
12099        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12100            return -1;
12101        }
12102
12103        return timeout;
12104    }
12105
12106    /**
12107     * Handle input dispatching timeouts.
12108     * Returns whether input dispatching should be aborted or not.
12109     */
12110    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12111            final ActivityRecord activity, final ActivityRecord parent,
12112            final boolean aboveSystem, String reason) {
12113        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12114                != PackageManager.PERMISSION_GRANTED) {
12115            throw new SecurityException("Requires permission "
12116                    + android.Manifest.permission.FILTER_EVENTS);
12117        }
12118
12119        final String annotation;
12120        if (reason == null) {
12121            annotation = "Input dispatching timed out";
12122        } else {
12123            annotation = "Input dispatching timed out (" + reason + ")";
12124        }
12125
12126        if (proc != null) {
12127            synchronized (this) {
12128                if (proc.debugging) {
12129                    return false;
12130                }
12131
12132                if (mDidDexOpt) {
12133                    // Give more time since we were dexopting.
12134                    mDidDexOpt = false;
12135                    return false;
12136                }
12137
12138                if (proc.instrumentationClass != null) {
12139                    Bundle info = new Bundle();
12140                    info.putString("shortMsg", "keyDispatchingTimedOut");
12141                    info.putString("longMsg", annotation);
12142                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12143                    return true;
12144                }
12145            }
12146            mHandler.post(new Runnable() {
12147                @Override
12148                public void run() {
12149                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12150                }
12151            });
12152        }
12153
12154        return true;
12155    }
12156
12157    @Override
12158    public Bundle getAssistContextExtras(int requestType) {
12159        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12160                null, null, true /* focused */, true /* newSessionId */,
12161                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12162        if (pae == null) {
12163            return null;
12164        }
12165        synchronized (pae) {
12166            while (!pae.haveResult) {
12167                try {
12168                    pae.wait();
12169                } catch (InterruptedException e) {
12170                }
12171            }
12172        }
12173        synchronized (this) {
12174            buildAssistBundleLocked(pae, pae.result);
12175            mPendingAssistExtras.remove(pae);
12176            mUiHandler.removeCallbacks(pae);
12177        }
12178        return pae.extras;
12179    }
12180
12181    @Override
12182    public boolean isAssistDataAllowedOnCurrentActivity() {
12183        int userId;
12184        synchronized (this) {
12185            userId = mUserController.getCurrentUserIdLocked();
12186            ActivityRecord activity = getFocusedStack().topActivity();
12187            if (activity == null) {
12188                return false;
12189            }
12190            userId = activity.userId;
12191        }
12192        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12193                Context.DEVICE_POLICY_SERVICE);
12194        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12195    }
12196
12197    @Override
12198    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12199        long ident = Binder.clearCallingIdentity();
12200        try {
12201            synchronized (this) {
12202                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12203                ActivityRecord top = getFocusedStack().topActivity();
12204                if (top != caller) {
12205                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12206                            + " is not current top " + top);
12207                    return false;
12208                }
12209                if (!top.nowVisible) {
12210                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12211                            + " is not visible");
12212                    return false;
12213                }
12214            }
12215            AssistUtils utils = new AssistUtils(mContext);
12216            return utils.showSessionForActiveService(args,
12217                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12218        } finally {
12219            Binder.restoreCallingIdentity(ident);
12220        }
12221    }
12222
12223    @Override
12224    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12225            Bundle receiverExtras,
12226            IBinder activityToken, boolean focused, boolean newSessionId) {
12227        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12228                activityToken, focused, newSessionId,
12229                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12230                != null;
12231    }
12232
12233    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12234            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12235            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12236        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12237                "enqueueAssistContext()");
12238        synchronized (this) {
12239            ActivityRecord activity = getFocusedStack().topActivity();
12240            if (activity == null) {
12241                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12242                return null;
12243            }
12244            if (activity.app == null || activity.app.thread == null) {
12245                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12246                return null;
12247            }
12248            if (focused) {
12249                if (activityToken != null) {
12250                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12251                    if (activity != caller) {
12252                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12253                                + " is not current top " + activity);
12254                        return null;
12255                    }
12256                }
12257            } else {
12258                activity = ActivityRecord.forTokenLocked(activityToken);
12259                if (activity == null) {
12260                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12261                            + " couldn't be found");
12262                    return null;
12263                }
12264            }
12265
12266            PendingAssistExtras pae;
12267            Bundle extras = new Bundle();
12268            if (args != null) {
12269                extras.putAll(args);
12270            }
12271            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12272            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12273            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12274                    userHandle);
12275            // Increment the sessionId if necessary
12276            if (newSessionId) {
12277                mViSessionId++;
12278            }
12279            try {
12280                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12281                        requestType, mViSessionId);
12282                mPendingAssistExtras.add(pae);
12283                mUiHandler.postDelayed(pae, timeout);
12284            } catch (RemoteException e) {
12285                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12286                return null;
12287            }
12288            return pae;
12289        }
12290    }
12291
12292    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12293        IResultReceiver receiver;
12294        synchronized (this) {
12295            mPendingAssistExtras.remove(pae);
12296            receiver = pae.receiver;
12297        }
12298        if (receiver != null) {
12299            // Caller wants result sent back to them.
12300            Bundle sendBundle = new Bundle();
12301            // At least return the receiver extras
12302            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12303                    pae.receiverExtras);
12304            try {
12305                pae.receiver.send(0, sendBundle);
12306            } catch (RemoteException e) {
12307            }
12308        }
12309    }
12310
12311    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12312        if (result != null) {
12313            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12314        }
12315        if (pae.hint != null) {
12316            pae.extras.putBoolean(pae.hint, true);
12317        }
12318    }
12319
12320    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12321            AssistContent content, Uri referrer) {
12322        PendingAssistExtras pae = (PendingAssistExtras)token;
12323        synchronized (pae) {
12324            pae.result = extras;
12325            pae.structure = structure;
12326            pae.content = content;
12327            if (referrer != null) {
12328                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12329            }
12330            pae.haveResult = true;
12331            pae.notifyAll();
12332            if (pae.intent == null && pae.receiver == null) {
12333                // Caller is just waiting for the result.
12334                return;
12335            }
12336        }
12337
12338        // We are now ready to launch the assist activity.
12339        IResultReceiver sendReceiver = null;
12340        Bundle sendBundle = null;
12341        synchronized (this) {
12342            buildAssistBundleLocked(pae, extras);
12343            boolean exists = mPendingAssistExtras.remove(pae);
12344            mUiHandler.removeCallbacks(pae);
12345            if (!exists) {
12346                // Timed out.
12347                return;
12348            }
12349            if ((sendReceiver=pae.receiver) != null) {
12350                // Caller wants result sent back to them.
12351                sendBundle = new Bundle();
12352                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12353                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12354                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12355                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12356                        pae.receiverExtras);
12357            }
12358        }
12359        if (sendReceiver != null) {
12360            try {
12361                sendReceiver.send(0, sendBundle);
12362            } catch (RemoteException e) {
12363            }
12364            return;
12365        }
12366
12367        long ident = Binder.clearCallingIdentity();
12368        try {
12369            pae.intent.replaceExtras(pae.extras);
12370            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12371                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12372                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12373            closeSystemDialogs("assist");
12374            try {
12375                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12376            } catch (ActivityNotFoundException e) {
12377                Slog.w(TAG, "No activity to handle assist action.", e);
12378            }
12379        } finally {
12380            Binder.restoreCallingIdentity(ident);
12381        }
12382    }
12383
12384    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12385            Bundle args) {
12386        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12387                true /* focused */, true /* newSessionId */,
12388                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12389    }
12390
12391    public void registerProcessObserver(IProcessObserver observer) {
12392        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12393                "registerProcessObserver()");
12394        synchronized (this) {
12395            mProcessObservers.register(observer);
12396        }
12397    }
12398
12399    @Override
12400    public void unregisterProcessObserver(IProcessObserver observer) {
12401        synchronized (this) {
12402            mProcessObservers.unregister(observer);
12403        }
12404    }
12405
12406    @Override
12407    public void registerUidObserver(IUidObserver observer, int which) {
12408        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12409                "registerUidObserver()");
12410        synchronized (this) {
12411            mUidObservers.register(observer, which);
12412        }
12413    }
12414
12415    @Override
12416    public void unregisterUidObserver(IUidObserver observer) {
12417        synchronized (this) {
12418            mUidObservers.unregister(observer);
12419        }
12420    }
12421
12422    @Override
12423    public boolean convertFromTranslucent(IBinder token) {
12424        final long origId = Binder.clearCallingIdentity();
12425        try {
12426            synchronized (this) {
12427                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12428                if (r == null) {
12429                    return false;
12430                }
12431                final boolean translucentChanged = r.changeWindowTranslucency(true);
12432                if (translucentChanged) {
12433                    r.task.stack.releaseBackgroundResources(r);
12434                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12435                }
12436                mWindowManager.setAppFullscreen(token, true);
12437                return translucentChanged;
12438            }
12439        } finally {
12440            Binder.restoreCallingIdentity(origId);
12441        }
12442    }
12443
12444    @Override
12445    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12446        final long origId = Binder.clearCallingIdentity();
12447        try {
12448            synchronized (this) {
12449                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12450                if (r == null) {
12451                    return false;
12452                }
12453                int index = r.task.mActivities.lastIndexOf(r);
12454                if (index > 0) {
12455                    ActivityRecord under = r.task.mActivities.get(index - 1);
12456                    under.returningOptions = options;
12457                }
12458                final boolean translucentChanged = r.changeWindowTranslucency(false);
12459                if (translucentChanged) {
12460                    r.task.stack.convertActivityToTranslucent(r);
12461                }
12462                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12463                mWindowManager.setAppFullscreen(token, false);
12464                return translucentChanged;
12465            }
12466        } finally {
12467            Binder.restoreCallingIdentity(origId);
12468        }
12469    }
12470
12471    @Override
12472    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12473        final long origId = Binder.clearCallingIdentity();
12474        try {
12475            synchronized (this) {
12476                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12477                if (r != null) {
12478                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12479                }
12480            }
12481            return false;
12482        } finally {
12483            Binder.restoreCallingIdentity(origId);
12484        }
12485    }
12486
12487    @Override
12488    public boolean isBackgroundVisibleBehind(IBinder token) {
12489        final long origId = Binder.clearCallingIdentity();
12490        try {
12491            synchronized (this) {
12492                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12493                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12494                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12495                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12496                return visible;
12497            }
12498        } finally {
12499            Binder.restoreCallingIdentity(origId);
12500        }
12501    }
12502
12503    @Override
12504    public ActivityOptions getActivityOptions(IBinder token) {
12505        final long origId = Binder.clearCallingIdentity();
12506        try {
12507            synchronized (this) {
12508                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12509                if (r != null) {
12510                    final ActivityOptions activityOptions = r.pendingOptions;
12511                    r.pendingOptions = null;
12512                    return activityOptions;
12513                }
12514                return null;
12515            }
12516        } finally {
12517            Binder.restoreCallingIdentity(origId);
12518        }
12519    }
12520
12521    @Override
12522    public void setImmersive(IBinder token, boolean immersive) {
12523        synchronized(this) {
12524            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12525            if (r == null) {
12526                throw new IllegalArgumentException();
12527            }
12528            r.immersive = immersive;
12529
12530            // update associated state if we're frontmost
12531            if (r == mFocusedActivity) {
12532                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12533                applyUpdateLockStateLocked(r);
12534            }
12535        }
12536    }
12537
12538    @Override
12539    public boolean isImmersive(IBinder token) {
12540        synchronized (this) {
12541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12542            if (r == null) {
12543                throw new IllegalArgumentException();
12544            }
12545            return r.immersive;
12546        }
12547    }
12548
12549    public void setVrThread(int tid) {
12550        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12551            throw new UnsupportedOperationException("VR mode not supported on this device!");
12552        }
12553
12554        synchronized (this) {
12555            ProcessRecord proc;
12556            synchronized (mPidsSelfLocked) {
12557                final int pid = Binder.getCallingPid();
12558                proc = mPidsSelfLocked.get(pid);
12559                if (proc != null && mInVrMode && tid >= 0) {
12560                    // ensure the tid belongs to the process
12561                    if (!Process.isThreadInProcess(pid, tid)) {
12562                        throw new IllegalArgumentException("VR thread does not belong to process");
12563                    }
12564                    // reset existing VR thread to CFS
12565                    if (proc.vrThreadTid != 0) {
12566                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12567                    }
12568                    // add check to guarantee that tid belongs to pid?
12569                    proc.vrThreadTid = tid;
12570                    // promote to FIFO now if the tid is non-zero
12571                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
12572                        Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12573                    }
12574                } else {
12575                    //Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
12576                }
12577            }
12578        }
12579    }
12580
12581    @Override
12582    public void setRenderThread(int tid) {
12583        synchronized (this) {
12584            ProcessRecord proc;
12585            synchronized (mPidsSelfLocked) {
12586                int pid = Binder.getCallingPid();
12587                proc = mPidsSelfLocked.get(pid);
12588                if (mUseFifoUiScheduling && proc != null && proc.renderThreadTid == 0 && tid > 0) {
12589                    // ensure the tid belongs to the process
12590                    if (!Process.isThreadInProcess(pid, tid)) {
12591                        throw new IllegalArgumentException(
12592                            "Render thread does not belong to process");
12593                    }
12594                    proc.renderThreadTid = tid;
12595                    if (DEBUG_OOM_ADJ) {
12596                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12597                    }
12598                    // promote to FIFO now
12599                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12600                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12601                        Process.setThreadScheduler(proc.renderThreadTid,
12602                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12603                    }
12604                } else {
12605                    if (DEBUG_OOM_ADJ) {
12606                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12607                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12608                               mUseFifoUiScheduling);
12609                    }
12610                }
12611            }
12612        }
12613    }
12614
12615    @Override
12616    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12617        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12618            throw new UnsupportedOperationException("VR mode not supported on this device!");
12619        }
12620
12621        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12622
12623        ActivityRecord r;
12624        synchronized (this) {
12625            r = ActivityRecord.isInStackLocked(token);
12626        }
12627
12628        if (r == null) {
12629            throw new IllegalArgumentException();
12630        }
12631
12632        int err;
12633        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12634                VrManagerInternal.NO_ERROR) {
12635            return err;
12636        }
12637
12638        synchronized(this) {
12639            r.requestedVrComponent = (enabled) ? packageName : null;
12640
12641            // Update associated state if this activity is currently focused
12642            if (r == mFocusedActivity) {
12643                applyUpdateVrModeLocked(r);
12644            }
12645            return 0;
12646        }
12647    }
12648
12649    @Override
12650    public boolean isVrModePackageEnabled(ComponentName packageName) {
12651        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12652            throw new UnsupportedOperationException("VR mode not supported on this device!");
12653        }
12654
12655        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12656
12657        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12658                VrManagerInternal.NO_ERROR;
12659    }
12660
12661    public boolean isTopActivityImmersive() {
12662        enforceNotIsolatedCaller("startActivity");
12663        synchronized (this) {
12664            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12665            return (r != null) ? r.immersive : false;
12666        }
12667    }
12668
12669    @Override
12670    public boolean isTopOfTask(IBinder token) {
12671        synchronized (this) {
12672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12673            if (r == null) {
12674                throw new IllegalArgumentException();
12675            }
12676            return r.task.getTopActivity() == r;
12677        }
12678    }
12679
12680    @Override
12681    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12682        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12683            String msg = "Permission Denial: setHasTopUi() from pid="
12684                    + Binder.getCallingPid()
12685                    + ", uid=" + Binder.getCallingUid()
12686                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12687            Slog.w(TAG, msg);
12688            throw new SecurityException(msg);
12689        }
12690        final int pid = Binder.getCallingPid();
12691        final long origId = Binder.clearCallingIdentity();
12692        try {
12693            synchronized (this) {
12694                boolean changed = false;
12695                ProcessRecord pr;
12696                synchronized (mPidsSelfLocked) {
12697                    pr = mPidsSelfLocked.get(pid);
12698                    if (pr == null) {
12699                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12700                        return;
12701                    }
12702                    if (pr.hasTopUi != hasTopUi) {
12703                        pr.hasTopUi = hasTopUi;
12704                        changed = true;
12705                    }
12706                }
12707                if (changed) {
12708                    updateOomAdjLocked(pr);
12709                }
12710            }
12711        } finally {
12712            Binder.restoreCallingIdentity(origId);
12713        }
12714    }
12715
12716    public final void enterSafeMode() {
12717        synchronized(this) {
12718            // It only makes sense to do this before the system is ready
12719            // and started launching other packages.
12720            if (!mSystemReady) {
12721                try {
12722                    AppGlobals.getPackageManager().enterSafeMode();
12723                } catch (RemoteException e) {
12724                }
12725            }
12726
12727            mSafeMode = true;
12728        }
12729    }
12730
12731    public final void showSafeModeOverlay() {
12732        View v = LayoutInflater.from(mContext).inflate(
12733                com.android.internal.R.layout.safe_mode, null);
12734        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12735        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12736        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12737        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12738        lp.gravity = Gravity.BOTTOM | Gravity.START;
12739        lp.format = v.getBackground().getOpacity();
12740        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12741                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12742        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12743        ((WindowManager)mContext.getSystemService(
12744                Context.WINDOW_SERVICE)).addView(v, lp);
12745    }
12746
12747    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12748        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12749            return;
12750        }
12751        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12752        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12753        synchronized (stats) {
12754            if (mBatteryStatsService.isOnBattery()) {
12755                mBatteryStatsService.enforceCallingPermission();
12756                int MY_UID = Binder.getCallingUid();
12757                final int uid;
12758                if (sender == null) {
12759                    uid = sourceUid;
12760                } else {
12761                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12762                }
12763                BatteryStatsImpl.Uid.Pkg pkg =
12764                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12765                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12766                pkg.noteWakeupAlarmLocked(tag);
12767            }
12768        }
12769    }
12770
12771    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12772        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12773            return;
12774        }
12775        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12776        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12777        synchronized (stats) {
12778            mBatteryStatsService.enforceCallingPermission();
12779            int MY_UID = Binder.getCallingUid();
12780            final int uid;
12781            if (sender == null) {
12782                uid = sourceUid;
12783            } else {
12784                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12785            }
12786            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12787        }
12788    }
12789
12790    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12791        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12792            return;
12793        }
12794        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12795        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12796        synchronized (stats) {
12797            mBatteryStatsService.enforceCallingPermission();
12798            int MY_UID = Binder.getCallingUid();
12799            final int uid;
12800            if (sender == null) {
12801                uid = sourceUid;
12802            } else {
12803                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12804            }
12805            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12806        }
12807    }
12808
12809    public boolean killPids(int[] pids, String pReason, boolean secure) {
12810        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12811            throw new SecurityException("killPids only available to the system");
12812        }
12813        String reason = (pReason == null) ? "Unknown" : pReason;
12814        // XXX Note: don't acquire main activity lock here, because the window
12815        // manager calls in with its locks held.
12816
12817        boolean killed = false;
12818        synchronized (mPidsSelfLocked) {
12819            int worstType = 0;
12820            for (int i=0; i<pids.length; i++) {
12821                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12822                if (proc != null) {
12823                    int type = proc.setAdj;
12824                    if (type > worstType) {
12825                        worstType = type;
12826                    }
12827                }
12828            }
12829
12830            // If the worst oom_adj is somewhere in the cached proc LRU range,
12831            // then constrain it so we will kill all cached procs.
12832            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12833                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12834                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12835            }
12836
12837            // If this is not a secure call, don't let it kill processes that
12838            // are important.
12839            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12840                worstType = ProcessList.SERVICE_ADJ;
12841            }
12842
12843            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12844            for (int i=0; i<pids.length; i++) {
12845                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12846                if (proc == null) {
12847                    continue;
12848                }
12849                int adj = proc.setAdj;
12850                if (adj >= worstType && !proc.killedByAm) {
12851                    proc.kill(reason, true);
12852                    killed = true;
12853                }
12854            }
12855        }
12856        return killed;
12857    }
12858
12859    @Override
12860    public void killUid(int appId, int userId, String reason) {
12861        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12862        synchronized (this) {
12863            final long identity = Binder.clearCallingIdentity();
12864            try {
12865                killPackageProcessesLocked(null, appId, userId,
12866                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12867                        reason != null ? reason : "kill uid");
12868            } finally {
12869                Binder.restoreCallingIdentity(identity);
12870            }
12871        }
12872    }
12873
12874    @Override
12875    public boolean killProcessesBelowForeground(String reason) {
12876        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12877            throw new SecurityException("killProcessesBelowForeground() only available to system");
12878        }
12879
12880        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12881    }
12882
12883    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12884        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12885            throw new SecurityException("killProcessesBelowAdj() only available to system");
12886        }
12887
12888        boolean killed = false;
12889        synchronized (mPidsSelfLocked) {
12890            final int size = mPidsSelfLocked.size();
12891            for (int i = 0; i < size; i++) {
12892                final int pid = mPidsSelfLocked.keyAt(i);
12893                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12894                if (proc == null) continue;
12895
12896                final int adj = proc.setAdj;
12897                if (adj > belowAdj && !proc.killedByAm) {
12898                    proc.kill(reason, true);
12899                    killed = true;
12900                }
12901            }
12902        }
12903        return killed;
12904    }
12905
12906    @Override
12907    public void hang(final IBinder who, boolean allowRestart) {
12908        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12909                != PackageManager.PERMISSION_GRANTED) {
12910            throw new SecurityException("Requires permission "
12911                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12912        }
12913
12914        final IBinder.DeathRecipient death = new DeathRecipient() {
12915            @Override
12916            public void binderDied() {
12917                synchronized (this) {
12918                    notifyAll();
12919                }
12920            }
12921        };
12922
12923        try {
12924            who.linkToDeath(death, 0);
12925        } catch (RemoteException e) {
12926            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12927            return;
12928        }
12929
12930        synchronized (this) {
12931            Watchdog.getInstance().setAllowRestart(allowRestart);
12932            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12933            synchronized (death) {
12934                while (who.isBinderAlive()) {
12935                    try {
12936                        death.wait();
12937                    } catch (InterruptedException e) {
12938                    }
12939                }
12940            }
12941            Watchdog.getInstance().setAllowRestart(true);
12942        }
12943    }
12944
12945    @Override
12946    public void restart() {
12947        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12948                != PackageManager.PERMISSION_GRANTED) {
12949            throw new SecurityException("Requires permission "
12950                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12951        }
12952
12953        Log.i(TAG, "Sending shutdown broadcast...");
12954
12955        BroadcastReceiver br = new BroadcastReceiver() {
12956            @Override public void onReceive(Context context, Intent intent) {
12957                // Now the broadcast is done, finish up the low-level shutdown.
12958                Log.i(TAG, "Shutting down activity manager...");
12959                shutdown(10000);
12960                Log.i(TAG, "Shutdown complete, restarting!");
12961                Process.killProcess(Process.myPid());
12962                System.exit(10);
12963            }
12964        };
12965
12966        // First send the high-level shut down broadcast.
12967        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12968        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12969        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12970        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12971        mContext.sendOrderedBroadcastAsUser(intent,
12972                UserHandle.ALL, null, br, mHandler, 0, null, null);
12973        */
12974        br.onReceive(mContext, intent);
12975    }
12976
12977    private long getLowRamTimeSinceIdle(long now) {
12978        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12979    }
12980
12981    @Override
12982    public void performIdleMaintenance() {
12983        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12984                != PackageManager.PERMISSION_GRANTED) {
12985            throw new SecurityException("Requires permission "
12986                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12987        }
12988
12989        synchronized (this) {
12990            final long now = SystemClock.uptimeMillis();
12991            final long timeSinceLastIdle = now - mLastIdleTime;
12992            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12993            mLastIdleTime = now;
12994            mLowRamTimeSinceLastIdle = 0;
12995            if (mLowRamStartTime != 0) {
12996                mLowRamStartTime = now;
12997            }
12998
12999            StringBuilder sb = new StringBuilder(128);
13000            sb.append("Idle maintenance over ");
13001            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13002            sb.append(" low RAM for ");
13003            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13004            Slog.i(TAG, sb.toString());
13005
13006            // If at least 1/3 of our time since the last idle period has been spent
13007            // with RAM low, then we want to kill processes.
13008            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13009
13010            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13011                ProcessRecord proc = mLruProcesses.get(i);
13012                if (proc.notCachedSinceIdle) {
13013                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13014                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13015                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13016                        if (doKilling && proc.initialIdlePss != 0
13017                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13018                            sb = new StringBuilder(128);
13019                            sb.append("Kill");
13020                            sb.append(proc.processName);
13021                            sb.append(" in idle maint: pss=");
13022                            sb.append(proc.lastPss);
13023                            sb.append(", swapPss=");
13024                            sb.append(proc.lastSwapPss);
13025                            sb.append(", initialPss=");
13026                            sb.append(proc.initialIdlePss);
13027                            sb.append(", period=");
13028                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13029                            sb.append(", lowRamPeriod=");
13030                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13031                            Slog.wtfQuiet(TAG, sb.toString());
13032                            proc.kill("idle maint (pss " + proc.lastPss
13033                                    + " from " + proc.initialIdlePss + ")", true);
13034                        }
13035                    }
13036                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13037                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13038                    proc.notCachedSinceIdle = true;
13039                    proc.initialIdlePss = 0;
13040                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13041                            mTestPssMode, isSleepingLocked(), now);
13042                }
13043            }
13044
13045            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13046            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13047        }
13048    }
13049
13050    @Override
13051    public void sendIdleJobTrigger() {
13052        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13053                != PackageManager.PERMISSION_GRANTED) {
13054            throw new SecurityException("Requires permission "
13055                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13056        }
13057
13058        final long ident = Binder.clearCallingIdentity();
13059        try {
13060            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13061                    .setPackage("android")
13062                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13063            broadcastIntent(null, intent, null, null, 0, null, null, null,
13064                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13065        } finally {
13066            Binder.restoreCallingIdentity(ident);
13067        }
13068    }
13069
13070    private void retrieveSettings() {
13071        final ContentResolver resolver = mContext.getContentResolver();
13072        final boolean freeformWindowManagement =
13073                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13074                        || Settings.Global.getInt(
13075                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13076        final boolean supportsPictureInPicture =
13077                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13078
13079        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13080        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13081        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13082        final boolean alwaysFinishActivities =
13083                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13084        final boolean lenientBackgroundCheck =
13085                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13086        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13087        final boolean forceResizable = Settings.Global.getInt(
13088                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13089        final boolean supportsLeanbackOnly =
13090                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13091
13092        // Transfer any global setting for forcing RTL layout, into a System Property
13093        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13094
13095        final Configuration configuration = new Configuration();
13096        Settings.System.getConfiguration(resolver, configuration);
13097        if (forceRtl) {
13098            // This will take care of setting the correct layout direction flags
13099            configuration.setLayoutDirection(configuration.locale);
13100        }
13101
13102        synchronized (this) {
13103            mDebugApp = mOrigDebugApp = debugApp;
13104            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13105            mAlwaysFinishActivities = alwaysFinishActivities;
13106            mLenientBackgroundCheck = lenientBackgroundCheck;
13107            mSupportsLeanbackOnly = supportsLeanbackOnly;
13108            mForceResizableActivities = forceResizable;
13109            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13110            if (supportsMultiWindow || forceResizable) {
13111                mSupportsMultiWindow = true;
13112                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13113                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13114            } else {
13115                mSupportsMultiWindow = false;
13116                mSupportsFreeformWindowManagement = false;
13117                mSupportsPictureInPicture = false;
13118            }
13119            // This happens before any activities are started, so we can
13120            // change mConfiguration in-place.
13121            updateConfigurationLocked(configuration, null, true);
13122            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13123                    "Initial config: " + mConfiguration);
13124
13125            // Load resources only after the current configuration has been set.
13126            final Resources res = mContext.getResources();
13127            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13128            mThumbnailWidth = res.getDimensionPixelSize(
13129                    com.android.internal.R.dimen.thumbnail_width);
13130            mThumbnailHeight = res.getDimensionPixelSize(
13131                    com.android.internal.R.dimen.thumbnail_height);
13132            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13133                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
13134            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13135                    com.android.internal.R.string.config_appsNotReportingCrashes));
13136            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13137                mFullscreenThumbnailScale = (float) res
13138                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13139                    (float) mConfiguration.screenWidthDp;
13140            } else {
13141                mFullscreenThumbnailScale = res.getFraction(
13142                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13143            }
13144        }
13145    }
13146
13147    public boolean testIsSystemReady() {
13148        // no need to synchronize(this) just to read & return the value
13149        return mSystemReady;
13150    }
13151
13152    public void systemReady(final Runnable goingCallback) {
13153        synchronized(this) {
13154            if (mSystemReady) {
13155                // If we're done calling all the receivers, run the next "boot phase" passed in
13156                // by the SystemServer
13157                if (goingCallback != null) {
13158                    goingCallback.run();
13159                }
13160                return;
13161            }
13162
13163            mLocalDeviceIdleController
13164                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13165
13166            // Make sure we have the current profile info, since it is needed for security checks.
13167            mUserController.onSystemReady();
13168            mRecentTasks.onSystemReadyLocked();
13169            mAppOpsService.systemReady();
13170            mSystemReady = true;
13171        }
13172
13173        ArrayList<ProcessRecord> procsToKill = null;
13174        synchronized(mPidsSelfLocked) {
13175            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13176                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13177                if (!isAllowedWhileBooting(proc.info)){
13178                    if (procsToKill == null) {
13179                        procsToKill = new ArrayList<ProcessRecord>();
13180                    }
13181                    procsToKill.add(proc);
13182                }
13183            }
13184        }
13185
13186        synchronized(this) {
13187            if (procsToKill != null) {
13188                for (int i=procsToKill.size()-1; i>=0; i--) {
13189                    ProcessRecord proc = procsToKill.get(i);
13190                    Slog.i(TAG, "Removing system update proc: " + proc);
13191                    removeProcessLocked(proc, true, false, "system update done");
13192                }
13193            }
13194
13195            // Now that we have cleaned up any update processes, we
13196            // are ready to start launching real processes and know that
13197            // we won't trample on them any more.
13198            mProcessesReady = true;
13199        }
13200
13201        Slog.i(TAG, "System now ready");
13202        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13203            SystemClock.uptimeMillis());
13204
13205        synchronized(this) {
13206            // Make sure we have no pre-ready processes sitting around.
13207
13208            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13209                ResolveInfo ri = mContext.getPackageManager()
13210                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13211                                STOCK_PM_FLAGS);
13212                CharSequence errorMsg = null;
13213                if (ri != null) {
13214                    ActivityInfo ai = ri.activityInfo;
13215                    ApplicationInfo app = ai.applicationInfo;
13216                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13217                        mTopAction = Intent.ACTION_FACTORY_TEST;
13218                        mTopData = null;
13219                        mTopComponent = new ComponentName(app.packageName,
13220                                ai.name);
13221                    } else {
13222                        errorMsg = mContext.getResources().getText(
13223                                com.android.internal.R.string.factorytest_not_system);
13224                    }
13225                } else {
13226                    errorMsg = mContext.getResources().getText(
13227                            com.android.internal.R.string.factorytest_no_action);
13228                }
13229                if (errorMsg != null) {
13230                    mTopAction = null;
13231                    mTopData = null;
13232                    mTopComponent = null;
13233                    Message msg = Message.obtain();
13234                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13235                    msg.getData().putCharSequence("msg", errorMsg);
13236                    mUiHandler.sendMessage(msg);
13237                }
13238            }
13239        }
13240
13241        retrieveSettings();
13242        final int currentUserId;
13243        synchronized (this) {
13244            currentUserId = mUserController.getCurrentUserIdLocked();
13245            readGrantedUriPermissionsLocked();
13246        }
13247
13248        if (goingCallback != null) goingCallback.run();
13249
13250        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13251                Integer.toString(currentUserId), currentUserId);
13252        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13253                Integer.toString(currentUserId), currentUserId);
13254        mSystemServiceManager.startUser(currentUserId);
13255
13256        synchronized (this) {
13257            // Only start up encryption-aware persistent apps; once user is
13258            // unlocked we'll come back around and start unaware apps
13259            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13260
13261            // Start up initial activity.
13262            mBooting = true;
13263            // Enable home activity for system user, so that the system can always boot
13264            if (UserManager.isSplitSystemUser()) {
13265                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13266                try {
13267                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13268                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13269                            UserHandle.USER_SYSTEM);
13270                } catch (RemoteException e) {
13271                    throw e.rethrowAsRuntimeException();
13272                }
13273            }
13274            startHomeActivityLocked(currentUserId, "systemReady");
13275
13276            try {
13277                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13278                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13279                            + " data partition or your device will be unstable.");
13280                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13281                }
13282            } catch (RemoteException e) {
13283            }
13284
13285            if (!Build.isBuildConsistent()) {
13286                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13287                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13288            }
13289
13290            long ident = Binder.clearCallingIdentity();
13291            try {
13292                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13293                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13294                        | Intent.FLAG_RECEIVER_FOREGROUND);
13295                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13296                broadcastIntentLocked(null, null, intent,
13297                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13298                        null, false, false, MY_PID, Process.SYSTEM_UID,
13299                        currentUserId);
13300                intent = new Intent(Intent.ACTION_USER_STARTING);
13301                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13302                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13303                broadcastIntentLocked(null, null, intent,
13304                        null, new IIntentReceiver.Stub() {
13305                            @Override
13306                            public void performReceive(Intent intent, int resultCode, String data,
13307                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13308                                    throws RemoteException {
13309                            }
13310                        }, 0, null, null,
13311                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13312                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13313            } catch (Throwable t) {
13314                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13315            } finally {
13316                Binder.restoreCallingIdentity(ident);
13317            }
13318            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13319            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13320        }
13321    }
13322
13323    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13324        synchronized (this) {
13325            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13326        }
13327    }
13328
13329    void skipCurrentReceiverLocked(ProcessRecord app) {
13330        for (BroadcastQueue queue : mBroadcastQueues) {
13331            queue.skipCurrentReceiverLocked(app);
13332        }
13333    }
13334
13335    /**
13336     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13337     * The application process will exit immediately after this call returns.
13338     * @param app object of the crashing app, null for the system server
13339     * @param crashInfo describing the exception
13340     */
13341    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13342        ProcessRecord r = findAppProcess(app, "Crash");
13343        final String processName = app == null ? "system_server"
13344                : (r == null ? "unknown" : r.processName);
13345
13346        handleApplicationCrashInner("crash", r, processName, crashInfo);
13347    }
13348
13349    /* Native crash reporting uses this inner version because it needs to be somewhat
13350     * decoupled from the AM-managed cleanup lifecycle
13351     */
13352    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13353            ApplicationErrorReport.CrashInfo crashInfo) {
13354        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13355                UserHandle.getUserId(Binder.getCallingUid()), processName,
13356                r == null ? -1 : r.info.flags,
13357                crashInfo.exceptionClassName,
13358                crashInfo.exceptionMessage,
13359                crashInfo.throwFileName,
13360                crashInfo.throwLineNumber);
13361
13362        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13363
13364        mAppErrors.crashApplication(r, crashInfo);
13365    }
13366
13367    public void handleApplicationStrictModeViolation(
13368            IBinder app,
13369            int violationMask,
13370            StrictMode.ViolationInfo info) {
13371        ProcessRecord r = findAppProcess(app, "StrictMode");
13372        if (r == null) {
13373            return;
13374        }
13375
13376        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13377            Integer stackFingerprint = info.hashCode();
13378            boolean logIt = true;
13379            synchronized (mAlreadyLoggedViolatedStacks) {
13380                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13381                    logIt = false;
13382                    // TODO: sub-sample into EventLog for these, with
13383                    // the info.durationMillis?  Then we'd get
13384                    // the relative pain numbers, without logging all
13385                    // the stack traces repeatedly.  We'd want to do
13386                    // likewise in the client code, which also does
13387                    // dup suppression, before the Binder call.
13388                } else {
13389                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13390                        mAlreadyLoggedViolatedStacks.clear();
13391                    }
13392                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13393                }
13394            }
13395            if (logIt) {
13396                logStrictModeViolationToDropBox(r, info);
13397            }
13398        }
13399
13400        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13401            AppErrorResult result = new AppErrorResult();
13402            synchronized (this) {
13403                final long origId = Binder.clearCallingIdentity();
13404
13405                Message msg = Message.obtain();
13406                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13407                HashMap<String, Object> data = new HashMap<String, Object>();
13408                data.put("result", result);
13409                data.put("app", r);
13410                data.put("violationMask", violationMask);
13411                data.put("info", info);
13412                msg.obj = data;
13413                mUiHandler.sendMessage(msg);
13414
13415                Binder.restoreCallingIdentity(origId);
13416            }
13417            int res = result.get();
13418            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13419        }
13420    }
13421
13422    // Depending on the policy in effect, there could be a bunch of
13423    // these in quick succession so we try to batch these together to
13424    // minimize disk writes, number of dropbox entries, and maximize
13425    // compression, by having more fewer, larger records.
13426    private void logStrictModeViolationToDropBox(
13427            ProcessRecord process,
13428            StrictMode.ViolationInfo info) {
13429        if (info == null) {
13430            return;
13431        }
13432        final boolean isSystemApp = process == null ||
13433                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13434                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13435        final String processName = process == null ? "unknown" : process.processName;
13436        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13437        final DropBoxManager dbox = (DropBoxManager)
13438                mContext.getSystemService(Context.DROPBOX_SERVICE);
13439
13440        // Exit early if the dropbox isn't configured to accept this report type.
13441        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13442
13443        boolean bufferWasEmpty;
13444        boolean needsFlush;
13445        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13446        synchronized (sb) {
13447            bufferWasEmpty = sb.length() == 0;
13448            appendDropBoxProcessHeaders(process, processName, sb);
13449            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13450            sb.append("System-App: ").append(isSystemApp).append("\n");
13451            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13452            if (info.violationNumThisLoop != 0) {
13453                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13454            }
13455            if (info.numAnimationsRunning != 0) {
13456                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13457            }
13458            if (info.broadcastIntentAction != null) {
13459                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13460            }
13461            if (info.durationMillis != -1) {
13462                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13463            }
13464            if (info.numInstances != -1) {
13465                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13466            }
13467            if (info.tags != null) {
13468                for (String tag : info.tags) {
13469                    sb.append("Span-Tag: ").append(tag).append("\n");
13470                }
13471            }
13472            sb.append("\n");
13473            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13474                sb.append(info.crashInfo.stackTrace);
13475                sb.append("\n");
13476            }
13477            if (info.message != null) {
13478                sb.append(info.message);
13479                sb.append("\n");
13480            }
13481
13482            // Only buffer up to ~64k.  Various logging bits truncate
13483            // things at 128k.
13484            needsFlush = (sb.length() > 64 * 1024);
13485        }
13486
13487        // Flush immediately if the buffer's grown too large, or this
13488        // is a non-system app.  Non-system apps are isolated with a
13489        // different tag & policy and not batched.
13490        //
13491        // Batching is useful during internal testing with
13492        // StrictMode settings turned up high.  Without batching,
13493        // thousands of separate files could be created on boot.
13494        if (!isSystemApp || needsFlush) {
13495            new Thread("Error dump: " + dropboxTag) {
13496                @Override
13497                public void run() {
13498                    String report;
13499                    synchronized (sb) {
13500                        report = sb.toString();
13501                        sb.delete(0, sb.length());
13502                        sb.trimToSize();
13503                    }
13504                    if (report.length() != 0) {
13505                        dbox.addText(dropboxTag, report);
13506                    }
13507                }
13508            }.start();
13509            return;
13510        }
13511
13512        // System app batching:
13513        if (!bufferWasEmpty) {
13514            // An existing dropbox-writing thread is outstanding, so
13515            // we don't need to start it up.  The existing thread will
13516            // catch the buffer appends we just did.
13517            return;
13518        }
13519
13520        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13521        // (After this point, we shouldn't access AMS internal data structures.)
13522        new Thread("Error dump: " + dropboxTag) {
13523            @Override
13524            public void run() {
13525                // 5 second sleep to let stacks arrive and be batched together
13526                try {
13527                    Thread.sleep(5000);  // 5 seconds
13528                } catch (InterruptedException e) {}
13529
13530                String errorReport;
13531                synchronized (mStrictModeBuffer) {
13532                    errorReport = mStrictModeBuffer.toString();
13533                    if (errorReport.length() == 0) {
13534                        return;
13535                    }
13536                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13537                    mStrictModeBuffer.trimToSize();
13538                }
13539                dbox.addText(dropboxTag, errorReport);
13540            }
13541        }.start();
13542    }
13543
13544    /**
13545     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13546     * @param app object of the crashing app, null for the system server
13547     * @param tag reported by the caller
13548     * @param system whether this wtf is coming from the system
13549     * @param crashInfo describing the context of the error
13550     * @return true if the process should exit immediately (WTF is fatal)
13551     */
13552    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13553            final ApplicationErrorReport.CrashInfo crashInfo) {
13554        final int callingUid = Binder.getCallingUid();
13555        final int callingPid = Binder.getCallingPid();
13556
13557        if (system) {
13558            // If this is coming from the system, we could very well have low-level
13559            // system locks held, so we want to do this all asynchronously.  And we
13560            // never want this to become fatal, so there is that too.
13561            mHandler.post(new Runnable() {
13562                @Override public void run() {
13563                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13564                }
13565            });
13566            return false;
13567        }
13568
13569        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13570                crashInfo);
13571
13572        if (r != null && r.pid != Process.myPid() &&
13573                Settings.Global.getInt(mContext.getContentResolver(),
13574                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13575            mAppErrors.crashApplication(r, crashInfo);
13576            return true;
13577        } else {
13578            return false;
13579        }
13580    }
13581
13582    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13583            final ApplicationErrorReport.CrashInfo crashInfo) {
13584        final ProcessRecord r = findAppProcess(app, "WTF");
13585        final String processName = app == null ? "system_server"
13586                : (r == null ? "unknown" : r.processName);
13587
13588        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13589                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13590
13591        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13592
13593        return r;
13594    }
13595
13596    /**
13597     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13598     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13599     */
13600    private ProcessRecord findAppProcess(IBinder app, String reason) {
13601        if (app == null) {
13602            return null;
13603        }
13604
13605        synchronized (this) {
13606            final int NP = mProcessNames.getMap().size();
13607            for (int ip=0; ip<NP; ip++) {
13608                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13609                final int NA = apps.size();
13610                for (int ia=0; ia<NA; ia++) {
13611                    ProcessRecord p = apps.valueAt(ia);
13612                    if (p.thread != null && p.thread.asBinder() == app) {
13613                        return p;
13614                    }
13615                }
13616            }
13617
13618            Slog.w(TAG, "Can't find mystery application for " + reason
13619                    + " from pid=" + Binder.getCallingPid()
13620                    + " uid=" + Binder.getCallingUid() + ": " + app);
13621            return null;
13622        }
13623    }
13624
13625    /**
13626     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13627     * to append various headers to the dropbox log text.
13628     */
13629    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13630            StringBuilder sb) {
13631        // Watchdog thread ends up invoking this function (with
13632        // a null ProcessRecord) to add the stack file to dropbox.
13633        // Do not acquire a lock on this (am) in such cases, as it
13634        // could cause a potential deadlock, if and when watchdog
13635        // is invoked due to unavailability of lock on am and it
13636        // would prevent watchdog from killing system_server.
13637        if (process == null) {
13638            sb.append("Process: ").append(processName).append("\n");
13639            return;
13640        }
13641        // Note: ProcessRecord 'process' is guarded by the service
13642        // instance.  (notably process.pkgList, which could otherwise change
13643        // concurrently during execution of this method)
13644        synchronized (this) {
13645            sb.append("Process: ").append(processName).append("\n");
13646            int flags = process.info.flags;
13647            IPackageManager pm = AppGlobals.getPackageManager();
13648            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13649            for (int ip=0; ip<process.pkgList.size(); ip++) {
13650                String pkg = process.pkgList.keyAt(ip);
13651                sb.append("Package: ").append(pkg);
13652                try {
13653                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13654                    if (pi != null) {
13655                        sb.append(" v").append(pi.versionCode);
13656                        if (pi.versionName != null) {
13657                            sb.append(" (").append(pi.versionName).append(")");
13658                        }
13659                    }
13660                } catch (RemoteException e) {
13661                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13662                }
13663                sb.append("\n");
13664            }
13665        }
13666    }
13667
13668    private static String processClass(ProcessRecord process) {
13669        if (process == null || process.pid == MY_PID) {
13670            return "system_server";
13671        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13672            return "system_app";
13673        } else {
13674            return "data_app";
13675        }
13676    }
13677
13678    private volatile long mWtfClusterStart;
13679    private volatile int mWtfClusterCount;
13680
13681    /**
13682     * Write a description of an error (crash, WTF, ANR) to the drop box.
13683     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13684     * @param process which caused the error, null means the system server
13685     * @param activity which triggered the error, null if unknown
13686     * @param parent activity related to the error, null if unknown
13687     * @param subject line related to the error, null if absent
13688     * @param report in long form describing the error, null if absent
13689     * @param dataFile text file to include in the report, null if none
13690     * @param crashInfo giving an application stack trace, null if absent
13691     */
13692    public void addErrorToDropBox(String eventType,
13693            ProcessRecord process, String processName, ActivityRecord activity,
13694            ActivityRecord parent, String subject,
13695            final String report, final File dataFile,
13696            final ApplicationErrorReport.CrashInfo crashInfo) {
13697        // NOTE -- this must never acquire the ActivityManagerService lock,
13698        // otherwise the watchdog may be prevented from resetting the system.
13699
13700        final String dropboxTag = processClass(process) + "_" + eventType;
13701        final DropBoxManager dbox = (DropBoxManager)
13702                mContext.getSystemService(Context.DROPBOX_SERVICE);
13703
13704        // Exit early if the dropbox isn't configured to accept this report type.
13705        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13706
13707        // Rate-limit how often we're willing to do the heavy lifting below to
13708        // collect and record logs; currently 5 logs per 10 second period.
13709        final long now = SystemClock.elapsedRealtime();
13710        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13711            mWtfClusterStart = now;
13712            mWtfClusterCount = 1;
13713        } else {
13714            if (mWtfClusterCount++ >= 5) return;
13715        }
13716
13717        final StringBuilder sb = new StringBuilder(1024);
13718        appendDropBoxProcessHeaders(process, processName, sb);
13719        if (process != null) {
13720            sb.append("Foreground: ")
13721                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13722                    .append("\n");
13723        }
13724        if (activity != null) {
13725            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13726        }
13727        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13728            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13729        }
13730        if (parent != null && parent != activity) {
13731            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13732        }
13733        if (subject != null) {
13734            sb.append("Subject: ").append(subject).append("\n");
13735        }
13736        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13737        if (Debug.isDebuggerConnected()) {
13738            sb.append("Debugger: Connected\n");
13739        }
13740        sb.append("\n");
13741
13742        // Do the rest in a worker thread to avoid blocking the caller on I/O
13743        // (After this point, we shouldn't access AMS internal data structures.)
13744        Thread worker = new Thread("Error dump: " + dropboxTag) {
13745            @Override
13746            public void run() {
13747                if (report != null) {
13748                    sb.append(report);
13749                }
13750
13751                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13752                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13753                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13754                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13755
13756                if (dataFile != null && maxDataFileSize > 0) {
13757                    try {
13758                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13759                                    "\n\n[[TRUNCATED]]"));
13760                    } catch (IOException e) {
13761                        Slog.e(TAG, "Error reading " + dataFile, e);
13762                    }
13763                }
13764                if (crashInfo != null && crashInfo.stackTrace != null) {
13765                    sb.append(crashInfo.stackTrace);
13766                }
13767
13768                if (lines > 0) {
13769                    sb.append("\n");
13770
13771                    // Merge several logcat streams, and take the last N lines
13772                    InputStreamReader input = null;
13773                    try {
13774                        java.lang.Process logcat = new ProcessBuilder(
13775                                "/system/bin/timeout", "-k", "15s", "10s",
13776                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13777                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13778                                        .redirectErrorStream(true).start();
13779
13780                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13781                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13782                        input = new InputStreamReader(logcat.getInputStream());
13783
13784                        int num;
13785                        char[] buf = new char[8192];
13786                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13787                    } catch (IOException e) {
13788                        Slog.e(TAG, "Error running logcat", e);
13789                    } finally {
13790                        if (input != null) try { input.close(); } catch (IOException e) {}
13791                    }
13792                }
13793
13794                dbox.addText(dropboxTag, sb.toString());
13795            }
13796        };
13797
13798        if (process == null) {
13799            // If process is null, we are being called from some internal code
13800            // and may be about to die -- run this synchronously.
13801            worker.run();
13802        } else {
13803            worker.start();
13804        }
13805    }
13806
13807    @Override
13808    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13809        enforceNotIsolatedCaller("getProcessesInErrorState");
13810        // assume our apps are happy - lazy create the list
13811        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13812
13813        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13814                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13815        int userId = UserHandle.getUserId(Binder.getCallingUid());
13816
13817        synchronized (this) {
13818
13819            // iterate across all processes
13820            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13821                ProcessRecord app = mLruProcesses.get(i);
13822                if (!allUsers && app.userId != userId) {
13823                    continue;
13824                }
13825                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13826                    // This one's in trouble, so we'll generate a report for it
13827                    // crashes are higher priority (in case there's a crash *and* an anr)
13828                    ActivityManager.ProcessErrorStateInfo report = null;
13829                    if (app.crashing) {
13830                        report = app.crashingReport;
13831                    } else if (app.notResponding) {
13832                        report = app.notRespondingReport;
13833                    }
13834
13835                    if (report != null) {
13836                        if (errList == null) {
13837                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13838                        }
13839                        errList.add(report);
13840                    } else {
13841                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13842                                " crashing = " + app.crashing +
13843                                " notResponding = " + app.notResponding);
13844                    }
13845                }
13846            }
13847        }
13848
13849        return errList;
13850    }
13851
13852    static int procStateToImportance(int procState, int memAdj,
13853            ActivityManager.RunningAppProcessInfo currApp) {
13854        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13855        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13856            currApp.lru = memAdj;
13857        } else {
13858            currApp.lru = 0;
13859        }
13860        return imp;
13861    }
13862
13863    private void fillInProcMemInfo(ProcessRecord app,
13864            ActivityManager.RunningAppProcessInfo outInfo) {
13865        outInfo.pid = app.pid;
13866        outInfo.uid = app.info.uid;
13867        if (mHeavyWeightProcess == app) {
13868            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13869        }
13870        if (app.persistent) {
13871            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13872        }
13873        if (app.activities.size() > 0) {
13874            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13875        }
13876        outInfo.lastTrimLevel = app.trimMemoryLevel;
13877        int adj = app.curAdj;
13878        int procState = app.curProcState;
13879        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13880        outInfo.importanceReasonCode = app.adjTypeCode;
13881        outInfo.processState = app.curProcState;
13882    }
13883
13884    @Override
13885    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13886        enforceNotIsolatedCaller("getRunningAppProcesses");
13887
13888        final int callingUid = Binder.getCallingUid();
13889
13890        // Lazy instantiation of list
13891        List<ActivityManager.RunningAppProcessInfo> runList = null;
13892        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13893                callingUid) == PackageManager.PERMISSION_GRANTED;
13894        final int userId = UserHandle.getUserId(callingUid);
13895        final boolean allUids = isGetTasksAllowed(
13896                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13897
13898        synchronized (this) {
13899            // Iterate across all processes
13900            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13901                ProcessRecord app = mLruProcesses.get(i);
13902                if ((!allUsers && app.userId != userId)
13903                        || (!allUids && app.uid != callingUid)) {
13904                    continue;
13905                }
13906                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13907                    // Generate process state info for running application
13908                    ActivityManager.RunningAppProcessInfo currApp =
13909                        new ActivityManager.RunningAppProcessInfo(app.processName,
13910                                app.pid, app.getPackageList());
13911                    fillInProcMemInfo(app, currApp);
13912                    if (app.adjSource instanceof ProcessRecord) {
13913                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13914                        currApp.importanceReasonImportance =
13915                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13916                                        app.adjSourceProcState);
13917                    } else if (app.adjSource instanceof ActivityRecord) {
13918                        ActivityRecord r = (ActivityRecord)app.adjSource;
13919                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13920                    }
13921                    if (app.adjTarget instanceof ComponentName) {
13922                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13923                    }
13924                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13925                    //        + " lru=" + currApp.lru);
13926                    if (runList == null) {
13927                        runList = new ArrayList<>();
13928                    }
13929                    runList.add(currApp);
13930                }
13931            }
13932        }
13933        return runList;
13934    }
13935
13936    @Override
13937    public List<ApplicationInfo> getRunningExternalApplications() {
13938        enforceNotIsolatedCaller("getRunningExternalApplications");
13939        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13940        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13941        if (runningApps != null && runningApps.size() > 0) {
13942            Set<String> extList = new HashSet<String>();
13943            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13944                if (app.pkgList != null) {
13945                    for (String pkg : app.pkgList) {
13946                        extList.add(pkg);
13947                    }
13948                }
13949            }
13950            IPackageManager pm = AppGlobals.getPackageManager();
13951            for (String pkg : extList) {
13952                try {
13953                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13954                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13955                        retList.add(info);
13956                    }
13957                } catch (RemoteException e) {
13958                }
13959            }
13960        }
13961        return retList;
13962    }
13963
13964    @Override
13965    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13966        enforceNotIsolatedCaller("getMyMemoryState");
13967        synchronized (this) {
13968            ProcessRecord proc;
13969            synchronized (mPidsSelfLocked) {
13970                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13971            }
13972            fillInProcMemInfo(proc, outInfo);
13973        }
13974    }
13975
13976    @Override
13977    public int getMemoryTrimLevel() {
13978        enforceNotIsolatedCaller("getMyMemoryState");
13979        synchronized (this) {
13980            return mLastMemoryLevel;
13981        }
13982    }
13983
13984    @Override
13985    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13986            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13987        (new ActivityManagerShellCommand(this, false)).exec(
13988                this, in, out, err, args, resultReceiver);
13989    }
13990
13991    @Override
13992    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13993        if (checkCallingPermission(android.Manifest.permission.DUMP)
13994                != PackageManager.PERMISSION_GRANTED) {
13995            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13996                    + Binder.getCallingPid()
13997                    + ", uid=" + Binder.getCallingUid()
13998                    + " without permission "
13999                    + android.Manifest.permission.DUMP);
14000            return;
14001        }
14002
14003        boolean dumpAll = false;
14004        boolean dumpClient = false;
14005        boolean dumpCheckin = false;
14006        boolean dumpCheckinFormat = false;
14007        String dumpPackage = null;
14008
14009        int opti = 0;
14010        while (opti < args.length) {
14011            String opt = args[opti];
14012            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14013                break;
14014            }
14015            opti++;
14016            if ("-a".equals(opt)) {
14017                dumpAll = true;
14018            } else if ("-c".equals(opt)) {
14019                dumpClient = true;
14020            } else if ("-p".equals(opt)) {
14021                if (opti < args.length) {
14022                    dumpPackage = args[opti];
14023                    opti++;
14024                } else {
14025                    pw.println("Error: -p option requires package argument");
14026                    return;
14027                }
14028                dumpClient = true;
14029            } else if ("--checkin".equals(opt)) {
14030                dumpCheckin = dumpCheckinFormat = true;
14031            } else if ("-C".equals(opt)) {
14032                dumpCheckinFormat = true;
14033            } else if ("-h".equals(opt)) {
14034                ActivityManagerShellCommand.dumpHelp(pw, true);
14035                return;
14036            } else {
14037                pw.println("Unknown argument: " + opt + "; use -h for help");
14038            }
14039        }
14040
14041        long origId = Binder.clearCallingIdentity();
14042        boolean more = false;
14043        // Is the caller requesting to dump a particular piece of data?
14044        if (opti < args.length) {
14045            String cmd = args[opti];
14046            opti++;
14047            if ("activities".equals(cmd) || "a".equals(cmd)) {
14048                synchronized (this) {
14049                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14050                }
14051            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14052                synchronized (this) {
14053                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14054                }
14055            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14056                String[] newArgs;
14057                String name;
14058                if (opti >= args.length) {
14059                    name = null;
14060                    newArgs = EMPTY_STRING_ARRAY;
14061                } else {
14062                    dumpPackage = args[opti];
14063                    opti++;
14064                    newArgs = new String[args.length - opti];
14065                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14066                            args.length - opti);
14067                }
14068                synchronized (this) {
14069                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14070                }
14071            } else if ("broadcast-stats".equals(cmd)) {
14072                String[] newArgs;
14073                String name;
14074                if (opti >= args.length) {
14075                    name = null;
14076                    newArgs = EMPTY_STRING_ARRAY;
14077                } else {
14078                    dumpPackage = args[opti];
14079                    opti++;
14080                    newArgs = new String[args.length - opti];
14081                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14082                            args.length - opti);
14083                }
14084                synchronized (this) {
14085                    if (dumpCheckinFormat) {
14086                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14087                                dumpPackage);
14088                    } else {
14089                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14090                    }
14091                }
14092            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14093                String[] newArgs;
14094                String name;
14095                if (opti >= args.length) {
14096                    name = null;
14097                    newArgs = EMPTY_STRING_ARRAY;
14098                } else {
14099                    dumpPackage = args[opti];
14100                    opti++;
14101                    newArgs = new String[args.length - opti];
14102                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14103                            args.length - opti);
14104                }
14105                synchronized (this) {
14106                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14107                }
14108            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14109                String[] newArgs;
14110                String name;
14111                if (opti >= args.length) {
14112                    name = null;
14113                    newArgs = EMPTY_STRING_ARRAY;
14114                } else {
14115                    dumpPackage = args[opti];
14116                    opti++;
14117                    newArgs = new String[args.length - opti];
14118                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14119                            args.length - opti);
14120                }
14121                synchronized (this) {
14122                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14123                }
14124            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14125                synchronized (this) {
14126                    dumpOomLocked(fd, pw, args, opti, true);
14127                }
14128            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14129                synchronized (this) {
14130                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14131                }
14132            } else if ("provider".equals(cmd)) {
14133                String[] newArgs;
14134                String name;
14135                if (opti >= args.length) {
14136                    name = null;
14137                    newArgs = EMPTY_STRING_ARRAY;
14138                } else {
14139                    name = args[opti];
14140                    opti++;
14141                    newArgs = new String[args.length - opti];
14142                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14143                }
14144                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14145                    pw.println("No providers match: " + name);
14146                    pw.println("Use -h for help.");
14147                }
14148            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14149                synchronized (this) {
14150                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14151                }
14152            } else if ("service".equals(cmd)) {
14153                String[] newArgs;
14154                String name;
14155                if (opti >= args.length) {
14156                    name = null;
14157                    newArgs = EMPTY_STRING_ARRAY;
14158                } else {
14159                    name = args[opti];
14160                    opti++;
14161                    newArgs = new String[args.length - opti];
14162                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14163                            args.length - opti);
14164                }
14165                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14166                    pw.println("No services match: " + name);
14167                    pw.println("Use -h for help.");
14168                }
14169            } else if ("package".equals(cmd)) {
14170                String[] newArgs;
14171                if (opti >= args.length) {
14172                    pw.println("package: no package name specified");
14173                    pw.println("Use -h for help.");
14174                } else {
14175                    dumpPackage = args[opti];
14176                    opti++;
14177                    newArgs = new String[args.length - opti];
14178                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14179                            args.length - opti);
14180                    args = newArgs;
14181                    opti = 0;
14182                    more = true;
14183                }
14184            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14185                synchronized (this) {
14186                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14187                }
14188            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14189                if (dumpClient) {
14190                    ActiveServices.ServiceDumper dumper;
14191                    synchronized (this) {
14192                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14193                                dumpPackage);
14194                    }
14195                    dumper.dumpWithClient();
14196                } else {
14197                    synchronized (this) {
14198                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14199                                dumpPackage).dumpLocked();
14200                    }
14201                }
14202            } else if ("locks".equals(cmd)) {
14203                LockGuard.dump(fd, pw, args);
14204            } else {
14205                // Dumping a single activity?
14206                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14207                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14208                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14209                    if (res < 0) {
14210                        pw.println("Bad activity command, or no activities match: " + cmd);
14211                        pw.println("Use -h for help.");
14212                    }
14213                }
14214            }
14215            if (!more) {
14216                Binder.restoreCallingIdentity(origId);
14217                return;
14218            }
14219        }
14220
14221        // No piece of data specified, dump everything.
14222        if (dumpCheckinFormat) {
14223            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14224        } else if (dumpClient) {
14225            ActiveServices.ServiceDumper sdumper;
14226            synchronized (this) {
14227                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14228                pw.println();
14229                if (dumpAll) {
14230                    pw.println("-------------------------------------------------------------------------------");
14231                }
14232                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14233                pw.println();
14234                if (dumpAll) {
14235                    pw.println("-------------------------------------------------------------------------------");
14236                }
14237                if (dumpAll || dumpPackage != null) {
14238                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14239                    pw.println();
14240                    if (dumpAll) {
14241                        pw.println("-------------------------------------------------------------------------------");
14242                    }
14243                }
14244                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14245                pw.println();
14246                if (dumpAll) {
14247                    pw.println("-------------------------------------------------------------------------------");
14248                }
14249                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14250                pw.println();
14251                if (dumpAll) {
14252                    pw.println("-------------------------------------------------------------------------------");
14253                }
14254                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14255                        dumpPackage);
14256            }
14257            sdumper.dumpWithClient();
14258            pw.println();
14259            synchronized (this) {
14260                if (dumpAll) {
14261                    pw.println("-------------------------------------------------------------------------------");
14262                }
14263                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14264                pw.println();
14265                if (dumpAll) {
14266                    pw.println("-------------------------------------------------------------------------------");
14267                }
14268                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14269                if (mAssociations.size() > 0) {
14270                    pw.println();
14271                    if (dumpAll) {
14272                        pw.println("-------------------------------------------------------------------------------");
14273                    }
14274                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14275                }
14276                pw.println();
14277                if (dumpAll) {
14278                    pw.println("-------------------------------------------------------------------------------");
14279                }
14280                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14281            }
14282
14283        } else {
14284            synchronized (this) {
14285                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14286                pw.println();
14287                if (dumpAll) {
14288                    pw.println("-------------------------------------------------------------------------------");
14289                }
14290                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14291                pw.println();
14292                if (dumpAll) {
14293                    pw.println("-------------------------------------------------------------------------------");
14294                }
14295                if (dumpAll || dumpPackage != null) {
14296                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14297                    pw.println();
14298                    if (dumpAll) {
14299                        pw.println("-------------------------------------------------------------------------------");
14300                    }
14301                }
14302                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14303                pw.println();
14304                if (dumpAll) {
14305                    pw.println("-------------------------------------------------------------------------------");
14306                }
14307                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14308                pw.println();
14309                if (dumpAll) {
14310                    pw.println("-------------------------------------------------------------------------------");
14311                }
14312                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14313                        .dumpLocked();
14314                pw.println();
14315                if (dumpAll) {
14316                    pw.println("-------------------------------------------------------------------------------");
14317                }
14318                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14319                pw.println();
14320                if (dumpAll) {
14321                    pw.println("-------------------------------------------------------------------------------");
14322                }
14323                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14324                if (mAssociations.size() > 0) {
14325                    pw.println();
14326                    if (dumpAll) {
14327                        pw.println("-------------------------------------------------------------------------------");
14328                    }
14329                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14330                }
14331                pw.println();
14332                if (dumpAll) {
14333                    pw.println("-------------------------------------------------------------------------------");
14334                }
14335                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14336            }
14337        }
14338        Binder.restoreCallingIdentity(origId);
14339    }
14340
14341    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14342            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14343        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14344
14345        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14346                dumpPackage);
14347        boolean needSep = printedAnything;
14348
14349        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14350                dumpPackage, needSep, "  mFocusedActivity: ");
14351        if (printed) {
14352            printedAnything = true;
14353            needSep = false;
14354        }
14355
14356        if (dumpPackage == null) {
14357            if (needSep) {
14358                pw.println();
14359            }
14360            needSep = true;
14361            printedAnything = true;
14362            mStackSupervisor.dump(pw, "  ");
14363        }
14364
14365        if (!printedAnything) {
14366            pw.println("  (nothing)");
14367        }
14368    }
14369
14370    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14371            int opti, boolean dumpAll, String dumpPackage) {
14372        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14373
14374        boolean printedAnything = false;
14375
14376        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14377            boolean printedHeader = false;
14378
14379            final int N = mRecentTasks.size();
14380            for (int i=0; i<N; i++) {
14381                TaskRecord tr = mRecentTasks.get(i);
14382                if (dumpPackage != null) {
14383                    if (tr.realActivity == null ||
14384                            !dumpPackage.equals(tr.realActivity)) {
14385                        continue;
14386                    }
14387                }
14388                if (!printedHeader) {
14389                    pw.println("  Recent tasks:");
14390                    printedHeader = true;
14391                    printedAnything = true;
14392                }
14393                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14394                        pw.println(tr);
14395                if (dumpAll) {
14396                    mRecentTasks.get(i).dump(pw, "    ");
14397                }
14398            }
14399        }
14400
14401        if (!printedAnything) {
14402            pw.println("  (nothing)");
14403        }
14404    }
14405
14406    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14407            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14408        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14409
14410        int dumpUid = 0;
14411        if (dumpPackage != null) {
14412            IPackageManager pm = AppGlobals.getPackageManager();
14413            try {
14414                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14415            } catch (RemoteException e) {
14416            }
14417        }
14418
14419        boolean printedAnything = false;
14420
14421        final long now = SystemClock.uptimeMillis();
14422
14423        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14424            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14425                    = mAssociations.valueAt(i1);
14426            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14427                SparseArray<ArrayMap<String, Association>> sourceUids
14428                        = targetComponents.valueAt(i2);
14429                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14430                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14431                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14432                        Association ass = sourceProcesses.valueAt(i4);
14433                        if (dumpPackage != null) {
14434                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14435                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14436                                continue;
14437                            }
14438                        }
14439                        printedAnything = true;
14440                        pw.print("  ");
14441                        pw.print(ass.mTargetProcess);
14442                        pw.print("/");
14443                        UserHandle.formatUid(pw, ass.mTargetUid);
14444                        pw.print(" <- ");
14445                        pw.print(ass.mSourceProcess);
14446                        pw.print("/");
14447                        UserHandle.formatUid(pw, ass.mSourceUid);
14448                        pw.println();
14449                        pw.print("    via ");
14450                        pw.print(ass.mTargetComponent.flattenToShortString());
14451                        pw.println();
14452                        pw.print("    ");
14453                        long dur = ass.mTime;
14454                        if (ass.mNesting > 0) {
14455                            dur += now - ass.mStartTime;
14456                        }
14457                        TimeUtils.formatDuration(dur, pw);
14458                        pw.print(" (");
14459                        pw.print(ass.mCount);
14460                        pw.print(" times)");
14461                        pw.print("  ");
14462                        for (int i=0; i<ass.mStateTimes.length; i++) {
14463                            long amt = ass.mStateTimes[i];
14464                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14465                                amt += now - ass.mLastStateUptime;
14466                            }
14467                            if (amt != 0) {
14468                                pw.print(" ");
14469                                pw.print(ProcessList.makeProcStateString(
14470                                            i + ActivityManager.MIN_PROCESS_STATE));
14471                                pw.print("=");
14472                                TimeUtils.formatDuration(amt, pw);
14473                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14474                                    pw.print("*");
14475                                }
14476                            }
14477                        }
14478                        pw.println();
14479                        if (ass.mNesting > 0) {
14480                            pw.print("    Currently active: ");
14481                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14482                            pw.println();
14483                        }
14484                    }
14485                }
14486            }
14487
14488        }
14489
14490        if (!printedAnything) {
14491            pw.println("  (nothing)");
14492        }
14493    }
14494
14495    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14496            String header, boolean needSep) {
14497        boolean printed = false;
14498        int whichAppId = -1;
14499        if (dumpPackage != null) {
14500            try {
14501                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14502                        dumpPackage, 0);
14503                whichAppId = UserHandle.getAppId(info.uid);
14504            } catch (NameNotFoundException e) {
14505                e.printStackTrace();
14506            }
14507        }
14508        for (int i=0; i<uids.size(); i++) {
14509            UidRecord uidRec = uids.valueAt(i);
14510            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14511                continue;
14512            }
14513            if (!printed) {
14514                printed = true;
14515                if (needSep) {
14516                    pw.println();
14517                }
14518                pw.print("  ");
14519                pw.println(header);
14520                needSep = true;
14521            }
14522            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14523            pw.print(": "); pw.println(uidRec);
14524        }
14525        return printed;
14526    }
14527
14528    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14529            int opti, boolean dumpAll, String dumpPackage) {
14530        boolean needSep = false;
14531        boolean printedAnything = false;
14532        int numPers = 0;
14533
14534        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14535
14536        if (dumpAll) {
14537            final int NP = mProcessNames.getMap().size();
14538            for (int ip=0; ip<NP; ip++) {
14539                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14540                final int NA = procs.size();
14541                for (int ia=0; ia<NA; ia++) {
14542                    ProcessRecord r = procs.valueAt(ia);
14543                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14544                        continue;
14545                    }
14546                    if (!needSep) {
14547                        pw.println("  All known processes:");
14548                        needSep = true;
14549                        printedAnything = true;
14550                    }
14551                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14552                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14553                        pw.print(" "); pw.println(r);
14554                    r.dump(pw, "    ");
14555                    if (r.persistent) {
14556                        numPers++;
14557                    }
14558                }
14559            }
14560        }
14561
14562        if (mIsolatedProcesses.size() > 0) {
14563            boolean printed = false;
14564            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14565                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14566                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14567                    continue;
14568                }
14569                if (!printed) {
14570                    if (needSep) {
14571                        pw.println();
14572                    }
14573                    pw.println("  Isolated process list (sorted by uid):");
14574                    printedAnything = true;
14575                    printed = true;
14576                    needSep = true;
14577                }
14578                pw.println(String.format("%sIsolated #%2d: %s",
14579                        "    ", i, r.toString()));
14580            }
14581        }
14582
14583        if (mActiveUids.size() > 0) {
14584            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14585                printedAnything = needSep = true;
14586            }
14587        }
14588        if (mValidateUids.size() > 0) {
14589            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14590                printedAnything = needSep = true;
14591            }
14592        }
14593
14594        if (mLruProcesses.size() > 0) {
14595            if (needSep) {
14596                pw.println();
14597            }
14598            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14599                    pw.print(" total, non-act at ");
14600                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14601                    pw.print(", non-svc at ");
14602                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14603                    pw.println("):");
14604            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14605            needSep = true;
14606            printedAnything = true;
14607        }
14608
14609        if (dumpAll || dumpPackage != null) {
14610            synchronized (mPidsSelfLocked) {
14611                boolean printed = false;
14612                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14613                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14614                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14615                        continue;
14616                    }
14617                    if (!printed) {
14618                        if (needSep) pw.println();
14619                        needSep = true;
14620                        pw.println("  PID mappings:");
14621                        printed = true;
14622                        printedAnything = true;
14623                    }
14624                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14625                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14626                }
14627            }
14628        }
14629
14630        if (mForegroundProcesses.size() > 0) {
14631            synchronized (mPidsSelfLocked) {
14632                boolean printed = false;
14633                for (int i=0; i<mForegroundProcesses.size(); i++) {
14634                    ProcessRecord r = mPidsSelfLocked.get(
14635                            mForegroundProcesses.valueAt(i).pid);
14636                    if (dumpPackage != null && (r == null
14637                            || !r.pkgList.containsKey(dumpPackage))) {
14638                        continue;
14639                    }
14640                    if (!printed) {
14641                        if (needSep) pw.println();
14642                        needSep = true;
14643                        pw.println("  Foreground Processes:");
14644                        printed = true;
14645                        printedAnything = true;
14646                    }
14647                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14648                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14649                }
14650            }
14651        }
14652
14653        if (mPersistentStartingProcesses.size() > 0) {
14654            if (needSep) pw.println();
14655            needSep = true;
14656            printedAnything = true;
14657            pw.println("  Persisent processes that are starting:");
14658            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14659                    "Starting Norm", "Restarting PERS", dumpPackage);
14660        }
14661
14662        if (mRemovedProcesses.size() > 0) {
14663            if (needSep) pw.println();
14664            needSep = true;
14665            printedAnything = true;
14666            pw.println("  Processes that are being removed:");
14667            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14668                    "Removed Norm", "Removed PERS", dumpPackage);
14669        }
14670
14671        if (mProcessesOnHold.size() > 0) {
14672            if (needSep) pw.println();
14673            needSep = true;
14674            printedAnything = true;
14675            pw.println("  Processes that are on old until the system is ready:");
14676            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14677                    "OnHold Norm", "OnHold PERS", dumpPackage);
14678        }
14679
14680        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14681
14682        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14683        if (needSep) {
14684            printedAnything = true;
14685        }
14686
14687        if (dumpPackage == null) {
14688            pw.println();
14689            needSep = false;
14690            mUserController.dump(pw, dumpAll);
14691        }
14692        if (mHomeProcess != null && (dumpPackage == null
14693                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14694            if (needSep) {
14695                pw.println();
14696                needSep = false;
14697            }
14698            pw.println("  mHomeProcess: " + mHomeProcess);
14699        }
14700        if (mPreviousProcess != null && (dumpPackage == null
14701                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14702            if (needSep) {
14703                pw.println();
14704                needSep = false;
14705            }
14706            pw.println("  mPreviousProcess: " + mPreviousProcess);
14707        }
14708        if (dumpAll) {
14709            StringBuilder sb = new StringBuilder(128);
14710            sb.append("  mPreviousProcessVisibleTime: ");
14711            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14712            pw.println(sb);
14713        }
14714        if (mHeavyWeightProcess != null && (dumpPackage == null
14715                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14716            if (needSep) {
14717                pw.println();
14718                needSep = false;
14719            }
14720            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14721        }
14722        if (dumpPackage == null) {
14723            pw.println("  mConfiguration: " + mConfiguration);
14724        }
14725        if (dumpAll) {
14726            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14727            if (mCompatModePackages.getPackages().size() > 0) {
14728                boolean printed = false;
14729                for (Map.Entry<String, Integer> entry
14730                        : mCompatModePackages.getPackages().entrySet()) {
14731                    String pkg = entry.getKey();
14732                    int mode = entry.getValue();
14733                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14734                        continue;
14735                    }
14736                    if (!printed) {
14737                        pw.println("  mScreenCompatPackages:");
14738                        printed = true;
14739                    }
14740                    pw.print("    "); pw.print(pkg); pw.print(": ");
14741                            pw.print(mode); pw.println();
14742                }
14743            }
14744        }
14745        if (dumpPackage == null) {
14746            pw.println("  mWakefulness="
14747                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14748            pw.println("  mSleepTokens=" + mSleepTokens);
14749            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14750                    + lockScreenShownToString());
14751            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14752            if (mRunningVoice != null) {
14753                pw.println("  mRunningVoice=" + mRunningVoice);
14754                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14755            }
14756        }
14757        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14758                || mOrigWaitForDebugger) {
14759            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14760                    || dumpPackage.equals(mOrigDebugApp)) {
14761                if (needSep) {
14762                    pw.println();
14763                    needSep = false;
14764                }
14765                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14766                        + " mDebugTransient=" + mDebugTransient
14767                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14768            }
14769        }
14770        if (mCurAppTimeTracker != null) {
14771            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14772        }
14773        if (mMemWatchProcesses.getMap().size() > 0) {
14774            pw.println("  Mem watch processes:");
14775            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14776                    = mMemWatchProcesses.getMap();
14777            for (int i=0; i<procs.size(); i++) {
14778                final String proc = procs.keyAt(i);
14779                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14780                for (int j=0; j<uids.size(); j++) {
14781                    if (needSep) {
14782                        pw.println();
14783                        needSep = false;
14784                    }
14785                    StringBuilder sb = new StringBuilder();
14786                    sb.append("    ").append(proc).append('/');
14787                    UserHandle.formatUid(sb, uids.keyAt(j));
14788                    Pair<Long, String> val = uids.valueAt(j);
14789                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14790                    if (val.second != null) {
14791                        sb.append(", report to ").append(val.second);
14792                    }
14793                    pw.println(sb.toString());
14794                }
14795            }
14796            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14797            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14798            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14799                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14800        }
14801        if (mTrackAllocationApp != null) {
14802            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14803                if (needSep) {
14804                    pw.println();
14805                    needSep = false;
14806                }
14807                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14808            }
14809        }
14810        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14811                || mProfileFd != null) {
14812            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14813                if (needSep) {
14814                    pw.println();
14815                    needSep = false;
14816                }
14817                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14818                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14819                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14820                        + mAutoStopProfiler);
14821                pw.println("  mProfileType=" + mProfileType);
14822            }
14823        }
14824        if (mNativeDebuggingApp != null) {
14825            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14826                if (needSep) {
14827                    pw.println();
14828                    needSep = false;
14829                }
14830                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14831            }
14832        }
14833        if (dumpPackage == null) {
14834            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14835                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14836                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14837            }
14838            if (mController != null) {
14839                pw.println("  mController=" + mController
14840                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14841            }
14842            if (dumpAll) {
14843                pw.println("  Total persistent processes: " + numPers);
14844                pw.println("  mProcessesReady=" + mProcessesReady
14845                        + " mSystemReady=" + mSystemReady
14846                        + " mBooted=" + mBooted
14847                        + " mFactoryTest=" + mFactoryTest);
14848                pw.println("  mBooting=" + mBooting
14849                        + " mCallFinishBooting=" + mCallFinishBooting
14850                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14851                pw.print("  mLastPowerCheckRealtime=");
14852                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14853                        pw.println("");
14854                pw.print("  mLastPowerCheckUptime=");
14855                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14856                        pw.println("");
14857                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14858                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14859                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14860                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14861                        + " (" + mLruProcesses.size() + " total)"
14862                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14863                        + " mNumServiceProcs=" + mNumServiceProcs
14864                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14865                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14866                        + " mLastMemoryLevel=" + mLastMemoryLevel
14867                        + " mLastNumProcesses=" + mLastNumProcesses);
14868                long now = SystemClock.uptimeMillis();
14869                pw.print("  mLastIdleTime=");
14870                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14871                        pw.print(" mLowRamSinceLastIdle=");
14872                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14873                        pw.println();
14874            }
14875        }
14876
14877        if (!printedAnything) {
14878            pw.println("  (nothing)");
14879        }
14880    }
14881
14882    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14883            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14884        if (mProcessesToGc.size() > 0) {
14885            boolean printed = false;
14886            long now = SystemClock.uptimeMillis();
14887            for (int i=0; i<mProcessesToGc.size(); i++) {
14888                ProcessRecord proc = mProcessesToGc.get(i);
14889                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14890                    continue;
14891                }
14892                if (!printed) {
14893                    if (needSep) pw.println();
14894                    needSep = true;
14895                    pw.println("  Processes that are waiting to GC:");
14896                    printed = true;
14897                }
14898                pw.print("    Process "); pw.println(proc);
14899                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14900                        pw.print(", last gced=");
14901                        pw.print(now-proc.lastRequestedGc);
14902                        pw.print(" ms ago, last lowMem=");
14903                        pw.print(now-proc.lastLowMemory);
14904                        pw.println(" ms ago");
14905
14906            }
14907        }
14908        return needSep;
14909    }
14910
14911    void printOomLevel(PrintWriter pw, String name, int adj) {
14912        pw.print("    ");
14913        if (adj >= 0) {
14914            pw.print(' ');
14915            if (adj < 10) pw.print(' ');
14916        } else {
14917            if (adj > -10) pw.print(' ');
14918        }
14919        pw.print(adj);
14920        pw.print(": ");
14921        pw.print(name);
14922        pw.print(" (");
14923        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14924        pw.println(")");
14925    }
14926
14927    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14928            int opti, boolean dumpAll) {
14929        boolean needSep = false;
14930
14931        if (mLruProcesses.size() > 0) {
14932            if (needSep) pw.println();
14933            needSep = true;
14934            pw.println("  OOM levels:");
14935            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14936            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14937            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14938            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14939            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14940            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14941            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14942            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14943            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14944            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14945            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14946            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14947            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14948            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14949
14950            if (needSep) pw.println();
14951            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14952                    pw.print(" total, non-act at ");
14953                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14954                    pw.print(", non-svc at ");
14955                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14956                    pw.println("):");
14957            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14958            needSep = true;
14959        }
14960
14961        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14962
14963        pw.println();
14964        pw.println("  mHomeProcess: " + mHomeProcess);
14965        pw.println("  mPreviousProcess: " + mPreviousProcess);
14966        if (mHeavyWeightProcess != null) {
14967            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14968        }
14969
14970        return true;
14971    }
14972
14973    /**
14974     * There are three ways to call this:
14975     *  - no provider specified: dump all the providers
14976     *  - a flattened component name that matched an existing provider was specified as the
14977     *    first arg: dump that one provider
14978     *  - the first arg isn't the flattened component name of an existing provider:
14979     *    dump all providers whose component contains the first arg as a substring
14980     */
14981    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14982            int opti, boolean dumpAll) {
14983        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14984    }
14985
14986    static class ItemMatcher {
14987        ArrayList<ComponentName> components;
14988        ArrayList<String> strings;
14989        ArrayList<Integer> objects;
14990        boolean all;
14991
14992        ItemMatcher() {
14993            all = true;
14994        }
14995
14996        void build(String name) {
14997            ComponentName componentName = ComponentName.unflattenFromString(name);
14998            if (componentName != null) {
14999                if (components == null) {
15000                    components = new ArrayList<ComponentName>();
15001                }
15002                components.add(componentName);
15003                all = false;
15004            } else {
15005                int objectId = 0;
15006                // Not a '/' separated full component name; maybe an object ID?
15007                try {
15008                    objectId = Integer.parseInt(name, 16);
15009                    if (objects == null) {
15010                        objects = new ArrayList<Integer>();
15011                    }
15012                    objects.add(objectId);
15013                    all = false;
15014                } catch (RuntimeException e) {
15015                    // Not an integer; just do string match.
15016                    if (strings == null) {
15017                        strings = new ArrayList<String>();
15018                    }
15019                    strings.add(name);
15020                    all = false;
15021                }
15022            }
15023        }
15024
15025        int build(String[] args, int opti) {
15026            for (; opti<args.length; opti++) {
15027                String name = args[opti];
15028                if ("--".equals(name)) {
15029                    return opti+1;
15030                }
15031                build(name);
15032            }
15033            return opti;
15034        }
15035
15036        boolean match(Object object, ComponentName comp) {
15037            if (all) {
15038                return true;
15039            }
15040            if (components != null) {
15041                for (int i=0; i<components.size(); i++) {
15042                    if (components.get(i).equals(comp)) {
15043                        return true;
15044                    }
15045                }
15046            }
15047            if (objects != null) {
15048                for (int i=0; i<objects.size(); i++) {
15049                    if (System.identityHashCode(object) == objects.get(i)) {
15050                        return true;
15051                    }
15052                }
15053            }
15054            if (strings != null) {
15055                String flat = comp.flattenToString();
15056                for (int i=0; i<strings.size(); i++) {
15057                    if (flat.contains(strings.get(i))) {
15058                        return true;
15059                    }
15060                }
15061            }
15062            return false;
15063        }
15064    }
15065
15066    /**
15067     * There are three things that cmd can be:
15068     *  - a flattened component name that matches an existing activity
15069     *  - the cmd arg isn't the flattened component name of an existing activity:
15070     *    dump all activity whose component contains the cmd as a substring
15071     *  - A hex number of the ActivityRecord object instance.
15072     */
15073    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15074            int opti, boolean dumpAll) {
15075        ArrayList<ActivityRecord> activities;
15076
15077        synchronized (this) {
15078            activities = mStackSupervisor.getDumpActivitiesLocked(name);
15079        }
15080
15081        if (activities.size() <= 0) {
15082            return false;
15083        }
15084
15085        String[] newArgs = new String[args.length - opti];
15086        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15087
15088        TaskRecord lastTask = null;
15089        boolean needSep = false;
15090        for (int i=activities.size()-1; i>=0; i--) {
15091            ActivityRecord r = activities.get(i);
15092            if (needSep) {
15093                pw.println();
15094            }
15095            needSep = true;
15096            synchronized (this) {
15097                if (lastTask != r.task) {
15098                    lastTask = r.task;
15099                    pw.print("TASK "); pw.print(lastTask.affinity);
15100                            pw.print(" id="); pw.println(lastTask.taskId);
15101                    if (dumpAll) {
15102                        lastTask.dump(pw, "  ");
15103                    }
15104                }
15105            }
15106            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15107        }
15108        return true;
15109    }
15110
15111    /**
15112     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15113     * there is a thread associated with the activity.
15114     */
15115    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15116            final ActivityRecord r, String[] args, boolean dumpAll) {
15117        String innerPrefix = prefix + "  ";
15118        synchronized (this) {
15119            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15120                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15121                    pw.print(" pid=");
15122                    if (r.app != null) pw.println(r.app.pid);
15123                    else pw.println("(not running)");
15124            if (dumpAll) {
15125                r.dump(pw, innerPrefix);
15126            }
15127        }
15128        if (r.app != null && r.app.thread != null) {
15129            // flush anything that is already in the PrintWriter since the thread is going
15130            // to write to the file descriptor directly
15131            pw.flush();
15132            try {
15133                TransferPipe tp = new TransferPipe();
15134                try {
15135                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15136                            r.appToken, innerPrefix, args);
15137                    tp.go(fd);
15138                } finally {
15139                    tp.kill();
15140                }
15141            } catch (IOException e) {
15142                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15143            } catch (RemoteException e) {
15144                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15145            }
15146        }
15147    }
15148
15149    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15150            int opti, boolean dumpAll, String dumpPackage) {
15151        boolean needSep = false;
15152        boolean onlyHistory = false;
15153        boolean printedAnything = false;
15154
15155        if ("history".equals(dumpPackage)) {
15156            if (opti < args.length && "-s".equals(args[opti])) {
15157                dumpAll = false;
15158            }
15159            onlyHistory = true;
15160            dumpPackage = null;
15161        }
15162
15163        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15164        if (!onlyHistory && dumpAll) {
15165            if (mRegisteredReceivers.size() > 0) {
15166                boolean printed = false;
15167                Iterator it = mRegisteredReceivers.values().iterator();
15168                while (it.hasNext()) {
15169                    ReceiverList r = (ReceiverList)it.next();
15170                    if (dumpPackage != null && (r.app == null ||
15171                            !dumpPackage.equals(r.app.info.packageName))) {
15172                        continue;
15173                    }
15174                    if (!printed) {
15175                        pw.println("  Registered Receivers:");
15176                        needSep = true;
15177                        printed = true;
15178                        printedAnything = true;
15179                    }
15180                    pw.print("  * "); pw.println(r);
15181                    r.dump(pw, "    ");
15182                }
15183            }
15184
15185            if (mReceiverResolver.dump(pw, needSep ?
15186                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15187                    "    ", dumpPackage, false, false)) {
15188                needSep = true;
15189                printedAnything = true;
15190            }
15191        }
15192
15193        for (BroadcastQueue q : mBroadcastQueues) {
15194            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15195            printedAnything |= needSep;
15196        }
15197
15198        needSep = true;
15199
15200        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15201            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15202                if (needSep) {
15203                    pw.println();
15204                }
15205                needSep = true;
15206                printedAnything = true;
15207                pw.print("  Sticky broadcasts for user ");
15208                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15209                StringBuilder sb = new StringBuilder(128);
15210                for (Map.Entry<String, ArrayList<Intent>> ent
15211                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15212                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15213                    if (dumpAll) {
15214                        pw.println(":");
15215                        ArrayList<Intent> intents = ent.getValue();
15216                        final int N = intents.size();
15217                        for (int i=0; i<N; i++) {
15218                            sb.setLength(0);
15219                            sb.append("    Intent: ");
15220                            intents.get(i).toShortString(sb, false, true, false, false);
15221                            pw.println(sb.toString());
15222                            Bundle bundle = intents.get(i).getExtras();
15223                            if (bundle != null) {
15224                                pw.print("      ");
15225                                pw.println(bundle.toString());
15226                            }
15227                        }
15228                    } else {
15229                        pw.println("");
15230                    }
15231                }
15232            }
15233        }
15234
15235        if (!onlyHistory && dumpAll) {
15236            pw.println();
15237            for (BroadcastQueue queue : mBroadcastQueues) {
15238                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15239                        + queue.mBroadcastsScheduled);
15240            }
15241            pw.println("  mHandler:");
15242            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15243            needSep = true;
15244            printedAnything = true;
15245        }
15246
15247        if (!printedAnything) {
15248            pw.println("  (nothing)");
15249        }
15250    }
15251
15252    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15253            int opti, boolean dumpAll, String dumpPackage) {
15254        if (mCurBroadcastStats == null) {
15255            return;
15256        }
15257
15258        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15259        final long now = SystemClock.elapsedRealtime();
15260        if (mLastBroadcastStats != null) {
15261            pw.print("  Last stats (from ");
15262            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15263            pw.print(" to ");
15264            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15265            pw.print(", ");
15266            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15267                    - mLastBroadcastStats.mStartUptime, pw);
15268            pw.println(" uptime):");
15269            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15270                pw.println("    (nothing)");
15271            }
15272            pw.println();
15273        }
15274        pw.print("  Current stats (from ");
15275        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15276        pw.print(" to now, ");
15277        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15278                - mCurBroadcastStats.mStartUptime, pw);
15279        pw.println(" uptime):");
15280        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15281            pw.println("    (nothing)");
15282        }
15283    }
15284
15285    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15286            int opti, boolean fullCheckin, String dumpPackage) {
15287        if (mCurBroadcastStats == null) {
15288            return;
15289        }
15290
15291        if (mLastBroadcastStats != null) {
15292            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15293            if (fullCheckin) {
15294                mLastBroadcastStats = null;
15295                return;
15296            }
15297        }
15298        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15299        if (fullCheckin) {
15300            mCurBroadcastStats = null;
15301        }
15302    }
15303
15304    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15305            int opti, boolean dumpAll, String dumpPackage) {
15306        boolean needSep;
15307        boolean printedAnything = false;
15308
15309        ItemMatcher matcher = new ItemMatcher();
15310        matcher.build(args, opti);
15311
15312        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15313
15314        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15315        printedAnything |= needSep;
15316
15317        if (mLaunchingProviders.size() > 0) {
15318            boolean printed = false;
15319            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15320                ContentProviderRecord r = mLaunchingProviders.get(i);
15321                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15322                    continue;
15323                }
15324                if (!printed) {
15325                    if (needSep) pw.println();
15326                    needSep = true;
15327                    pw.println("  Launching content providers:");
15328                    printed = true;
15329                    printedAnything = true;
15330                }
15331                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15332                        pw.println(r);
15333            }
15334        }
15335
15336        if (!printedAnything) {
15337            pw.println("  (nothing)");
15338        }
15339    }
15340
15341    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15342            int opti, boolean dumpAll, String dumpPackage) {
15343        boolean needSep = false;
15344        boolean printedAnything = false;
15345
15346        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15347
15348        if (mGrantedUriPermissions.size() > 0) {
15349            boolean printed = false;
15350            int dumpUid = -2;
15351            if (dumpPackage != null) {
15352                try {
15353                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15354                            MATCH_UNINSTALLED_PACKAGES, 0);
15355                } catch (NameNotFoundException e) {
15356                    dumpUid = -1;
15357                }
15358            }
15359            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15360                int uid = mGrantedUriPermissions.keyAt(i);
15361                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15362                    continue;
15363                }
15364                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15365                if (!printed) {
15366                    if (needSep) pw.println();
15367                    needSep = true;
15368                    pw.println("  Granted Uri Permissions:");
15369                    printed = true;
15370                    printedAnything = true;
15371                }
15372                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15373                for (UriPermission perm : perms.values()) {
15374                    pw.print("    "); pw.println(perm);
15375                    if (dumpAll) {
15376                        perm.dump(pw, "      ");
15377                    }
15378                }
15379            }
15380        }
15381
15382        if (!printedAnything) {
15383            pw.println("  (nothing)");
15384        }
15385    }
15386
15387    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15388            int opti, boolean dumpAll, String dumpPackage) {
15389        boolean printed = false;
15390
15391        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15392
15393        if (mIntentSenderRecords.size() > 0) {
15394            Iterator<WeakReference<PendingIntentRecord>> it
15395                    = mIntentSenderRecords.values().iterator();
15396            while (it.hasNext()) {
15397                WeakReference<PendingIntentRecord> ref = it.next();
15398                PendingIntentRecord rec = ref != null ? ref.get(): null;
15399                if (dumpPackage != null && (rec == null
15400                        || !dumpPackage.equals(rec.key.packageName))) {
15401                    continue;
15402                }
15403                printed = true;
15404                if (rec != null) {
15405                    pw.print("  * "); pw.println(rec);
15406                    if (dumpAll) {
15407                        rec.dump(pw, "    ");
15408                    }
15409                } else {
15410                    pw.print("  * "); pw.println(ref);
15411                }
15412            }
15413        }
15414
15415        if (!printed) {
15416            pw.println("  (nothing)");
15417        }
15418    }
15419
15420    private static final int dumpProcessList(PrintWriter pw,
15421            ActivityManagerService service, List list,
15422            String prefix, String normalLabel, String persistentLabel,
15423            String dumpPackage) {
15424        int numPers = 0;
15425        final int N = list.size()-1;
15426        for (int i=N; i>=0; i--) {
15427            ProcessRecord r = (ProcessRecord)list.get(i);
15428            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15429                continue;
15430            }
15431            pw.println(String.format("%s%s #%2d: %s",
15432                    prefix, (r.persistent ? persistentLabel : normalLabel),
15433                    i, r.toString()));
15434            if (r.persistent) {
15435                numPers++;
15436            }
15437        }
15438        return numPers;
15439    }
15440
15441    private static final boolean dumpProcessOomList(PrintWriter pw,
15442            ActivityManagerService service, List<ProcessRecord> origList,
15443            String prefix, String normalLabel, String persistentLabel,
15444            boolean inclDetails, String dumpPackage) {
15445
15446        ArrayList<Pair<ProcessRecord, Integer>> list
15447                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15448        for (int i=0; i<origList.size(); i++) {
15449            ProcessRecord r = origList.get(i);
15450            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15451                continue;
15452            }
15453            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15454        }
15455
15456        if (list.size() <= 0) {
15457            return false;
15458        }
15459
15460        Comparator<Pair<ProcessRecord, Integer>> comparator
15461                = new Comparator<Pair<ProcessRecord, Integer>>() {
15462            @Override
15463            public int compare(Pair<ProcessRecord, Integer> object1,
15464                    Pair<ProcessRecord, Integer> object2) {
15465                if (object1.first.setAdj != object2.first.setAdj) {
15466                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15467                }
15468                if (object1.first.setProcState != object2.first.setProcState) {
15469                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15470                }
15471                if (object1.second.intValue() != object2.second.intValue()) {
15472                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15473                }
15474                return 0;
15475            }
15476        };
15477
15478        Collections.sort(list, comparator);
15479
15480        final long curRealtime = SystemClock.elapsedRealtime();
15481        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15482        final long curUptime = SystemClock.uptimeMillis();
15483        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15484
15485        for (int i=list.size()-1; i>=0; i--) {
15486            ProcessRecord r = list.get(i).first;
15487            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15488            char schedGroup;
15489            switch (r.setSchedGroup) {
15490                case ProcessList.SCHED_GROUP_BACKGROUND:
15491                    schedGroup = 'B';
15492                    break;
15493                case ProcessList.SCHED_GROUP_DEFAULT:
15494                    schedGroup = 'F';
15495                    break;
15496                case ProcessList.SCHED_GROUP_TOP_APP:
15497                    schedGroup = 'T';
15498                    break;
15499                default:
15500                    schedGroup = '?';
15501                    break;
15502            }
15503            char foreground;
15504            if (r.foregroundActivities) {
15505                foreground = 'A';
15506            } else if (r.foregroundServices) {
15507                foreground = 'S';
15508            } else {
15509                foreground = ' ';
15510            }
15511            String procState = ProcessList.makeProcStateString(r.curProcState);
15512            pw.print(prefix);
15513            pw.print(r.persistent ? persistentLabel : normalLabel);
15514            pw.print(" #");
15515            int num = (origList.size()-1)-list.get(i).second;
15516            if (num < 10) pw.print(' ');
15517            pw.print(num);
15518            pw.print(": ");
15519            pw.print(oomAdj);
15520            pw.print(' ');
15521            pw.print(schedGroup);
15522            pw.print('/');
15523            pw.print(foreground);
15524            pw.print('/');
15525            pw.print(procState);
15526            pw.print(" trm:");
15527            if (r.trimMemoryLevel < 10) pw.print(' ');
15528            pw.print(r.trimMemoryLevel);
15529            pw.print(' ');
15530            pw.print(r.toShortString());
15531            pw.print(" (");
15532            pw.print(r.adjType);
15533            pw.println(')');
15534            if (r.adjSource != null || r.adjTarget != null) {
15535                pw.print(prefix);
15536                pw.print("    ");
15537                if (r.adjTarget instanceof ComponentName) {
15538                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15539                } else if (r.adjTarget != null) {
15540                    pw.print(r.adjTarget.toString());
15541                } else {
15542                    pw.print("{null}");
15543                }
15544                pw.print("<=");
15545                if (r.adjSource instanceof ProcessRecord) {
15546                    pw.print("Proc{");
15547                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15548                    pw.println("}");
15549                } else if (r.adjSource != null) {
15550                    pw.println(r.adjSource.toString());
15551                } else {
15552                    pw.println("{null}");
15553                }
15554            }
15555            if (inclDetails) {
15556                pw.print(prefix);
15557                pw.print("    ");
15558                pw.print("oom: max="); pw.print(r.maxAdj);
15559                pw.print(" curRaw="); pw.print(r.curRawAdj);
15560                pw.print(" setRaw="); pw.print(r.setRawAdj);
15561                pw.print(" cur="); pw.print(r.curAdj);
15562                pw.print(" set="); pw.println(r.setAdj);
15563                pw.print(prefix);
15564                pw.print("    ");
15565                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15566                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15567                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15568                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15569                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15570                pw.println();
15571                pw.print(prefix);
15572                pw.print("    ");
15573                pw.print("cached="); pw.print(r.cached);
15574                pw.print(" empty="); pw.print(r.empty);
15575                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15576
15577                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15578                    if (r.lastWakeTime != 0) {
15579                        long wtime;
15580                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15581                        synchronized (stats) {
15582                            wtime = stats.getProcessWakeTime(r.info.uid,
15583                                    r.pid, curRealtime);
15584                        }
15585                        long timeUsed = wtime - r.lastWakeTime;
15586                        pw.print(prefix);
15587                        pw.print("    ");
15588                        pw.print("keep awake over ");
15589                        TimeUtils.formatDuration(realtimeSince, pw);
15590                        pw.print(" used ");
15591                        TimeUtils.formatDuration(timeUsed, pw);
15592                        pw.print(" (");
15593                        pw.print((timeUsed*100)/realtimeSince);
15594                        pw.println("%)");
15595                    }
15596                    if (r.lastCpuTime != 0) {
15597                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15598                        pw.print(prefix);
15599                        pw.print("    ");
15600                        pw.print("run cpu over ");
15601                        TimeUtils.formatDuration(uptimeSince, pw);
15602                        pw.print(" used ");
15603                        TimeUtils.formatDuration(timeUsed, pw);
15604                        pw.print(" (");
15605                        pw.print((timeUsed*100)/uptimeSince);
15606                        pw.println("%)");
15607                    }
15608                }
15609            }
15610        }
15611        return true;
15612    }
15613
15614    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15615            String[] args) {
15616        ArrayList<ProcessRecord> procs;
15617        synchronized (this) {
15618            if (args != null && args.length > start
15619                    && args[start].charAt(0) != '-') {
15620                procs = new ArrayList<ProcessRecord>();
15621                int pid = -1;
15622                try {
15623                    pid = Integer.parseInt(args[start]);
15624                } catch (NumberFormatException e) {
15625                }
15626                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15627                    ProcessRecord proc = mLruProcesses.get(i);
15628                    if (proc.pid == pid) {
15629                        procs.add(proc);
15630                    } else if (allPkgs && proc.pkgList != null
15631                            && proc.pkgList.containsKey(args[start])) {
15632                        procs.add(proc);
15633                    } else if (proc.processName.equals(args[start])) {
15634                        procs.add(proc);
15635                    }
15636                }
15637                if (procs.size() <= 0) {
15638                    return null;
15639                }
15640            } else {
15641                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15642            }
15643        }
15644        return procs;
15645    }
15646
15647    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15648            PrintWriter pw, String[] args) {
15649        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15650        if (procs == null) {
15651            pw.println("No process found for: " + args[0]);
15652            return;
15653        }
15654
15655        long uptime = SystemClock.uptimeMillis();
15656        long realtime = SystemClock.elapsedRealtime();
15657        pw.println("Applications Graphics Acceleration Info:");
15658        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15659
15660        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15661            ProcessRecord r = procs.get(i);
15662            if (r.thread != null) {
15663                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15664                pw.flush();
15665                try {
15666                    TransferPipe tp = new TransferPipe();
15667                    try {
15668                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15669                        tp.go(fd);
15670                    } finally {
15671                        tp.kill();
15672                    }
15673                } catch (IOException e) {
15674                    pw.println("Failure while dumping the app: " + r);
15675                    pw.flush();
15676                } catch (RemoteException e) {
15677                    pw.println("Got a RemoteException while dumping the app " + r);
15678                    pw.flush();
15679                }
15680            }
15681        }
15682    }
15683
15684    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15685        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15686        if (procs == null) {
15687            pw.println("No process found for: " + args[0]);
15688            return;
15689        }
15690
15691        pw.println("Applications Database Info:");
15692
15693        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15694            ProcessRecord r = procs.get(i);
15695            if (r.thread != null) {
15696                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15697                pw.flush();
15698                try {
15699                    TransferPipe tp = new TransferPipe();
15700                    try {
15701                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15702                        tp.go(fd);
15703                    } finally {
15704                        tp.kill();
15705                    }
15706                } catch (IOException e) {
15707                    pw.println("Failure while dumping the app: " + r);
15708                    pw.flush();
15709                } catch (RemoteException e) {
15710                    pw.println("Got a RemoteException while dumping the app " + r);
15711                    pw.flush();
15712                }
15713            }
15714        }
15715    }
15716
15717    final static class MemItem {
15718        final boolean isProc;
15719        final String label;
15720        final String shortLabel;
15721        final long pss;
15722        final long swapPss;
15723        final int id;
15724        final boolean hasActivities;
15725        ArrayList<MemItem> subitems;
15726
15727        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15728                boolean _hasActivities) {
15729            isProc = true;
15730            label = _label;
15731            shortLabel = _shortLabel;
15732            pss = _pss;
15733            swapPss = _swapPss;
15734            id = _id;
15735            hasActivities = _hasActivities;
15736        }
15737
15738        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15739            isProc = false;
15740            label = _label;
15741            shortLabel = _shortLabel;
15742            pss = _pss;
15743            swapPss = _swapPss;
15744            id = _id;
15745            hasActivities = false;
15746        }
15747    }
15748
15749    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15750            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15751        if (sort && !isCompact) {
15752            Collections.sort(items, new Comparator<MemItem>() {
15753                @Override
15754                public int compare(MemItem lhs, MemItem rhs) {
15755                    if (lhs.pss < rhs.pss) {
15756                        return 1;
15757                    } else if (lhs.pss > rhs.pss) {
15758                        return -1;
15759                    }
15760                    return 0;
15761                }
15762            });
15763        }
15764
15765        for (int i=0; i<items.size(); i++) {
15766            MemItem mi = items.get(i);
15767            if (!isCompact) {
15768                if (dumpSwapPss) {
15769                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15770                            mi.label, stringifyKBSize(mi.swapPss));
15771                } else {
15772                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15773                }
15774            } else if (mi.isProc) {
15775                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15776                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15777                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15778                pw.println(mi.hasActivities ? ",a" : ",e");
15779            } else {
15780                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15781                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15782            }
15783            if (mi.subitems != null) {
15784                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15785                        true, isCompact, dumpSwapPss);
15786            }
15787        }
15788    }
15789
15790    // These are in KB.
15791    static final long[] DUMP_MEM_BUCKETS = new long[] {
15792        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15793        120*1024, 160*1024, 200*1024,
15794        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15795        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15796    };
15797
15798    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15799            boolean stackLike) {
15800        int start = label.lastIndexOf('.');
15801        if (start >= 0) start++;
15802        else start = 0;
15803        int end = label.length();
15804        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15805            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15806                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15807                out.append(bucket);
15808                out.append(stackLike ? "MB." : "MB ");
15809                out.append(label, start, end);
15810                return;
15811            }
15812        }
15813        out.append(memKB/1024);
15814        out.append(stackLike ? "MB." : "MB ");
15815        out.append(label, start, end);
15816    }
15817
15818    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15819            ProcessList.NATIVE_ADJ,
15820            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15821            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15822            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15823            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15824            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15825            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15826    };
15827    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15828            "Native",
15829            "System", "Persistent", "Persistent Service", "Foreground",
15830            "Visible", "Perceptible",
15831            "Heavy Weight", "Backup",
15832            "A Services", "Home",
15833            "Previous", "B Services", "Cached"
15834    };
15835    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15836            "native",
15837            "sys", "pers", "persvc", "fore",
15838            "vis", "percept",
15839            "heavy", "backup",
15840            "servicea", "home",
15841            "prev", "serviceb", "cached"
15842    };
15843
15844    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15845            long realtime, boolean isCheckinRequest, boolean isCompact) {
15846        if (isCompact) {
15847            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15848        }
15849        if (isCheckinRequest || isCompact) {
15850            // short checkin version
15851            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15852        } else {
15853            pw.println("Applications Memory Usage (in Kilobytes):");
15854            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15855        }
15856    }
15857
15858    private static final int KSM_SHARED = 0;
15859    private static final int KSM_SHARING = 1;
15860    private static final int KSM_UNSHARED = 2;
15861    private static final int KSM_VOLATILE = 3;
15862
15863    private final long[] getKsmInfo() {
15864        long[] longOut = new long[4];
15865        final int[] SINGLE_LONG_FORMAT = new int[] {
15866            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15867        };
15868        long[] longTmp = new long[1];
15869        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15870                SINGLE_LONG_FORMAT, null, longTmp, null);
15871        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15872        longTmp[0] = 0;
15873        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15874                SINGLE_LONG_FORMAT, null, longTmp, null);
15875        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15876        longTmp[0] = 0;
15877        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15878                SINGLE_LONG_FORMAT, null, longTmp, null);
15879        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15880        longTmp[0] = 0;
15881        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15882                SINGLE_LONG_FORMAT, null, longTmp, null);
15883        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15884        return longOut;
15885    }
15886
15887    private static String stringifySize(long size, int order) {
15888        Locale locale = Locale.US;
15889        switch (order) {
15890            case 1:
15891                return String.format(locale, "%,13d", size);
15892            case 1024:
15893                return String.format(locale, "%,9dK", size / 1024);
15894            case 1024 * 1024:
15895                return String.format(locale, "%,5dM", size / 1024 / 1024);
15896            case 1024 * 1024 * 1024:
15897                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15898            default:
15899                throw new IllegalArgumentException("Invalid size order");
15900        }
15901    }
15902
15903    private static String stringifyKBSize(long size) {
15904        return stringifySize(size * 1024, 1024);
15905    }
15906
15907    // Update this version number in case you change the 'compact' format
15908    private static final int MEMINFO_COMPACT_VERSION = 1;
15909
15910    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15911            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15912        boolean dumpDetails = false;
15913        boolean dumpFullDetails = false;
15914        boolean dumpDalvik = false;
15915        boolean dumpSummaryOnly = false;
15916        boolean dumpUnreachable = false;
15917        boolean oomOnly = false;
15918        boolean isCompact = false;
15919        boolean localOnly = false;
15920        boolean packages = false;
15921        boolean isCheckinRequest = false;
15922        boolean dumpSwapPss = false;
15923
15924        int opti = 0;
15925        while (opti < args.length) {
15926            String opt = args[opti];
15927            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15928                break;
15929            }
15930            opti++;
15931            if ("-a".equals(opt)) {
15932                dumpDetails = true;
15933                dumpFullDetails = true;
15934                dumpDalvik = true;
15935                dumpSwapPss = true;
15936            } else if ("-d".equals(opt)) {
15937                dumpDalvik = true;
15938            } else if ("-c".equals(opt)) {
15939                isCompact = true;
15940            } else if ("-s".equals(opt)) {
15941                dumpDetails = true;
15942                dumpSummaryOnly = true;
15943            } else if ("-S".equals(opt)) {
15944                dumpSwapPss = true;
15945            } else if ("--unreachable".equals(opt)) {
15946                dumpUnreachable = true;
15947            } else if ("--oom".equals(opt)) {
15948                oomOnly = true;
15949            } else if ("--local".equals(opt)) {
15950                localOnly = true;
15951            } else if ("--package".equals(opt)) {
15952                packages = true;
15953            } else if ("--checkin".equals(opt)) {
15954                isCheckinRequest = true;
15955
15956            } else if ("-h".equals(opt)) {
15957                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15958                pw.println("  -a: include all available information for each process.");
15959                pw.println("  -d: include dalvik details.");
15960                pw.println("  -c: dump in a compact machine-parseable representation.");
15961                pw.println("  -s: dump only summary of application memory usage.");
15962                pw.println("  -S: dump also SwapPss.");
15963                pw.println("  --oom: only show processes organized by oom adj.");
15964                pw.println("  --local: only collect details locally, don't call process.");
15965                pw.println("  --package: interpret process arg as package, dumping all");
15966                pw.println("             processes that have loaded that package.");
15967                pw.println("  --checkin: dump data for a checkin");
15968                pw.println("If [process] is specified it can be the name or ");
15969                pw.println("pid of a specific process to dump.");
15970                return;
15971            } else {
15972                pw.println("Unknown argument: " + opt + "; use -h for help");
15973            }
15974        }
15975
15976        long uptime = SystemClock.uptimeMillis();
15977        long realtime = SystemClock.elapsedRealtime();
15978        final long[] tmpLong = new long[1];
15979
15980        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15981        if (procs == null) {
15982            // No Java processes.  Maybe they want to print a native process.
15983            if (args != null && args.length > opti
15984                    && args[opti].charAt(0) != '-') {
15985                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15986                        = new ArrayList<ProcessCpuTracker.Stats>();
15987                updateCpuStatsNow();
15988                int findPid = -1;
15989                try {
15990                    findPid = Integer.parseInt(args[opti]);
15991                } catch (NumberFormatException e) {
15992                }
15993                synchronized (mProcessCpuTracker) {
15994                    final int N = mProcessCpuTracker.countStats();
15995                    for (int i=0; i<N; i++) {
15996                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15997                        if (st.pid == findPid || (st.baseName != null
15998                                && st.baseName.equals(args[opti]))) {
15999                            nativeProcs.add(st);
16000                        }
16001                    }
16002                }
16003                if (nativeProcs.size() > 0) {
16004                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16005                            isCompact);
16006                    Debug.MemoryInfo mi = null;
16007                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16008                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16009                        final int pid = r.pid;
16010                        if (!isCheckinRequest && dumpDetails) {
16011                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16012                        }
16013                        if (mi == null) {
16014                            mi = new Debug.MemoryInfo();
16015                        }
16016                        if (dumpDetails || (!brief && !oomOnly)) {
16017                            Debug.getMemoryInfo(pid, mi);
16018                        } else {
16019                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16020                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16021                        }
16022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16023                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16024                        if (isCheckinRequest) {
16025                            pw.println();
16026                        }
16027                    }
16028                    return;
16029                }
16030            }
16031            pw.println("No process found for: " + args[opti]);
16032            return;
16033        }
16034
16035        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16036            dumpDetails = true;
16037        }
16038
16039        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16040
16041        String[] innerArgs = new String[args.length-opti];
16042        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16043
16044        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16045        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16046        long nativePss = 0;
16047        long nativeSwapPss = 0;
16048        long dalvikPss = 0;
16049        long dalvikSwapPss = 0;
16050        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16051                EmptyArray.LONG;
16052        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16053                EmptyArray.LONG;
16054        long otherPss = 0;
16055        long otherSwapPss = 0;
16056        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16057        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16058
16059        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16060        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16061        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16062                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16063
16064        long totalPss = 0;
16065        long totalSwapPss = 0;
16066        long cachedPss = 0;
16067        long cachedSwapPss = 0;
16068        boolean hasSwapPss = false;
16069
16070        Debug.MemoryInfo mi = null;
16071        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16072            final ProcessRecord r = procs.get(i);
16073            final IApplicationThread thread;
16074            final int pid;
16075            final int oomAdj;
16076            final boolean hasActivities;
16077            synchronized (this) {
16078                thread = r.thread;
16079                pid = r.pid;
16080                oomAdj = r.getSetAdjWithServices();
16081                hasActivities = r.activities.size() > 0;
16082            }
16083            if (thread != null) {
16084                if (!isCheckinRequest && dumpDetails) {
16085                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16086                }
16087                if (mi == null) {
16088                    mi = new Debug.MemoryInfo();
16089                }
16090                if (dumpDetails || (!brief && !oomOnly)) {
16091                    Debug.getMemoryInfo(pid, mi);
16092                    hasSwapPss = mi.hasSwappedOutPss;
16093                } else {
16094                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16095                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16096                }
16097                if (dumpDetails) {
16098                    if (localOnly) {
16099                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16100                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16101                        if (isCheckinRequest) {
16102                            pw.println();
16103                        }
16104                    } else {
16105                        try {
16106                            pw.flush();
16107                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16108                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16109                        } catch (RemoteException e) {
16110                            if (!isCheckinRequest) {
16111                                pw.println("Got RemoteException!");
16112                                pw.flush();
16113                            }
16114                        }
16115                    }
16116                }
16117
16118                final long myTotalPss = mi.getTotalPss();
16119                final long myTotalUss = mi.getTotalUss();
16120                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16121
16122                synchronized (this) {
16123                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16124                        // Record this for posterity if the process has been stable.
16125                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16126                    }
16127                }
16128
16129                if (!isCheckinRequest && mi != null) {
16130                    totalPss += myTotalPss;
16131                    totalSwapPss += myTotalSwapPss;
16132                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16133                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16134                            myTotalSwapPss, pid, hasActivities);
16135                    procMems.add(pssItem);
16136                    procMemsMap.put(pid, pssItem);
16137
16138                    nativePss += mi.nativePss;
16139                    nativeSwapPss += mi.nativeSwappedOutPss;
16140                    dalvikPss += mi.dalvikPss;
16141                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16142                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16143                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16144                        dalvikSubitemSwapPss[j] +=
16145                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16146                    }
16147                    otherPss += mi.otherPss;
16148                    otherSwapPss += mi.otherSwappedOutPss;
16149                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16150                        long mem = mi.getOtherPss(j);
16151                        miscPss[j] += mem;
16152                        otherPss -= mem;
16153                        mem = mi.getOtherSwappedOutPss(j);
16154                        miscSwapPss[j] += mem;
16155                        otherSwapPss -= mem;
16156                    }
16157
16158                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16159                        cachedPss += myTotalPss;
16160                        cachedSwapPss += myTotalSwapPss;
16161                    }
16162
16163                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16164                        if (oomIndex == (oomPss.length - 1)
16165                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16166                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16167                            oomPss[oomIndex] += myTotalPss;
16168                            oomSwapPss[oomIndex] += myTotalSwapPss;
16169                            if (oomProcs[oomIndex] == null) {
16170                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16171                            }
16172                            oomProcs[oomIndex].add(pssItem);
16173                            break;
16174                        }
16175                    }
16176                }
16177            }
16178        }
16179
16180        long nativeProcTotalPss = 0;
16181
16182        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16183            // If we are showing aggregations, also look for native processes to
16184            // include so that our aggregations are more accurate.
16185            updateCpuStatsNow();
16186            mi = null;
16187            synchronized (mProcessCpuTracker) {
16188                final int N = mProcessCpuTracker.countStats();
16189                for (int i=0; i<N; i++) {
16190                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16191                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16192                        if (mi == null) {
16193                            mi = new Debug.MemoryInfo();
16194                        }
16195                        if (!brief && !oomOnly) {
16196                            Debug.getMemoryInfo(st.pid, mi);
16197                        } else {
16198                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16199                            mi.nativePrivateDirty = (int)tmpLong[0];
16200                        }
16201
16202                        final long myTotalPss = mi.getTotalPss();
16203                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16204                        totalPss += myTotalPss;
16205                        nativeProcTotalPss += myTotalPss;
16206
16207                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16208                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16209                        procMems.add(pssItem);
16210
16211                        nativePss += mi.nativePss;
16212                        nativeSwapPss += mi.nativeSwappedOutPss;
16213                        dalvikPss += mi.dalvikPss;
16214                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16215                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16216                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16217                            dalvikSubitemSwapPss[j] +=
16218                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16219                        }
16220                        otherPss += mi.otherPss;
16221                        otherSwapPss += mi.otherSwappedOutPss;
16222                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16223                            long mem = mi.getOtherPss(j);
16224                            miscPss[j] += mem;
16225                            otherPss -= mem;
16226                            mem = mi.getOtherSwappedOutPss(j);
16227                            miscSwapPss[j] += mem;
16228                            otherSwapPss -= mem;
16229                        }
16230                        oomPss[0] += myTotalPss;
16231                        oomSwapPss[0] += myTotalSwapPss;
16232                        if (oomProcs[0] == null) {
16233                            oomProcs[0] = new ArrayList<MemItem>();
16234                        }
16235                        oomProcs[0].add(pssItem);
16236                    }
16237                }
16238            }
16239
16240            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16241
16242            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16243            final MemItem dalvikItem =
16244                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16245            if (dalvikSubitemPss.length > 0) {
16246                dalvikItem.subitems = new ArrayList<MemItem>();
16247                for (int j=0; j<dalvikSubitemPss.length; j++) {
16248                    final String name = Debug.MemoryInfo.getOtherLabel(
16249                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16250                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16251                                    dalvikSubitemSwapPss[j], j));
16252                }
16253            }
16254            catMems.add(dalvikItem);
16255            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16256            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16257                String label = Debug.MemoryInfo.getOtherLabel(j);
16258                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16259            }
16260
16261            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16262            for (int j=0; j<oomPss.length; j++) {
16263                if (oomPss[j] != 0) {
16264                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16265                            : DUMP_MEM_OOM_LABEL[j];
16266                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16267                            DUMP_MEM_OOM_ADJ[j]);
16268                    item.subitems = oomProcs[j];
16269                    oomMems.add(item);
16270                }
16271            }
16272
16273            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16274            if (!brief && !oomOnly && !isCompact) {
16275                pw.println();
16276                pw.println("Total PSS by process:");
16277                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16278                pw.println();
16279            }
16280            if (!isCompact) {
16281                pw.println("Total PSS by OOM adjustment:");
16282            }
16283            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16284            if (!brief && !oomOnly) {
16285                PrintWriter out = categoryPw != null ? categoryPw : pw;
16286                if (!isCompact) {
16287                    out.println();
16288                    out.println("Total PSS by category:");
16289                }
16290                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16291            }
16292            if (!isCompact) {
16293                pw.println();
16294            }
16295            MemInfoReader memInfo = new MemInfoReader();
16296            memInfo.readMemInfo();
16297            if (nativeProcTotalPss > 0) {
16298                synchronized (this) {
16299                    final long cachedKb = memInfo.getCachedSizeKb();
16300                    final long freeKb = memInfo.getFreeSizeKb();
16301                    final long zramKb = memInfo.getZramTotalSizeKb();
16302                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16303                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16304                            kernelKb*1024, nativeProcTotalPss*1024);
16305                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16306                            nativeProcTotalPss);
16307                }
16308            }
16309            if (!brief) {
16310                if (!isCompact) {
16311                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16312                    pw.print(" (status ");
16313                    switch (mLastMemoryLevel) {
16314                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16315                            pw.println("normal)");
16316                            break;
16317                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16318                            pw.println("moderate)");
16319                            break;
16320                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16321                            pw.println("low)");
16322                            break;
16323                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16324                            pw.println("critical)");
16325                            break;
16326                        default:
16327                            pw.print(mLastMemoryLevel);
16328                            pw.println(")");
16329                            break;
16330                    }
16331                    pw.print(" Free RAM: ");
16332                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16333                            + memInfo.getFreeSizeKb()));
16334                    pw.print(" (");
16335                    pw.print(stringifyKBSize(cachedPss));
16336                    pw.print(" cached pss + ");
16337                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16338                    pw.print(" cached kernel + ");
16339                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16340                    pw.println(" free)");
16341                } else {
16342                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16343                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16344                            + memInfo.getFreeSizeKb()); pw.print(",");
16345                    pw.println(totalPss - cachedPss);
16346                }
16347            }
16348            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16349                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16350                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16351            if (!isCompact) {
16352                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16353                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16354                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16355                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16356                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16357            } else {
16358                pw.print("lostram,"); pw.println(lostRAM);
16359            }
16360            if (!brief) {
16361                if (memInfo.getZramTotalSizeKb() != 0) {
16362                    if (!isCompact) {
16363                        pw.print("     ZRAM: ");
16364                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16365                                pw.print(" physical used for ");
16366                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16367                                        - memInfo.getSwapFreeSizeKb()));
16368                                pw.print(" in swap (");
16369                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16370                                pw.println(" total swap)");
16371                    } else {
16372                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16373                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16374                                pw.println(memInfo.getSwapFreeSizeKb());
16375                    }
16376                }
16377                final long[] ksm = getKsmInfo();
16378                if (!isCompact) {
16379                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16380                            || ksm[KSM_VOLATILE] != 0) {
16381                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16382                                pw.print(" saved from shared ");
16383                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16384                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16385                                pw.print(" unshared; ");
16386                                pw.print(stringifyKBSize(
16387                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16388                    }
16389                    pw.print("   Tuning: ");
16390                    pw.print(ActivityManager.staticGetMemoryClass());
16391                    pw.print(" (large ");
16392                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16393                    pw.print("), oom ");
16394                    pw.print(stringifySize(
16395                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16396                    pw.print(", restore limit ");
16397                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16398                    if (ActivityManager.isLowRamDeviceStatic()) {
16399                        pw.print(" (low-ram)");
16400                    }
16401                    if (ActivityManager.isHighEndGfx()) {
16402                        pw.print(" (high-end-gfx)");
16403                    }
16404                    pw.println();
16405                } else {
16406                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16407                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16408                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16409                    pw.print("tuning,");
16410                    pw.print(ActivityManager.staticGetMemoryClass());
16411                    pw.print(',');
16412                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16413                    pw.print(',');
16414                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16415                    if (ActivityManager.isLowRamDeviceStatic()) {
16416                        pw.print(",low-ram");
16417                    }
16418                    if (ActivityManager.isHighEndGfx()) {
16419                        pw.print(",high-end-gfx");
16420                    }
16421                    pw.println();
16422                }
16423            }
16424        }
16425    }
16426
16427    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16428            long memtrack, String name) {
16429        sb.append("  ");
16430        sb.append(ProcessList.makeOomAdjString(oomAdj));
16431        sb.append(' ');
16432        sb.append(ProcessList.makeProcStateString(procState));
16433        sb.append(' ');
16434        ProcessList.appendRamKb(sb, pss);
16435        sb.append(": ");
16436        sb.append(name);
16437        if (memtrack > 0) {
16438            sb.append(" (");
16439            sb.append(stringifyKBSize(memtrack));
16440            sb.append(" memtrack)");
16441        }
16442    }
16443
16444    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16445        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16446        sb.append(" (pid ");
16447        sb.append(mi.pid);
16448        sb.append(") ");
16449        sb.append(mi.adjType);
16450        sb.append('\n');
16451        if (mi.adjReason != null) {
16452            sb.append("                      ");
16453            sb.append(mi.adjReason);
16454            sb.append('\n');
16455        }
16456    }
16457
16458    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16459        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16460        for (int i=0, N=memInfos.size(); i<N; i++) {
16461            ProcessMemInfo mi = memInfos.get(i);
16462            infoMap.put(mi.pid, mi);
16463        }
16464        updateCpuStatsNow();
16465        long[] memtrackTmp = new long[1];
16466        synchronized (mProcessCpuTracker) {
16467            final int N = mProcessCpuTracker.countStats();
16468            for (int i=0; i<N; i++) {
16469                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16470                if (st.vsize > 0) {
16471                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16472                    if (pss > 0) {
16473                        if (infoMap.indexOfKey(st.pid) < 0) {
16474                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16475                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16476                            mi.pss = pss;
16477                            mi.memtrack = memtrackTmp[0];
16478                            memInfos.add(mi);
16479                        }
16480                    }
16481                }
16482            }
16483        }
16484
16485        long totalPss = 0;
16486        long totalMemtrack = 0;
16487        for (int i=0, N=memInfos.size(); i<N; i++) {
16488            ProcessMemInfo mi = memInfos.get(i);
16489            if (mi.pss == 0) {
16490                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16491                mi.memtrack = memtrackTmp[0];
16492            }
16493            totalPss += mi.pss;
16494            totalMemtrack += mi.memtrack;
16495        }
16496        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16497            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16498                if (lhs.oomAdj != rhs.oomAdj) {
16499                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16500                }
16501                if (lhs.pss != rhs.pss) {
16502                    return lhs.pss < rhs.pss ? 1 : -1;
16503                }
16504                return 0;
16505            }
16506        });
16507
16508        StringBuilder tag = new StringBuilder(128);
16509        StringBuilder stack = new StringBuilder(128);
16510        tag.append("Low on memory -- ");
16511        appendMemBucket(tag, totalPss, "total", false);
16512        appendMemBucket(stack, totalPss, "total", true);
16513
16514        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16515        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16516        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16517
16518        boolean firstLine = true;
16519        int lastOomAdj = Integer.MIN_VALUE;
16520        long extraNativeRam = 0;
16521        long extraNativeMemtrack = 0;
16522        long cachedPss = 0;
16523        for (int i=0, N=memInfos.size(); i<N; i++) {
16524            ProcessMemInfo mi = memInfos.get(i);
16525
16526            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16527                cachedPss += mi.pss;
16528            }
16529
16530            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16531                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16532                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16533                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16534                if (lastOomAdj != mi.oomAdj) {
16535                    lastOomAdj = mi.oomAdj;
16536                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16537                        tag.append(" / ");
16538                    }
16539                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16540                        if (firstLine) {
16541                            stack.append(":");
16542                            firstLine = false;
16543                        }
16544                        stack.append("\n\t at ");
16545                    } else {
16546                        stack.append("$");
16547                    }
16548                } else {
16549                    tag.append(" ");
16550                    stack.append("$");
16551                }
16552                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16553                    appendMemBucket(tag, mi.pss, mi.name, false);
16554                }
16555                appendMemBucket(stack, mi.pss, mi.name, true);
16556                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16557                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16558                    stack.append("(");
16559                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16560                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16561                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16562                            stack.append(":");
16563                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16564                        }
16565                    }
16566                    stack.append(")");
16567                }
16568            }
16569
16570            appendMemInfo(fullNativeBuilder, mi);
16571            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16572                // The short form only has native processes that are >= 512K.
16573                if (mi.pss >= 512) {
16574                    appendMemInfo(shortNativeBuilder, mi);
16575                } else {
16576                    extraNativeRam += mi.pss;
16577                    extraNativeMemtrack += mi.memtrack;
16578                }
16579            } else {
16580                // Short form has all other details, but if we have collected RAM
16581                // from smaller native processes let's dump a summary of that.
16582                if (extraNativeRam > 0) {
16583                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16584                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16585                    shortNativeBuilder.append('\n');
16586                    extraNativeRam = 0;
16587                }
16588                appendMemInfo(fullJavaBuilder, mi);
16589            }
16590        }
16591
16592        fullJavaBuilder.append("           ");
16593        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16594        fullJavaBuilder.append(": TOTAL");
16595        if (totalMemtrack > 0) {
16596            fullJavaBuilder.append(" (");
16597            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16598            fullJavaBuilder.append(" memtrack)");
16599        } else {
16600        }
16601        fullJavaBuilder.append("\n");
16602
16603        MemInfoReader memInfo = new MemInfoReader();
16604        memInfo.readMemInfo();
16605        final long[] infos = memInfo.getRawInfo();
16606
16607        StringBuilder memInfoBuilder = new StringBuilder(1024);
16608        Debug.getMemInfo(infos);
16609        memInfoBuilder.append("  MemInfo: ");
16610        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16611        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16612        memInfoBuilder.append(stringifyKBSize(
16613                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16614        memInfoBuilder.append(stringifyKBSize(
16615                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16616        memInfoBuilder.append(stringifyKBSize(
16617                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16618        memInfoBuilder.append("           ");
16619        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16620        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16621        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16622        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16623        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16624            memInfoBuilder.append("  ZRAM: ");
16625            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16626            memInfoBuilder.append(" RAM, ");
16627            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16628            memInfoBuilder.append(" swap total, ");
16629            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16630            memInfoBuilder.append(" swap free\n");
16631        }
16632        final long[] ksm = getKsmInfo();
16633        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16634                || ksm[KSM_VOLATILE] != 0) {
16635            memInfoBuilder.append("  KSM: ");
16636            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16637            memInfoBuilder.append(" saved from shared ");
16638            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16639            memInfoBuilder.append("\n       ");
16640            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16641            memInfoBuilder.append(" unshared; ");
16642            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16643            memInfoBuilder.append(" volatile\n");
16644        }
16645        memInfoBuilder.append("  Free RAM: ");
16646        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16647                + memInfo.getFreeSizeKb()));
16648        memInfoBuilder.append("\n");
16649        memInfoBuilder.append("  Used RAM: ");
16650        memInfoBuilder.append(stringifyKBSize(
16651                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16652        memInfoBuilder.append("\n");
16653        memInfoBuilder.append("  Lost RAM: ");
16654        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16655                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16656                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16657        memInfoBuilder.append("\n");
16658        Slog.i(TAG, "Low on memory:");
16659        Slog.i(TAG, shortNativeBuilder.toString());
16660        Slog.i(TAG, fullJavaBuilder.toString());
16661        Slog.i(TAG, memInfoBuilder.toString());
16662
16663        StringBuilder dropBuilder = new StringBuilder(1024);
16664        /*
16665        StringWriter oomSw = new StringWriter();
16666        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16667        StringWriter catSw = new StringWriter();
16668        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16669        String[] emptyArgs = new String[] { };
16670        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16671        oomPw.flush();
16672        String oomString = oomSw.toString();
16673        */
16674        dropBuilder.append("Low on memory:");
16675        dropBuilder.append(stack);
16676        dropBuilder.append('\n');
16677        dropBuilder.append(fullNativeBuilder);
16678        dropBuilder.append(fullJavaBuilder);
16679        dropBuilder.append('\n');
16680        dropBuilder.append(memInfoBuilder);
16681        dropBuilder.append('\n');
16682        /*
16683        dropBuilder.append(oomString);
16684        dropBuilder.append('\n');
16685        */
16686        StringWriter catSw = new StringWriter();
16687        synchronized (ActivityManagerService.this) {
16688            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16689            String[] emptyArgs = new String[] { };
16690            catPw.println();
16691            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16692            catPw.println();
16693            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16694                    false, null).dumpLocked();
16695            catPw.println();
16696            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16697            catPw.flush();
16698        }
16699        dropBuilder.append(catSw.toString());
16700        addErrorToDropBox("lowmem", null, "system_server", null,
16701                null, tag.toString(), dropBuilder.toString(), null, null);
16702        //Slog.i(TAG, "Sent to dropbox:");
16703        //Slog.i(TAG, dropBuilder.toString());
16704        synchronized (ActivityManagerService.this) {
16705            long now = SystemClock.uptimeMillis();
16706            if (mLastMemUsageReportTime < now) {
16707                mLastMemUsageReportTime = now;
16708            }
16709        }
16710    }
16711
16712    /**
16713     * Searches array of arguments for the specified string
16714     * @param args array of argument strings
16715     * @param value value to search for
16716     * @return true if the value is contained in the array
16717     */
16718    private static boolean scanArgs(String[] args, String value) {
16719        if (args != null) {
16720            for (String arg : args) {
16721                if (value.equals(arg)) {
16722                    return true;
16723                }
16724            }
16725        }
16726        return false;
16727    }
16728
16729    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16730            ContentProviderRecord cpr, boolean always) {
16731        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16732
16733        if (!inLaunching || always) {
16734            synchronized (cpr) {
16735                cpr.launchingApp = null;
16736                cpr.notifyAll();
16737            }
16738            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16739            String names[] = cpr.info.authority.split(";");
16740            for (int j = 0; j < names.length; j++) {
16741                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16742            }
16743        }
16744
16745        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16746            ContentProviderConnection conn = cpr.connections.get(i);
16747            if (conn.waiting) {
16748                // If this connection is waiting for the provider, then we don't
16749                // need to mess with its process unless we are always removing
16750                // or for some reason the provider is not currently launching.
16751                if (inLaunching && !always) {
16752                    continue;
16753                }
16754            }
16755            ProcessRecord capp = conn.client;
16756            conn.dead = true;
16757            if (conn.stableCount > 0) {
16758                if (!capp.persistent && capp.thread != null
16759                        && capp.pid != 0
16760                        && capp.pid != MY_PID) {
16761                    capp.kill("depends on provider "
16762                            + cpr.name.flattenToShortString()
16763                            + " in dying proc " + (proc != null ? proc.processName : "??")
16764                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16765                }
16766            } else if (capp.thread != null && conn.provider.provider != null) {
16767                try {
16768                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16769                } catch (RemoteException e) {
16770                }
16771                // In the protocol here, we don't expect the client to correctly
16772                // clean up this connection, we'll just remove it.
16773                cpr.connections.remove(i);
16774                if (conn.client.conProviders.remove(conn)) {
16775                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16776                }
16777            }
16778        }
16779
16780        if (inLaunching && always) {
16781            mLaunchingProviders.remove(cpr);
16782        }
16783        return inLaunching;
16784    }
16785
16786    /**
16787     * Main code for cleaning up a process when it has gone away.  This is
16788     * called both as a result of the process dying, or directly when stopping
16789     * a process when running in single process mode.
16790     *
16791     * @return Returns true if the given process has been restarted, so the
16792     * app that was passed in must remain on the process lists.
16793     */
16794    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16795            boolean restarting, boolean allowRestart, int index) {
16796        if (index >= 0) {
16797            removeLruProcessLocked(app);
16798            ProcessList.remove(app.pid);
16799        }
16800
16801        mProcessesToGc.remove(app);
16802        mPendingPssProcesses.remove(app);
16803
16804        // Dismiss any open dialogs.
16805        if (app.crashDialog != null && !app.forceCrashReport) {
16806            app.crashDialog.dismiss();
16807            app.crashDialog = null;
16808        }
16809        if (app.anrDialog != null) {
16810            app.anrDialog.dismiss();
16811            app.anrDialog = null;
16812        }
16813        if (app.waitDialog != null) {
16814            app.waitDialog.dismiss();
16815            app.waitDialog = null;
16816        }
16817
16818        app.crashing = false;
16819        app.notResponding = false;
16820
16821        app.resetPackageList(mProcessStats);
16822        app.unlinkDeathRecipient();
16823        app.makeInactive(mProcessStats);
16824        app.waitingToKill = null;
16825        app.forcingToForeground = null;
16826        updateProcessForegroundLocked(app, false, false);
16827        app.foregroundActivities = false;
16828        app.hasShownUi = false;
16829        app.treatLikeActivity = false;
16830        app.hasAboveClient = false;
16831        app.hasClientActivities = false;
16832
16833        mServices.killServicesLocked(app, allowRestart);
16834
16835        boolean restart = false;
16836
16837        // Remove published content providers.
16838        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16839            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16840            final boolean always = app.bad || !allowRestart;
16841            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16842            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16843                // We left the provider in the launching list, need to
16844                // restart it.
16845                restart = true;
16846            }
16847
16848            cpr.provider = null;
16849            cpr.proc = null;
16850        }
16851        app.pubProviders.clear();
16852
16853        // Take care of any launching providers waiting for this process.
16854        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16855            restart = true;
16856        }
16857
16858        // Unregister from connected content providers.
16859        if (!app.conProviders.isEmpty()) {
16860            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16861                ContentProviderConnection conn = app.conProviders.get(i);
16862                conn.provider.connections.remove(conn);
16863                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16864                        conn.provider.name);
16865            }
16866            app.conProviders.clear();
16867        }
16868
16869        // At this point there may be remaining entries in mLaunchingProviders
16870        // where we were the only one waiting, so they are no longer of use.
16871        // Look for these and clean up if found.
16872        // XXX Commented out for now.  Trying to figure out a way to reproduce
16873        // the actual situation to identify what is actually going on.
16874        if (false) {
16875            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16876                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16877                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16878                    synchronized (cpr) {
16879                        cpr.launchingApp = null;
16880                        cpr.notifyAll();
16881                    }
16882                }
16883            }
16884        }
16885
16886        skipCurrentReceiverLocked(app);
16887
16888        // Unregister any receivers.
16889        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16890            removeReceiverLocked(app.receivers.valueAt(i));
16891        }
16892        app.receivers.clear();
16893
16894        // If the app is undergoing backup, tell the backup manager about it
16895        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16896            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16897                    + mBackupTarget.appInfo + " died during backup");
16898            try {
16899                IBackupManager bm = IBackupManager.Stub.asInterface(
16900                        ServiceManager.getService(Context.BACKUP_SERVICE));
16901                bm.agentDisconnected(app.info.packageName);
16902            } catch (RemoteException e) {
16903                // can't happen; backup manager is local
16904            }
16905        }
16906
16907        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16908            ProcessChangeItem item = mPendingProcessChanges.get(i);
16909            if (item.pid == app.pid) {
16910                mPendingProcessChanges.remove(i);
16911                mAvailProcessChanges.add(item);
16912            }
16913        }
16914        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16915                null).sendToTarget();
16916
16917        // If the caller is restarting this app, then leave it in its
16918        // current lists and let the caller take care of it.
16919        if (restarting) {
16920            return false;
16921        }
16922
16923        if (!app.persistent || app.isolated) {
16924            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16925                    "Removing non-persistent process during cleanup: " + app);
16926            removeProcessNameLocked(app.processName, app.uid);
16927            if (mHeavyWeightProcess == app) {
16928                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16929                        mHeavyWeightProcess.userId, 0));
16930                mHeavyWeightProcess = null;
16931            }
16932        } else if (!app.removed) {
16933            // This app is persistent, so we need to keep its record around.
16934            // If it is not already on the pending app list, add it there
16935            // and start a new process for it.
16936            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16937                mPersistentStartingProcesses.add(app);
16938                restart = true;
16939            }
16940        }
16941        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16942                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16943        mProcessesOnHold.remove(app);
16944
16945        if (app == mHomeProcess) {
16946            mHomeProcess = null;
16947        }
16948        if (app == mPreviousProcess) {
16949            mPreviousProcess = null;
16950        }
16951
16952        if (restart && !app.isolated) {
16953            // We have components that still need to be running in the
16954            // process, so re-launch it.
16955            if (index < 0) {
16956                ProcessList.remove(app.pid);
16957            }
16958            addProcessNameLocked(app);
16959            startProcessLocked(app, "restart", app.processName);
16960            return true;
16961        } else if (app.pid > 0 && app.pid != MY_PID) {
16962            // Goodbye!
16963            boolean removed;
16964            synchronized (mPidsSelfLocked) {
16965                mPidsSelfLocked.remove(app.pid);
16966                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16967            }
16968            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16969            if (app.isolated) {
16970                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16971            }
16972            app.setPid(0);
16973        }
16974        return false;
16975    }
16976
16977    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16978        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16979            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16980            if (cpr.launchingApp == app) {
16981                return true;
16982            }
16983        }
16984        return false;
16985    }
16986
16987    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16988        // Look through the content providers we are waiting to have launched,
16989        // and if any run in this process then either schedule a restart of
16990        // the process or kill the client waiting for it if this process has
16991        // gone bad.
16992        boolean restart = false;
16993        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16994            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16995            if (cpr.launchingApp == app) {
16996                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16997                    restart = true;
16998                } else {
16999                    removeDyingProviderLocked(app, cpr, true);
17000                }
17001            }
17002        }
17003        return restart;
17004    }
17005
17006    // =========================================================
17007    // SERVICES
17008    // =========================================================
17009
17010    @Override
17011    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17012            int flags) {
17013        enforceNotIsolatedCaller("getServices");
17014        synchronized (this) {
17015            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17016        }
17017    }
17018
17019    @Override
17020    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17021        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17022        synchronized (this) {
17023            return mServices.getRunningServiceControlPanelLocked(name);
17024        }
17025    }
17026
17027    @Override
17028    public ComponentName startService(IApplicationThread caller, Intent service,
17029            String resolvedType, String callingPackage, int userId)
17030            throws TransactionTooLargeException {
17031        enforceNotIsolatedCaller("startService");
17032        // Refuse possible leaked file descriptors
17033        if (service != null && service.hasFileDescriptors() == true) {
17034            throw new IllegalArgumentException("File descriptors passed in Intent");
17035        }
17036
17037        if (callingPackage == null) {
17038            throw new IllegalArgumentException("callingPackage cannot be null");
17039        }
17040
17041        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17042                "startService: " + service + " type=" + resolvedType);
17043        synchronized(this) {
17044            final int callingPid = Binder.getCallingPid();
17045            final int callingUid = Binder.getCallingUid();
17046            final long origId = Binder.clearCallingIdentity();
17047            ComponentName res = mServices.startServiceLocked(caller, service,
17048                    resolvedType, callingPid, callingUid, callingPackage, userId);
17049            Binder.restoreCallingIdentity(origId);
17050            return res;
17051        }
17052    }
17053
17054    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17055            String callingPackage, int userId)
17056            throws TransactionTooLargeException {
17057        synchronized(this) {
17058            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17059                    "startServiceInPackage: " + service + " type=" + resolvedType);
17060            final long origId = Binder.clearCallingIdentity();
17061            ComponentName res = mServices.startServiceLocked(null, service,
17062                    resolvedType, -1, uid, callingPackage, userId);
17063            Binder.restoreCallingIdentity(origId);
17064            return res;
17065        }
17066    }
17067
17068    @Override
17069    public int stopService(IApplicationThread caller, Intent service,
17070            String resolvedType, int userId) {
17071        enforceNotIsolatedCaller("stopService");
17072        // Refuse possible leaked file descriptors
17073        if (service != null && service.hasFileDescriptors() == true) {
17074            throw new IllegalArgumentException("File descriptors passed in Intent");
17075        }
17076
17077        synchronized(this) {
17078            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17079        }
17080    }
17081
17082    @Override
17083    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17084        enforceNotIsolatedCaller("peekService");
17085        // Refuse possible leaked file descriptors
17086        if (service != null && service.hasFileDescriptors() == true) {
17087            throw new IllegalArgumentException("File descriptors passed in Intent");
17088        }
17089
17090        if (callingPackage == null) {
17091            throw new IllegalArgumentException("callingPackage cannot be null");
17092        }
17093
17094        synchronized(this) {
17095            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17096        }
17097    }
17098
17099    @Override
17100    public boolean stopServiceToken(ComponentName className, IBinder token,
17101            int startId) {
17102        synchronized(this) {
17103            return mServices.stopServiceTokenLocked(className, token, startId);
17104        }
17105    }
17106
17107    @Override
17108    public void setServiceForeground(ComponentName className, IBinder token,
17109            int id, Notification notification, int flags) {
17110        synchronized(this) {
17111            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17112        }
17113    }
17114
17115    @Override
17116    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17117            boolean requireFull, String name, String callerPackage) {
17118        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17119                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17120    }
17121
17122    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17123            String className, int flags) {
17124        boolean result = false;
17125        // For apps that don't have pre-defined UIDs, check for permission
17126        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17127            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17128                if (ActivityManager.checkUidPermission(
17129                        INTERACT_ACROSS_USERS,
17130                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17131                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17132                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17133                            + " requests FLAG_SINGLE_USER, but app does not hold "
17134                            + INTERACT_ACROSS_USERS;
17135                    Slog.w(TAG, msg);
17136                    throw new SecurityException(msg);
17137                }
17138                // Permission passed
17139                result = true;
17140            }
17141        } else if ("system".equals(componentProcessName)) {
17142            result = true;
17143        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17144            // Phone app and persistent apps are allowed to export singleuser providers.
17145            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17146                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17147        }
17148        if (DEBUG_MU) Slog.v(TAG_MU,
17149                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17150                + Integer.toHexString(flags) + ") = " + result);
17151        return result;
17152    }
17153
17154    /**
17155     * Checks to see if the caller is in the same app as the singleton
17156     * component, or the component is in a special app. It allows special apps
17157     * to export singleton components but prevents exporting singleton
17158     * components for regular apps.
17159     */
17160    boolean isValidSingletonCall(int callingUid, int componentUid) {
17161        int componentAppId = UserHandle.getAppId(componentUid);
17162        return UserHandle.isSameApp(callingUid, componentUid)
17163                || componentAppId == Process.SYSTEM_UID
17164                || componentAppId == Process.PHONE_UID
17165                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17166                        == PackageManager.PERMISSION_GRANTED;
17167    }
17168
17169    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17170            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17171            int userId) throws TransactionTooLargeException {
17172        enforceNotIsolatedCaller("bindService");
17173
17174        // Refuse possible leaked file descriptors
17175        if (service != null && service.hasFileDescriptors() == true) {
17176            throw new IllegalArgumentException("File descriptors passed in Intent");
17177        }
17178
17179        if (callingPackage == null) {
17180            throw new IllegalArgumentException("callingPackage cannot be null");
17181        }
17182
17183        synchronized(this) {
17184            return mServices.bindServiceLocked(caller, token, service,
17185                    resolvedType, connection, flags, callingPackage, userId);
17186        }
17187    }
17188
17189    public boolean unbindService(IServiceConnection connection) {
17190        synchronized (this) {
17191            return mServices.unbindServiceLocked(connection);
17192        }
17193    }
17194
17195    public void publishService(IBinder token, Intent intent, IBinder service) {
17196        // Refuse possible leaked file descriptors
17197        if (intent != null && intent.hasFileDescriptors() == true) {
17198            throw new IllegalArgumentException("File descriptors passed in Intent");
17199        }
17200
17201        synchronized(this) {
17202            if (!(token instanceof ServiceRecord)) {
17203                throw new IllegalArgumentException("Invalid service token");
17204            }
17205            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17206        }
17207    }
17208
17209    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17210        // Refuse possible leaked file descriptors
17211        if (intent != null && intent.hasFileDescriptors() == true) {
17212            throw new IllegalArgumentException("File descriptors passed in Intent");
17213        }
17214
17215        synchronized(this) {
17216            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17217        }
17218    }
17219
17220    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17221        synchronized(this) {
17222            if (!(token instanceof ServiceRecord)) {
17223                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17224                throw new IllegalArgumentException("Invalid service token");
17225            }
17226            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17227        }
17228    }
17229
17230    // =========================================================
17231    // BACKUP AND RESTORE
17232    // =========================================================
17233
17234    // Cause the target app to be launched if necessary and its backup agent
17235    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17236    // activity manager to announce its creation.
17237    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17238        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17239        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17240
17241        IPackageManager pm = AppGlobals.getPackageManager();
17242        ApplicationInfo app = null;
17243        try {
17244            app = pm.getApplicationInfo(packageName, 0, userId);
17245        } catch (RemoteException e) {
17246            // can't happen; package manager is process-local
17247        }
17248        if (app == null) {
17249            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17250            return false;
17251        }
17252
17253        synchronized(this) {
17254            // !!! TODO: currently no check here that we're already bound
17255            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17256            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17257            synchronized (stats) {
17258                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17259            }
17260
17261            // Backup agent is now in use, its package can't be stopped.
17262            try {
17263                AppGlobals.getPackageManager().setPackageStoppedState(
17264                        app.packageName, false, UserHandle.getUserId(app.uid));
17265            } catch (RemoteException e) {
17266            } catch (IllegalArgumentException e) {
17267                Slog.w(TAG, "Failed trying to unstop package "
17268                        + app.packageName + ": " + e);
17269            }
17270
17271            BackupRecord r = new BackupRecord(ss, app, backupMode);
17272            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17273                    ? new ComponentName(app.packageName, app.backupAgentName)
17274                    : new ComponentName("android", "FullBackupAgent");
17275            // startProcessLocked() returns existing proc's record if it's already running
17276            ProcessRecord proc = startProcessLocked(app.processName, app,
17277                    false, 0, "backup", hostingName, false, false, false);
17278            if (proc == null) {
17279                Slog.e(TAG, "Unable to start backup agent process " + r);
17280                return false;
17281            }
17282
17283            // If the app is a regular app (uid >= 10000) and not the system server or phone
17284            // process, etc, then mark it as being in full backup so that certain calls to the
17285            // process can be blocked. This is not reset to false anywhere because we kill the
17286            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17287            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17288                proc.inFullBackup = true;
17289            }
17290            r.app = proc;
17291            mBackupTarget = r;
17292            mBackupAppName = app.packageName;
17293
17294            // Try not to kill the process during backup
17295            updateOomAdjLocked(proc);
17296
17297            // If the process is already attached, schedule the creation of the backup agent now.
17298            // If it is not yet live, this will be done when it attaches to the framework.
17299            if (proc.thread != null) {
17300                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17301                try {
17302                    proc.thread.scheduleCreateBackupAgent(app,
17303                            compatibilityInfoForPackageLocked(app), backupMode);
17304                } catch (RemoteException e) {
17305                    // Will time out on the backup manager side
17306                }
17307            } else {
17308                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17309            }
17310            // Invariants: at this point, the target app process exists and the application
17311            // is either already running or in the process of coming up.  mBackupTarget and
17312            // mBackupAppName describe the app, so that when it binds back to the AM we
17313            // know that it's scheduled for a backup-agent operation.
17314        }
17315
17316        return true;
17317    }
17318
17319    @Override
17320    public void clearPendingBackup() {
17321        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17322        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17323
17324        synchronized (this) {
17325            mBackupTarget = null;
17326            mBackupAppName = null;
17327        }
17328    }
17329
17330    // A backup agent has just come up
17331    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17332        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17333                + " = " + agent);
17334
17335        synchronized(this) {
17336            if (!agentPackageName.equals(mBackupAppName)) {
17337                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17338                return;
17339            }
17340        }
17341
17342        long oldIdent = Binder.clearCallingIdentity();
17343        try {
17344            IBackupManager bm = IBackupManager.Stub.asInterface(
17345                    ServiceManager.getService(Context.BACKUP_SERVICE));
17346            bm.agentConnected(agentPackageName, agent);
17347        } catch (RemoteException e) {
17348            // can't happen; the backup manager service is local
17349        } catch (Exception e) {
17350            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17351            e.printStackTrace();
17352        } finally {
17353            Binder.restoreCallingIdentity(oldIdent);
17354        }
17355    }
17356
17357    // done with this agent
17358    public void unbindBackupAgent(ApplicationInfo appInfo) {
17359        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17360        if (appInfo == null) {
17361            Slog.w(TAG, "unbind backup agent for null app");
17362            return;
17363        }
17364
17365        synchronized(this) {
17366            try {
17367                if (mBackupAppName == null) {
17368                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17369                    return;
17370                }
17371
17372                if (!mBackupAppName.equals(appInfo.packageName)) {
17373                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17374                    return;
17375                }
17376
17377                // Not backing this app up any more; reset its OOM adjustment
17378                final ProcessRecord proc = mBackupTarget.app;
17379                updateOomAdjLocked(proc);
17380
17381                // If the app crashed during backup, 'thread' will be null here
17382                if (proc.thread != null) {
17383                    try {
17384                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17385                                compatibilityInfoForPackageLocked(appInfo));
17386                    } catch (Exception e) {
17387                        Slog.e(TAG, "Exception when unbinding backup agent:");
17388                        e.printStackTrace();
17389                    }
17390                }
17391            } finally {
17392                mBackupTarget = null;
17393                mBackupAppName = null;
17394            }
17395        }
17396    }
17397    // =========================================================
17398    // BROADCASTS
17399    // =========================================================
17400
17401    boolean isPendingBroadcastProcessLocked(int pid) {
17402        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17403                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17404    }
17405
17406    void skipPendingBroadcastLocked(int pid) {
17407            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17408            for (BroadcastQueue queue : mBroadcastQueues) {
17409                queue.skipPendingBroadcastLocked(pid);
17410            }
17411    }
17412
17413    // The app just attached; send any pending broadcasts that it should receive
17414    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17415        boolean didSomething = false;
17416        for (BroadcastQueue queue : mBroadcastQueues) {
17417            didSomething |= queue.sendPendingBroadcastsLocked(app);
17418        }
17419        return didSomething;
17420    }
17421
17422    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17423            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17424        enforceNotIsolatedCaller("registerReceiver");
17425        ArrayList<Intent> stickyIntents = null;
17426        ProcessRecord callerApp = null;
17427        int callingUid;
17428        int callingPid;
17429        synchronized(this) {
17430            if (caller != null) {
17431                callerApp = getRecordForAppLocked(caller);
17432                if (callerApp == null) {
17433                    throw new SecurityException(
17434                            "Unable to find app for caller " + caller
17435                            + " (pid=" + Binder.getCallingPid()
17436                            + ") when registering receiver " + receiver);
17437                }
17438                if (callerApp.info.uid != Process.SYSTEM_UID &&
17439                        !callerApp.pkgList.containsKey(callerPackage) &&
17440                        !"android".equals(callerPackage)) {
17441                    throw new SecurityException("Given caller package " + callerPackage
17442                            + " is not running in process " + callerApp);
17443                }
17444                callingUid = callerApp.info.uid;
17445                callingPid = callerApp.pid;
17446            } else {
17447                callerPackage = null;
17448                callingUid = Binder.getCallingUid();
17449                callingPid = Binder.getCallingPid();
17450            }
17451
17452            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17453                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17454
17455            Iterator<String> actions = filter.actionsIterator();
17456            if (actions == null) {
17457                ArrayList<String> noAction = new ArrayList<String>(1);
17458                noAction.add(null);
17459                actions = noAction.iterator();
17460            }
17461
17462            // Collect stickies of users
17463            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17464            while (actions.hasNext()) {
17465                String action = actions.next();
17466                for (int id : userIds) {
17467                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17468                    if (stickies != null) {
17469                        ArrayList<Intent> intents = stickies.get(action);
17470                        if (intents != null) {
17471                            if (stickyIntents == null) {
17472                                stickyIntents = new ArrayList<Intent>();
17473                            }
17474                            stickyIntents.addAll(intents);
17475                        }
17476                    }
17477                }
17478            }
17479        }
17480
17481        ArrayList<Intent> allSticky = null;
17482        if (stickyIntents != null) {
17483            final ContentResolver resolver = mContext.getContentResolver();
17484            // Look for any matching sticky broadcasts...
17485            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17486                Intent intent = stickyIntents.get(i);
17487                // If intent has scheme "content", it will need to acccess
17488                // provider that needs to lock mProviderMap in ActivityThread
17489                // and also it may need to wait application response, so we
17490                // cannot lock ActivityManagerService here.
17491                if (filter.match(resolver, intent, true, TAG) >= 0) {
17492                    if (allSticky == null) {
17493                        allSticky = new ArrayList<Intent>();
17494                    }
17495                    allSticky.add(intent);
17496                }
17497            }
17498        }
17499
17500        // The first sticky in the list is returned directly back to the client.
17501        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17502        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17503        if (receiver == null) {
17504            return sticky;
17505        }
17506
17507        synchronized (this) {
17508            if (callerApp != null && (callerApp.thread == null
17509                    || callerApp.thread.asBinder() != caller.asBinder())) {
17510                // Original caller already died
17511                return null;
17512            }
17513            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17514            if (rl == null) {
17515                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17516                        userId, receiver);
17517                if (rl.app != null) {
17518                    rl.app.receivers.add(rl);
17519                } else {
17520                    try {
17521                        receiver.asBinder().linkToDeath(rl, 0);
17522                    } catch (RemoteException e) {
17523                        return sticky;
17524                    }
17525                    rl.linkedToDeath = true;
17526                }
17527                mRegisteredReceivers.put(receiver.asBinder(), rl);
17528            } else if (rl.uid != callingUid) {
17529                throw new IllegalArgumentException(
17530                        "Receiver requested to register for uid " + callingUid
17531                        + " was previously registered for uid " + rl.uid);
17532            } else if (rl.pid != callingPid) {
17533                throw new IllegalArgumentException(
17534                        "Receiver requested to register for pid " + callingPid
17535                        + " was previously registered for pid " + rl.pid);
17536            } else if (rl.userId != userId) {
17537                throw new IllegalArgumentException(
17538                        "Receiver requested to register for user " + userId
17539                        + " was previously registered for user " + rl.userId);
17540            }
17541            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17542                    permission, callingUid, userId);
17543            rl.add(bf);
17544            if (!bf.debugCheck()) {
17545                Slog.w(TAG, "==> For Dynamic broadcast");
17546            }
17547            mReceiverResolver.addFilter(bf);
17548
17549            // Enqueue broadcasts for all existing stickies that match
17550            // this filter.
17551            if (allSticky != null) {
17552                ArrayList receivers = new ArrayList();
17553                receivers.add(bf);
17554
17555                final int stickyCount = allSticky.size();
17556                for (int i = 0; i < stickyCount; i++) {
17557                    Intent intent = allSticky.get(i);
17558                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17559                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17560                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17561                            null, 0, null, null, false, true, true, -1);
17562                    queue.enqueueParallelBroadcastLocked(r);
17563                    queue.scheduleBroadcastsLocked();
17564                }
17565            }
17566
17567            return sticky;
17568        }
17569    }
17570
17571    public void unregisterReceiver(IIntentReceiver receiver) {
17572        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17573
17574        final long origId = Binder.clearCallingIdentity();
17575        try {
17576            boolean doTrim = false;
17577
17578            synchronized(this) {
17579                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17580                if (rl != null) {
17581                    final BroadcastRecord r = rl.curBroadcast;
17582                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17583                        final boolean doNext = r.queue.finishReceiverLocked(
17584                                r, r.resultCode, r.resultData, r.resultExtras,
17585                                r.resultAbort, false);
17586                        if (doNext) {
17587                            doTrim = true;
17588                            r.queue.processNextBroadcast(false);
17589                        }
17590                    }
17591
17592                    if (rl.app != null) {
17593                        rl.app.receivers.remove(rl);
17594                    }
17595                    removeReceiverLocked(rl);
17596                    if (rl.linkedToDeath) {
17597                        rl.linkedToDeath = false;
17598                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17599                    }
17600                }
17601            }
17602
17603            // If we actually concluded any broadcasts, we might now be able
17604            // to trim the recipients' apps from our working set
17605            if (doTrim) {
17606                trimApplications();
17607                return;
17608            }
17609
17610        } finally {
17611            Binder.restoreCallingIdentity(origId);
17612        }
17613    }
17614
17615    void removeReceiverLocked(ReceiverList rl) {
17616        mRegisteredReceivers.remove(rl.receiver.asBinder());
17617        for (int i = rl.size() - 1; i >= 0; i--) {
17618            mReceiverResolver.removeFilter(rl.get(i));
17619        }
17620    }
17621
17622    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17623        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17624            ProcessRecord r = mLruProcesses.get(i);
17625            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17626                try {
17627                    r.thread.dispatchPackageBroadcast(cmd, packages);
17628                } catch (RemoteException ex) {
17629                }
17630            }
17631        }
17632    }
17633
17634    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17635            int callingUid, int[] users) {
17636        // TODO: come back and remove this assumption to triage all broadcasts
17637        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17638
17639        List<ResolveInfo> receivers = null;
17640        try {
17641            HashSet<ComponentName> singleUserReceivers = null;
17642            boolean scannedFirstReceivers = false;
17643            for (int user : users) {
17644                // Skip users that have Shell restrictions, with exception of always permitted
17645                // Shell broadcasts
17646                if (callingUid == Process.SHELL_UID
17647                        && mUserController.hasUserRestriction(
17648                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17649                        && !isPermittedShellBroadcast(intent)) {
17650                    continue;
17651                }
17652                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17653                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17654                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17655                    // If this is not the system user, we need to check for
17656                    // any receivers that should be filtered out.
17657                    for (int i=0; i<newReceivers.size(); i++) {
17658                        ResolveInfo ri = newReceivers.get(i);
17659                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17660                            newReceivers.remove(i);
17661                            i--;
17662                        }
17663                    }
17664                }
17665                if (newReceivers != null && newReceivers.size() == 0) {
17666                    newReceivers = null;
17667                }
17668                if (receivers == null) {
17669                    receivers = newReceivers;
17670                } else if (newReceivers != null) {
17671                    // We need to concatenate the additional receivers
17672                    // found with what we have do far.  This would be easy,
17673                    // but we also need to de-dup any receivers that are
17674                    // singleUser.
17675                    if (!scannedFirstReceivers) {
17676                        // Collect any single user receivers we had already retrieved.
17677                        scannedFirstReceivers = true;
17678                        for (int i=0; i<receivers.size(); i++) {
17679                            ResolveInfo ri = receivers.get(i);
17680                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17681                                ComponentName cn = new ComponentName(
17682                                        ri.activityInfo.packageName, ri.activityInfo.name);
17683                                if (singleUserReceivers == null) {
17684                                    singleUserReceivers = new HashSet<ComponentName>();
17685                                }
17686                                singleUserReceivers.add(cn);
17687                            }
17688                        }
17689                    }
17690                    // Add the new results to the existing results, tracking
17691                    // and de-dupping single user receivers.
17692                    for (int i=0; i<newReceivers.size(); i++) {
17693                        ResolveInfo ri = newReceivers.get(i);
17694                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17695                            ComponentName cn = new ComponentName(
17696                                    ri.activityInfo.packageName, ri.activityInfo.name);
17697                            if (singleUserReceivers == null) {
17698                                singleUserReceivers = new HashSet<ComponentName>();
17699                            }
17700                            if (!singleUserReceivers.contains(cn)) {
17701                                singleUserReceivers.add(cn);
17702                                receivers.add(ri);
17703                            }
17704                        } else {
17705                            receivers.add(ri);
17706                        }
17707                    }
17708                }
17709            }
17710        } catch (RemoteException ex) {
17711            // pm is in same process, this will never happen.
17712        }
17713        return receivers;
17714    }
17715
17716    private boolean isPermittedShellBroadcast(Intent intent) {
17717        // remote bugreport should always be allowed to be taken
17718        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17719    }
17720
17721    final int broadcastIntentLocked(ProcessRecord callerApp,
17722            String callerPackage, Intent intent, String resolvedType,
17723            IIntentReceiver resultTo, int resultCode, String resultData,
17724            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17725            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17726        intent = new Intent(intent);
17727
17728        // By default broadcasts do not go to stopped apps.
17729        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17730
17731        // If we have not finished booting, don't allow this to launch new processes.
17732        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17733            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17734        }
17735
17736        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17737                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17738                + " ordered=" + ordered + " userid=" + userId);
17739        if ((resultTo != null) && !ordered) {
17740            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17741        }
17742
17743        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17744                ALLOW_NON_FULL, "broadcast", callerPackage);
17745
17746        // Make sure that the user who is receiving this broadcast is running.
17747        // If not, we will just skip it. Make an exception for shutdown broadcasts
17748        // and upgrade steps.
17749
17750        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17751            if ((callingUid != Process.SYSTEM_UID
17752                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17753                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17754                Slog.w(TAG, "Skipping broadcast of " + intent
17755                        + ": user " + userId + " is stopped");
17756                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17757            }
17758        }
17759
17760        BroadcastOptions brOptions = null;
17761        if (bOptions != null) {
17762            brOptions = new BroadcastOptions(bOptions);
17763            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17764                // See if the caller is allowed to do this.  Note we are checking against
17765                // the actual real caller (not whoever provided the operation as say a
17766                // PendingIntent), because that who is actually supplied the arguments.
17767                if (checkComponentPermission(
17768                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17769                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17770                        != PackageManager.PERMISSION_GRANTED) {
17771                    String msg = "Permission Denial: " + intent.getAction()
17772                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17773                            + ", uid=" + callingUid + ")"
17774                            + " requires "
17775                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17776                    Slog.w(TAG, msg);
17777                    throw new SecurityException(msg);
17778                }
17779            }
17780        }
17781
17782        // Verify that protected broadcasts are only being sent by system code,
17783        // and that system code is only sending protected broadcasts.
17784        final String action = intent.getAction();
17785        final boolean isProtectedBroadcast;
17786        try {
17787            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17788        } catch (RemoteException e) {
17789            Slog.w(TAG, "Remote exception", e);
17790            return ActivityManager.BROADCAST_SUCCESS;
17791        }
17792
17793        final boolean isCallerSystem;
17794        switch (UserHandle.getAppId(callingUid)) {
17795            case Process.ROOT_UID:
17796            case Process.SYSTEM_UID:
17797            case Process.PHONE_UID:
17798            case Process.BLUETOOTH_UID:
17799            case Process.NFC_UID:
17800                isCallerSystem = true;
17801                break;
17802            default:
17803                isCallerSystem = (callerApp != null) && callerApp.persistent;
17804                break;
17805        }
17806
17807        if (isCallerSystem) {
17808            if (isProtectedBroadcast
17809                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17810                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17811                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17812                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17813                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17814                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17815                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17816                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17817                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17818                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17819                // Broadcast is either protected, or it's a public action that
17820                // we've relaxed, so it's fine for system internals to send.
17821            } else {
17822                // The vast majority of broadcasts sent from system internals
17823                // should be protected to avoid security holes, so yell loudly
17824                // to ensure we examine these cases.
17825                if (callerApp != null) {
17826                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17827                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17828                            new Throwable());
17829                } else {
17830                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17831                            + " from system uid " + UserHandle.formatUid(callingUid)
17832                            + " pkg " + callerPackage,
17833                            new Throwable());
17834                }
17835            }
17836
17837        } else {
17838            if (isProtectedBroadcast) {
17839                String msg = "Permission Denial: not allowed to send broadcast "
17840                        + action + " from pid="
17841                        + callingPid + ", uid=" + callingUid;
17842                Slog.w(TAG, msg);
17843                throw new SecurityException(msg);
17844
17845            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17846                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17847                // Special case for compatibility: we don't want apps to send this,
17848                // but historically it has not been protected and apps may be using it
17849                // to poke their own app widget.  So, instead of making it protected,
17850                // just limit it to the caller.
17851                if (callerPackage == null) {
17852                    String msg = "Permission Denial: not allowed to send broadcast "
17853                            + action + " from unknown caller.";
17854                    Slog.w(TAG, msg);
17855                    throw new SecurityException(msg);
17856                } else if (intent.getComponent() != null) {
17857                    // They are good enough to send to an explicit component...  verify
17858                    // it is being sent to the calling app.
17859                    if (!intent.getComponent().getPackageName().equals(
17860                            callerPackage)) {
17861                        String msg = "Permission Denial: not allowed to send broadcast "
17862                                + action + " to "
17863                                + intent.getComponent().getPackageName() + " from "
17864                                + callerPackage;
17865                        Slog.w(TAG, msg);
17866                        throw new SecurityException(msg);
17867                    }
17868                } else {
17869                    // Limit broadcast to their own package.
17870                    intent.setPackage(callerPackage);
17871                }
17872            }
17873        }
17874
17875        if (action != null) {
17876            switch (action) {
17877                case Intent.ACTION_UID_REMOVED:
17878                case Intent.ACTION_PACKAGE_REMOVED:
17879                case Intent.ACTION_PACKAGE_CHANGED:
17880                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17881                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17882                case Intent.ACTION_PACKAGES_SUSPENDED:
17883                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17884                    // Handle special intents: if this broadcast is from the package
17885                    // manager about a package being removed, we need to remove all of
17886                    // its activities from the history stack.
17887                    if (checkComponentPermission(
17888                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17889                            callingPid, callingUid, -1, true)
17890                            != PackageManager.PERMISSION_GRANTED) {
17891                        String msg = "Permission Denial: " + intent.getAction()
17892                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17893                                + ", uid=" + callingUid + ")"
17894                                + " requires "
17895                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17896                        Slog.w(TAG, msg);
17897                        throw new SecurityException(msg);
17898                    }
17899                    switch (action) {
17900                        case Intent.ACTION_UID_REMOVED:
17901                            final Bundle intentExtras = intent.getExtras();
17902                            final int uid = intentExtras != null
17903                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17904                            if (uid >= 0) {
17905                                mBatteryStatsService.removeUid(uid);
17906                                mAppOpsService.uidRemoved(uid);
17907                            }
17908                            break;
17909                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17910                            // If resources are unavailable just force stop all those packages
17911                            // and flush the attribute cache as well.
17912                            String list[] =
17913                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17914                            if (list != null && list.length > 0) {
17915                                for (int i = 0; i < list.length; i++) {
17916                                    forceStopPackageLocked(list[i], -1, false, true, true,
17917                                            false, false, userId, "storage unmount");
17918                                }
17919                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17920                                sendPackageBroadcastLocked(
17921                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17922                                        userId);
17923                            }
17924                            break;
17925                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17926                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17927                            break;
17928                        case Intent.ACTION_PACKAGE_REMOVED:
17929                        case Intent.ACTION_PACKAGE_CHANGED:
17930                            Uri data = intent.getData();
17931                            String ssp;
17932                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17933                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17934                                final boolean replacing =
17935                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17936                                final boolean killProcess =
17937                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17938                                final boolean fullUninstall = removed && !replacing;
17939                                if (removed) {
17940                                    if (killProcess) {
17941                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17942                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17943                                                false, true, true, false, fullUninstall, userId,
17944                                                removed ? "pkg removed" : "pkg changed");
17945                                    }
17946                                    final int cmd = killProcess
17947                                            ? IApplicationThread.PACKAGE_REMOVED
17948                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17949                                    sendPackageBroadcastLocked(cmd,
17950                                            new String[] {ssp}, userId);
17951                                    if (fullUninstall) {
17952                                        mAppOpsService.packageRemoved(
17953                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17954
17955                                        // Remove all permissions granted from/to this package
17956                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17957
17958                                        removeTasksByPackageNameLocked(ssp, userId);
17959
17960                                        // Hide the "unsupported display" dialog if necessary.
17961                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17962                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17963                                            mUnsupportedDisplaySizeDialog.dismiss();
17964                                            mUnsupportedDisplaySizeDialog = null;
17965                                        }
17966                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17967                                        mBatteryStatsService.notePackageUninstalled(ssp);
17968                                    }
17969                                } else {
17970                                    if (killProcess) {
17971                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17972                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17973                                                userId, ProcessList.INVALID_ADJ,
17974                                                false, true, true, false, "change " + ssp);
17975                                    }
17976                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17977                                            intent.getStringArrayExtra(
17978                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17979                                }
17980                            }
17981                            break;
17982                        case Intent.ACTION_PACKAGES_SUSPENDED:
17983                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17984                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17985                                    intent.getAction());
17986                            final String[] packageNames = intent.getStringArrayExtra(
17987                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17988                            final int userHandle = intent.getIntExtra(
17989                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17990
17991                            synchronized(ActivityManagerService.this) {
17992                                mRecentTasks.onPackagesSuspendedChanged(
17993                                        packageNames, suspended, userHandle);
17994                            }
17995                            break;
17996                    }
17997                    break;
17998                case Intent.ACTION_PACKAGE_REPLACED:
17999                {
18000                    final Uri data = intent.getData();
18001                    final String ssp;
18002                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18003                        final ApplicationInfo aInfo =
18004                                getPackageManagerInternalLocked().getApplicationInfo(
18005                                        ssp,
18006                                        userId);
18007                        if (aInfo == null) {
18008                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18009                                    + " ssp=" + ssp + " data=" + data);
18010                            return ActivityManager.BROADCAST_SUCCESS;
18011                        }
18012                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18013                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18014                                new String[] {ssp}, userId);
18015                    }
18016                    break;
18017                }
18018                case Intent.ACTION_PACKAGE_ADDED:
18019                {
18020                    // Special case for adding a package: by default turn on compatibility mode.
18021                    Uri data = intent.getData();
18022                    String ssp;
18023                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18024                        final boolean replacing =
18025                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18026                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18027
18028                        try {
18029                            ApplicationInfo ai = AppGlobals.getPackageManager().
18030                                    getApplicationInfo(ssp, 0, 0);
18031                            mBatteryStatsService.notePackageInstalled(ssp,
18032                                    ai != null ? ai.versionCode : 0);
18033                        } catch (RemoteException e) {
18034                        }
18035                    }
18036                    break;
18037                }
18038                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18039                {
18040                    Uri data = intent.getData();
18041                    String ssp;
18042                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18043                        // Hide the "unsupported display" dialog if necessary.
18044                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18045                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18046                            mUnsupportedDisplaySizeDialog.dismiss();
18047                            mUnsupportedDisplaySizeDialog = null;
18048                        }
18049                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18050                    }
18051                    break;
18052                }
18053                case Intent.ACTION_TIMEZONE_CHANGED:
18054                    // If this is the time zone changed action, queue up a message that will reset
18055                    // the timezone of all currently running processes. This message will get
18056                    // queued up before the broadcast happens.
18057                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18058                    break;
18059                case Intent.ACTION_TIME_CHANGED:
18060                    // If the user set the time, let all running processes know.
18061                    final int is24Hour =
18062                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18063                                    : 0;
18064                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18065                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18066                    synchronized (stats) {
18067                        stats.noteCurrentTimeChangedLocked();
18068                    }
18069                    break;
18070                case Intent.ACTION_CLEAR_DNS_CACHE:
18071                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18072                    break;
18073                case Proxy.PROXY_CHANGE_ACTION:
18074                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18075                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18076                    break;
18077                case android.hardware.Camera.ACTION_NEW_PICTURE:
18078                case android.hardware.Camera.ACTION_NEW_VIDEO:
18079                    // These broadcasts are no longer allowed by the system, since they can
18080                    // cause significant thrashing at a crictical point (using the camera).
18081                    // Apps should use JobScehduler to monitor for media provider changes.
18082                    Slog.w(TAG, action + " no longer allowed; dropping from "
18083                            + UserHandle.formatUid(callingUid));
18084                    if (resultTo != null) {
18085                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18086                        try {
18087                            queue.performReceiveLocked(callerApp, resultTo, intent,
18088                                    Activity.RESULT_CANCELED, null, null,
18089                                    false, false, userId);
18090                        } catch (RemoteException e) {
18091                            Slog.w(TAG, "Failure ["
18092                                    + queue.mQueueName + "] sending broadcast result of "
18093                                    + intent, e);
18094
18095                        }
18096                    }
18097                    // Lie; we don't want to crash the app.
18098                    return ActivityManager.BROADCAST_SUCCESS;
18099            }
18100        }
18101
18102        // Add to the sticky list if requested.
18103        if (sticky) {
18104            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18105                    callingPid, callingUid)
18106                    != PackageManager.PERMISSION_GRANTED) {
18107                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18108                        + callingPid + ", uid=" + callingUid
18109                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18110                Slog.w(TAG, msg);
18111                throw new SecurityException(msg);
18112            }
18113            if (requiredPermissions != null && requiredPermissions.length > 0) {
18114                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18115                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18116                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18117            }
18118            if (intent.getComponent() != null) {
18119                throw new SecurityException(
18120                        "Sticky broadcasts can't target a specific component");
18121            }
18122            // We use userId directly here, since the "all" target is maintained
18123            // as a separate set of sticky broadcasts.
18124            if (userId != UserHandle.USER_ALL) {
18125                // But first, if this is not a broadcast to all users, then
18126                // make sure it doesn't conflict with an existing broadcast to
18127                // all users.
18128                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18129                        UserHandle.USER_ALL);
18130                if (stickies != null) {
18131                    ArrayList<Intent> list = stickies.get(intent.getAction());
18132                    if (list != null) {
18133                        int N = list.size();
18134                        int i;
18135                        for (i=0; i<N; i++) {
18136                            if (intent.filterEquals(list.get(i))) {
18137                                throw new IllegalArgumentException(
18138                                        "Sticky broadcast " + intent + " for user "
18139                                        + userId + " conflicts with existing global broadcast");
18140                            }
18141                        }
18142                    }
18143                }
18144            }
18145            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18146            if (stickies == null) {
18147                stickies = new ArrayMap<>();
18148                mStickyBroadcasts.put(userId, stickies);
18149            }
18150            ArrayList<Intent> list = stickies.get(intent.getAction());
18151            if (list == null) {
18152                list = new ArrayList<>();
18153                stickies.put(intent.getAction(), list);
18154            }
18155            final int stickiesCount = list.size();
18156            int i;
18157            for (i = 0; i < stickiesCount; i++) {
18158                if (intent.filterEquals(list.get(i))) {
18159                    // This sticky already exists, replace it.
18160                    list.set(i, new Intent(intent));
18161                    break;
18162                }
18163            }
18164            if (i >= stickiesCount) {
18165                list.add(new Intent(intent));
18166            }
18167        }
18168
18169        int[] users;
18170        if (userId == UserHandle.USER_ALL) {
18171            // Caller wants broadcast to go to all started users.
18172            users = mUserController.getStartedUserArrayLocked();
18173        } else {
18174            // Caller wants broadcast to go to one specific user.
18175            users = new int[] {userId};
18176        }
18177
18178        // Figure out who all will receive this broadcast.
18179        List receivers = null;
18180        List<BroadcastFilter> registeredReceivers = null;
18181        // Need to resolve the intent to interested receivers...
18182        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18183                 == 0) {
18184            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18185        }
18186        if (intent.getComponent() == null) {
18187            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18188                // Query one target user at a time, excluding shell-restricted users
18189                for (int i = 0; i < users.length; i++) {
18190                    if (mUserController.hasUserRestriction(
18191                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18192                        continue;
18193                    }
18194                    List<BroadcastFilter> registeredReceiversForUser =
18195                            mReceiverResolver.queryIntent(intent,
18196                                    resolvedType, false, users[i]);
18197                    if (registeredReceivers == null) {
18198                        registeredReceivers = registeredReceiversForUser;
18199                    } else if (registeredReceiversForUser != null) {
18200                        registeredReceivers.addAll(registeredReceiversForUser);
18201                    }
18202                }
18203            } else {
18204                registeredReceivers = mReceiverResolver.queryIntent(intent,
18205                        resolvedType, false, userId);
18206            }
18207        }
18208
18209        final boolean replacePending =
18210                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18211
18212        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18213                + " replacePending=" + replacePending);
18214
18215        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18216        if (!ordered && NR > 0) {
18217            // If we are not serializing this broadcast, then send the
18218            // registered receivers separately so they don't wait for the
18219            // components to be launched.
18220            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18221            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18222                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18223                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18224                    resultExtras, ordered, sticky, false, userId);
18225            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18226            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18227            if (!replaced) {
18228                queue.enqueueParallelBroadcastLocked(r);
18229                queue.scheduleBroadcastsLocked();
18230            }
18231            registeredReceivers = null;
18232            NR = 0;
18233        }
18234
18235        // Merge into one list.
18236        int ir = 0;
18237        if (receivers != null) {
18238            // A special case for PACKAGE_ADDED: do not allow the package
18239            // being added to see this broadcast.  This prevents them from
18240            // using this as a back door to get run as soon as they are
18241            // installed.  Maybe in the future we want to have a special install
18242            // broadcast or such for apps, but we'd like to deliberately make
18243            // this decision.
18244            String skipPackages[] = null;
18245            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18246                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18247                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18248                Uri data = intent.getData();
18249                if (data != null) {
18250                    String pkgName = data.getSchemeSpecificPart();
18251                    if (pkgName != null) {
18252                        skipPackages = new String[] { pkgName };
18253                    }
18254                }
18255            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18256                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18257            }
18258            if (skipPackages != null && (skipPackages.length > 0)) {
18259                for (String skipPackage : skipPackages) {
18260                    if (skipPackage != null) {
18261                        int NT = receivers.size();
18262                        for (int it=0; it<NT; it++) {
18263                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18264                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18265                                receivers.remove(it);
18266                                it--;
18267                                NT--;
18268                            }
18269                        }
18270                    }
18271                }
18272            }
18273
18274            int NT = receivers != null ? receivers.size() : 0;
18275            int it = 0;
18276            ResolveInfo curt = null;
18277            BroadcastFilter curr = null;
18278            while (it < NT && ir < NR) {
18279                if (curt == null) {
18280                    curt = (ResolveInfo)receivers.get(it);
18281                }
18282                if (curr == null) {
18283                    curr = registeredReceivers.get(ir);
18284                }
18285                if (curr.getPriority() >= curt.priority) {
18286                    // Insert this broadcast record into the final list.
18287                    receivers.add(it, curr);
18288                    ir++;
18289                    curr = null;
18290                    it++;
18291                    NT++;
18292                } else {
18293                    // Skip to the next ResolveInfo in the final list.
18294                    it++;
18295                    curt = null;
18296                }
18297            }
18298        }
18299        while (ir < NR) {
18300            if (receivers == null) {
18301                receivers = new ArrayList();
18302            }
18303            receivers.add(registeredReceivers.get(ir));
18304            ir++;
18305        }
18306
18307        if ((receivers != null && receivers.size() > 0)
18308                || resultTo != null) {
18309            BroadcastQueue queue = broadcastQueueForIntent(intent);
18310            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18311                    callerPackage, callingPid, callingUid, resolvedType,
18312                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18313                    resultData, resultExtras, ordered, sticky, false, userId);
18314
18315            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18316                    + ": prev had " + queue.mOrderedBroadcasts.size());
18317            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18318                    "Enqueueing broadcast " + r.intent.getAction());
18319
18320            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18321            if (!replaced) {
18322                queue.enqueueOrderedBroadcastLocked(r);
18323                queue.scheduleBroadcastsLocked();
18324            }
18325        } else {
18326            // There was nobody interested in the broadcast, but we still want to record
18327            // that it happened.
18328            if (intent.getComponent() == null && intent.getPackage() == null
18329                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18330                // This was an implicit broadcast... let's record it for posterity.
18331                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18332            }
18333        }
18334
18335        return ActivityManager.BROADCAST_SUCCESS;
18336    }
18337
18338    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18339            int skipCount, long dispatchTime) {
18340        final long now = SystemClock.elapsedRealtime();
18341        if (mCurBroadcastStats == null ||
18342                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18343            mLastBroadcastStats = mCurBroadcastStats;
18344            if (mLastBroadcastStats != null) {
18345                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18346                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18347            }
18348            mCurBroadcastStats = new BroadcastStats();
18349        }
18350        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18351    }
18352
18353    final Intent verifyBroadcastLocked(Intent intent) {
18354        // Refuse possible leaked file descriptors
18355        if (intent != null && intent.hasFileDescriptors() == true) {
18356            throw new IllegalArgumentException("File descriptors passed in Intent");
18357        }
18358
18359        int flags = intent.getFlags();
18360
18361        if (!mProcessesReady) {
18362            // if the caller really truly claims to know what they're doing, go
18363            // ahead and allow the broadcast without launching any receivers
18364            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18365                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18366            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18367                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18368                        + " before boot completion");
18369                throw new IllegalStateException("Cannot broadcast before boot completed");
18370            }
18371        }
18372
18373        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18374            throw new IllegalArgumentException(
18375                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18376        }
18377
18378        return intent;
18379    }
18380
18381    public final int broadcastIntent(IApplicationThread caller,
18382            Intent intent, String resolvedType, IIntentReceiver resultTo,
18383            int resultCode, String resultData, Bundle resultExtras,
18384            String[] requiredPermissions, int appOp, Bundle bOptions,
18385            boolean serialized, boolean sticky, int userId) {
18386        enforceNotIsolatedCaller("broadcastIntent");
18387        synchronized(this) {
18388            intent = verifyBroadcastLocked(intent);
18389
18390            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18391            final int callingPid = Binder.getCallingPid();
18392            final int callingUid = Binder.getCallingUid();
18393            final long origId = Binder.clearCallingIdentity();
18394            int res = broadcastIntentLocked(callerApp,
18395                    callerApp != null ? callerApp.info.packageName : null,
18396                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18397                    requiredPermissions, appOp, bOptions, serialized, sticky,
18398                    callingPid, callingUid, userId);
18399            Binder.restoreCallingIdentity(origId);
18400            return res;
18401        }
18402    }
18403
18404
18405    int broadcastIntentInPackage(String packageName, int uid,
18406            Intent intent, String resolvedType, IIntentReceiver resultTo,
18407            int resultCode, String resultData, Bundle resultExtras,
18408            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18409            int userId) {
18410        synchronized(this) {
18411            intent = verifyBroadcastLocked(intent);
18412
18413            final long origId = Binder.clearCallingIdentity();
18414            String[] requiredPermissions = requiredPermission == null ? null
18415                    : new String[] {requiredPermission};
18416            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18417                    resultTo, resultCode, resultData, resultExtras,
18418                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18419                    sticky, -1, uid, userId);
18420            Binder.restoreCallingIdentity(origId);
18421            return res;
18422        }
18423    }
18424
18425    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18426        // Refuse possible leaked file descriptors
18427        if (intent != null && intent.hasFileDescriptors() == true) {
18428            throw new IllegalArgumentException("File descriptors passed in Intent");
18429        }
18430
18431        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18432                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18433
18434        synchronized(this) {
18435            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18436                    != PackageManager.PERMISSION_GRANTED) {
18437                String msg = "Permission Denial: unbroadcastIntent() from pid="
18438                        + Binder.getCallingPid()
18439                        + ", uid=" + Binder.getCallingUid()
18440                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18441                Slog.w(TAG, msg);
18442                throw new SecurityException(msg);
18443            }
18444            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18445            if (stickies != null) {
18446                ArrayList<Intent> list = stickies.get(intent.getAction());
18447                if (list != null) {
18448                    int N = list.size();
18449                    int i;
18450                    for (i=0; i<N; i++) {
18451                        if (intent.filterEquals(list.get(i))) {
18452                            list.remove(i);
18453                            break;
18454                        }
18455                    }
18456                    if (list.size() <= 0) {
18457                        stickies.remove(intent.getAction());
18458                    }
18459                }
18460                if (stickies.size() <= 0) {
18461                    mStickyBroadcasts.remove(userId);
18462                }
18463            }
18464        }
18465    }
18466
18467    void backgroundServicesFinishedLocked(int userId) {
18468        for (BroadcastQueue queue : mBroadcastQueues) {
18469            queue.backgroundServicesFinishedLocked(userId);
18470        }
18471    }
18472
18473    public void finishReceiver(IBinder who, int resultCode, String resultData,
18474            Bundle resultExtras, boolean resultAbort, int flags) {
18475        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18476
18477        // Refuse possible leaked file descriptors
18478        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18479            throw new IllegalArgumentException("File descriptors passed in Bundle");
18480        }
18481
18482        final long origId = Binder.clearCallingIdentity();
18483        try {
18484            boolean doNext = false;
18485            BroadcastRecord r;
18486
18487            synchronized(this) {
18488                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18489                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18490                r = queue.getMatchingOrderedReceiver(who);
18491                if (r != null) {
18492                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18493                        resultData, resultExtras, resultAbort, true);
18494                }
18495            }
18496
18497            if (doNext) {
18498                r.queue.processNextBroadcast(false);
18499            }
18500            trimApplications();
18501        } finally {
18502            Binder.restoreCallingIdentity(origId);
18503        }
18504    }
18505
18506    // =========================================================
18507    // INSTRUMENTATION
18508    // =========================================================
18509
18510    public boolean startInstrumentation(ComponentName className,
18511            String profileFile, int flags, Bundle arguments,
18512            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18513            int userId, String abiOverride) {
18514        enforceNotIsolatedCaller("startInstrumentation");
18515        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18516                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18517        // Refuse possible leaked file descriptors
18518        if (arguments != null && arguments.hasFileDescriptors()) {
18519            throw new IllegalArgumentException("File descriptors passed in Bundle");
18520        }
18521
18522        synchronized(this) {
18523            InstrumentationInfo ii = null;
18524            ApplicationInfo ai = null;
18525            try {
18526                ii = mContext.getPackageManager().getInstrumentationInfo(
18527                    className, STOCK_PM_FLAGS);
18528                ai = AppGlobals.getPackageManager().getApplicationInfo(
18529                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18530            } catch (PackageManager.NameNotFoundException e) {
18531            } catch (RemoteException e) {
18532            }
18533            if (ii == null) {
18534                reportStartInstrumentationFailureLocked(watcher, className,
18535                        "Unable to find instrumentation info for: " + className);
18536                return false;
18537            }
18538            if (ai == null) {
18539                reportStartInstrumentationFailureLocked(watcher, className,
18540                        "Unable to find instrumentation target package: " + ii.targetPackage);
18541                return false;
18542            }
18543            if (!ai.hasCode()) {
18544                reportStartInstrumentationFailureLocked(watcher, className,
18545                        "Instrumentation target has no code: " + ii.targetPackage);
18546                return false;
18547            }
18548
18549            int match = mContext.getPackageManager().checkSignatures(
18550                    ii.targetPackage, ii.packageName);
18551            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18552                String msg = "Permission Denial: starting instrumentation "
18553                        + className + " from pid="
18554                        + Binder.getCallingPid()
18555                        + ", uid=" + Binder.getCallingPid()
18556                        + " not allowed because package " + ii.packageName
18557                        + " does not have a signature matching the target "
18558                        + ii.targetPackage;
18559                reportStartInstrumentationFailureLocked(watcher, className, msg);
18560                throw new SecurityException(msg);
18561            }
18562
18563            final long origId = Binder.clearCallingIdentity();
18564            // Instrumentation can kill and relaunch even persistent processes
18565            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18566                    "start instr");
18567            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18568            app.instrumentationClass = className;
18569            app.instrumentationInfo = ai;
18570            app.instrumentationProfileFile = profileFile;
18571            app.instrumentationArguments = arguments;
18572            app.instrumentationWatcher = watcher;
18573            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18574            app.instrumentationResultClass = className;
18575            Binder.restoreCallingIdentity(origId);
18576        }
18577
18578        return true;
18579    }
18580
18581    /**
18582     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18583     * error to the logs, but if somebody is watching, send the report there too.  This enables
18584     * the "am" command to report errors with more information.
18585     *
18586     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18587     * @param cn The component name of the instrumentation.
18588     * @param report The error report.
18589     */
18590    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18591            ComponentName cn, String report) {
18592        Slog.w(TAG, report);
18593        if (watcher != null) {
18594            Bundle results = new Bundle();
18595            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18596            results.putString("Error", report);
18597            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18598        }
18599    }
18600
18601    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18602        if (app.instrumentationWatcher != null) {
18603            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18604                    app.instrumentationClass, resultCode, results);
18605        }
18606
18607        // Can't call out of the system process with a lock held, so post a message.
18608        if (app.instrumentationUiAutomationConnection != null) {
18609            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18610                    app.instrumentationUiAutomationConnection).sendToTarget();
18611        }
18612
18613        app.instrumentationWatcher = null;
18614        app.instrumentationUiAutomationConnection = null;
18615        app.instrumentationClass = null;
18616        app.instrumentationInfo = null;
18617        app.instrumentationProfileFile = null;
18618        app.instrumentationArguments = null;
18619
18620        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18621                "finished inst");
18622    }
18623
18624    public void finishInstrumentation(IApplicationThread target,
18625            int resultCode, Bundle results) {
18626        int userId = UserHandle.getCallingUserId();
18627        // Refuse possible leaked file descriptors
18628        if (results != null && results.hasFileDescriptors()) {
18629            throw new IllegalArgumentException("File descriptors passed in Intent");
18630        }
18631
18632        synchronized(this) {
18633            ProcessRecord app = getRecordForAppLocked(target);
18634            if (app == null) {
18635                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18636                return;
18637            }
18638            final long origId = Binder.clearCallingIdentity();
18639            finishInstrumentationLocked(app, resultCode, results);
18640            Binder.restoreCallingIdentity(origId);
18641        }
18642    }
18643
18644    // =========================================================
18645    // CONFIGURATION
18646    // =========================================================
18647
18648    public ConfigurationInfo getDeviceConfigurationInfo() {
18649        ConfigurationInfo config = new ConfigurationInfo();
18650        synchronized (this) {
18651            config.reqTouchScreen = mConfiguration.touchscreen;
18652            config.reqKeyboardType = mConfiguration.keyboard;
18653            config.reqNavigation = mConfiguration.navigation;
18654            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18655                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18656                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18657            }
18658            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18659                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18660                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18661            }
18662            config.reqGlEsVersion = GL_ES_VERSION;
18663        }
18664        return config;
18665    }
18666
18667    ActivityStack getFocusedStack() {
18668        return mStackSupervisor.getFocusedStack();
18669    }
18670
18671    @Override
18672    public int getFocusedStackId() throws RemoteException {
18673        ActivityStack focusedStack = getFocusedStack();
18674        if (focusedStack != null) {
18675            return focusedStack.getStackId();
18676        }
18677        return -1;
18678    }
18679
18680    public Configuration getConfiguration() {
18681        Configuration ci;
18682        synchronized(this) {
18683            ci = new Configuration(mConfiguration);
18684            ci.userSetLocale = false;
18685        }
18686        return ci;
18687    }
18688
18689    @Override
18690    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18691        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18692        synchronized (this) {
18693            mSuppressResizeConfigChanges = suppress;
18694        }
18695    }
18696
18697    @Override
18698    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18699        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18700        if (fromStackId == HOME_STACK_ID) {
18701            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18702        }
18703        synchronized (this) {
18704            final long origId = Binder.clearCallingIdentity();
18705            try {
18706                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18707            } finally {
18708                Binder.restoreCallingIdentity(origId);
18709            }
18710        }
18711    }
18712
18713    @Override
18714    public void updatePersistentConfiguration(Configuration values) {
18715        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18716                "updateConfiguration()");
18717        enforceWriteSettingsPermission("updateConfiguration()");
18718        if (values == null) {
18719            throw new NullPointerException("Configuration must not be null");
18720        }
18721
18722        int userId = UserHandle.getCallingUserId();
18723
18724        synchronized(this) {
18725            updatePersistentConfigurationLocked(values, userId);
18726        }
18727    }
18728
18729    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18730        final long origId = Binder.clearCallingIdentity();
18731        try {
18732            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18733        } finally {
18734            Binder.restoreCallingIdentity(origId);
18735        }
18736    }
18737
18738    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18739        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18740                FONT_SCALE, 1.0f, userId);
18741        if (mConfiguration.fontScale != scaleFactor) {
18742            final Configuration configuration = mWindowManager.computeNewConfiguration();
18743            configuration.fontScale = scaleFactor;
18744            synchronized (this) {
18745                updatePersistentConfigurationLocked(configuration, userId);
18746            }
18747        }
18748    }
18749
18750    private void enforceWriteSettingsPermission(String func) {
18751        int uid = Binder.getCallingUid();
18752        if (uid == Process.ROOT_UID) {
18753            return;
18754        }
18755
18756        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18757                Settings.getPackageNameForUid(mContext, uid), false)) {
18758            return;
18759        }
18760
18761        String msg = "Permission Denial: " + func + " from pid="
18762                + Binder.getCallingPid()
18763                + ", uid=" + uid
18764                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18765        Slog.w(TAG, msg);
18766        throw new SecurityException(msg);
18767    }
18768
18769    public void updateConfiguration(Configuration values) {
18770        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18771                "updateConfiguration()");
18772
18773        synchronized(this) {
18774            if (values == null && mWindowManager != null) {
18775                // sentinel: fetch the current configuration from the window manager
18776                values = mWindowManager.computeNewConfiguration();
18777            }
18778
18779            if (mWindowManager != null) {
18780                mProcessList.applyDisplaySize(mWindowManager);
18781            }
18782
18783            final long origId = Binder.clearCallingIdentity();
18784            if (values != null) {
18785                Settings.System.clearConfiguration(values);
18786            }
18787            updateConfigurationLocked(values, null, false);
18788            Binder.restoreCallingIdentity(origId);
18789        }
18790    }
18791
18792    void updateUserConfigurationLocked() {
18793        Configuration configuration = new Configuration(mConfiguration);
18794        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18795                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18796        updateConfigurationLocked(configuration, null, false);
18797    }
18798
18799    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18800            boolean initLocale) {
18801        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18802    }
18803
18804    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18805            boolean initLocale, boolean deferResume) {
18806        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18807        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18808                UserHandle.USER_NULL, deferResume);
18809    }
18810
18811    // To cache the list of supported system locales
18812    private String[] mSupportedSystemLocales = null;
18813
18814    /**
18815     * Do either or both things: (1) change the current configuration, and (2)
18816     * make sure the given activity is running with the (now) current
18817     * configuration.  Returns true if the activity has been left running, or
18818     * false if <var>starting</var> is being destroyed to match the new
18819     * configuration.
18820     *
18821     * @param userId is only used when persistent parameter is set to true to persist configuration
18822     *               for that particular user
18823     */
18824    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18825            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18826        int changes = 0;
18827
18828        if (mWindowManager != null) {
18829            mWindowManager.deferSurfaceLayout();
18830        }
18831        if (values != null) {
18832            Configuration newConfig = new Configuration(mConfiguration);
18833            changes = newConfig.updateFrom(values);
18834            if (changes != 0) {
18835                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18836                        "Updating configuration to: " + values);
18837
18838                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18839
18840                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18841                    final LocaleList locales = values.getLocales();
18842                    int bestLocaleIndex = 0;
18843                    if (locales.size() > 1) {
18844                        if (mSupportedSystemLocales == null) {
18845                            mSupportedSystemLocales =
18846                                    Resources.getSystem().getAssets().getLocales();
18847                        }
18848                        bestLocaleIndex = Math.max(0,
18849                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18850                    }
18851                    SystemProperties.set("persist.sys.locale",
18852                            locales.get(bestLocaleIndex).toLanguageTag());
18853                    LocaleList.setDefault(locales, bestLocaleIndex);
18854                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18855                            locales.get(bestLocaleIndex)));
18856                }
18857
18858                mConfigurationSeq++;
18859                if (mConfigurationSeq <= 0) {
18860                    mConfigurationSeq = 1;
18861                }
18862                newConfig.seq = mConfigurationSeq;
18863                mConfiguration = newConfig;
18864                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18865                mUsageStatsService.reportConfigurationChange(newConfig,
18866                        mUserController.getCurrentUserIdLocked());
18867                //mUsageStatsService.noteStartConfig(newConfig);
18868
18869                final Configuration configCopy = new Configuration(mConfiguration);
18870
18871                // TODO: If our config changes, should we auto dismiss any currently
18872                // showing dialogs?
18873                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18874
18875                AttributeCache ac = AttributeCache.instance();
18876                if (ac != null) {
18877                    ac.updateConfiguration(configCopy);
18878                }
18879
18880                // Make sure all resources in our process are updated
18881                // right now, so that anyone who is going to retrieve
18882                // resource values after we return will be sure to get
18883                // the new ones.  This is especially important during
18884                // boot, where the first config change needs to guarantee
18885                // all resources have that config before following boot
18886                // code is executed.
18887                mSystemThread.applyConfigurationToResources(configCopy);
18888
18889                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18890                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18891                    msg.obj = new Configuration(configCopy);
18892                    msg.arg1 = userId;
18893                    mHandler.sendMessage(msg);
18894                }
18895
18896                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18897                if (isDensityChange) {
18898                    // Reset the unsupported display size dialog.
18899                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18900
18901                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18902                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18903                }
18904
18905                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18906                    ProcessRecord app = mLruProcesses.get(i);
18907                    try {
18908                        if (app.thread != null) {
18909                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18910                                    + app.processName + " new config " + mConfiguration);
18911                            app.thread.scheduleConfigurationChanged(configCopy);
18912                        }
18913                    } catch (Exception e) {
18914                    }
18915                }
18916                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18917                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18918                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18919                        | Intent.FLAG_RECEIVER_FOREGROUND);
18920                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18921                        null, AppOpsManager.OP_NONE, null, false, false,
18922                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18923                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18924                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18925                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18926                    if (!mProcessesReady) {
18927                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18928                    }
18929                    broadcastIntentLocked(null, null, intent,
18930                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18931                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18932                }
18933            }
18934            // Update the configuration with WM first and check if any of the stacks need to be
18935            // resized due to the configuration change. If so, resize the stacks now and do any
18936            // relaunches if necessary. This way we don't need to relaunch again below in
18937            // ensureActivityConfigurationLocked().
18938            if (mWindowManager != null) {
18939                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18940                if (resizedStacks != null) {
18941                    for (int stackId : resizedStacks) {
18942                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18943                        mStackSupervisor.resizeStackLocked(
18944                                stackId, newBounds, null, null, false, false, deferResume);
18945                    }
18946                }
18947            }
18948        }
18949
18950        boolean kept = true;
18951        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18952        // mainStack is null during startup.
18953        if (mainStack != null) {
18954            if (changes != 0 && starting == null) {
18955                // If the configuration changed, and the caller is not already
18956                // in the process of starting an activity, then find the top
18957                // activity to check if its configuration needs to change.
18958                starting = mainStack.topRunningActivityLocked();
18959            }
18960
18961            if (starting != null) {
18962                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18963                // And we need to make sure at this point that all other activities
18964                // are made visible with the correct configuration.
18965                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18966                        !PRESERVE_WINDOWS);
18967            }
18968        }
18969        if (mWindowManager != null) {
18970            mWindowManager.continueSurfaceLayout();
18971        }
18972        return kept;
18973    }
18974
18975    /**
18976     * Decide based on the configuration whether we should shouw the ANR,
18977     * crash, etc dialogs.  The idea is that if there is no affordence to
18978     * press the on-screen buttons, or the user experience would be more
18979     * greatly impacted than the crash itself, we shouldn't show the dialog.
18980     *
18981     * A thought: SystemUI might also want to get told about this, the Power
18982     * dialog / global actions also might want different behaviors.
18983     */
18984    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18985        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18986                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18987                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18988        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18989        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18990                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18991        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18992    }
18993
18994    @Override
18995    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18996        synchronized (this) {
18997            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18998            if (srec != null) {
18999                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19000            }
19001        }
19002        return false;
19003    }
19004
19005    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19006            Intent resultData) {
19007
19008        synchronized (this) {
19009            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19010            if (r != null) {
19011                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19012            }
19013            return false;
19014        }
19015    }
19016
19017    public int getLaunchedFromUid(IBinder activityToken) {
19018        ActivityRecord srec;
19019        synchronized (this) {
19020            srec = ActivityRecord.forTokenLocked(activityToken);
19021        }
19022        if (srec == null) {
19023            return -1;
19024        }
19025        return srec.launchedFromUid;
19026    }
19027
19028    public String getLaunchedFromPackage(IBinder activityToken) {
19029        ActivityRecord srec;
19030        synchronized (this) {
19031            srec = ActivityRecord.forTokenLocked(activityToken);
19032        }
19033        if (srec == null) {
19034            return null;
19035        }
19036        return srec.launchedFromPackage;
19037    }
19038
19039    // =========================================================
19040    // LIFETIME MANAGEMENT
19041    // =========================================================
19042
19043    // Returns which broadcast queue the app is the current [or imminent] receiver
19044    // on, or 'null' if the app is not an active broadcast recipient.
19045    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19046        BroadcastRecord r = app.curReceiver;
19047        if (r != null) {
19048            return r.queue;
19049        }
19050
19051        // It's not the current receiver, but it might be starting up to become one
19052        synchronized (this) {
19053            for (BroadcastQueue queue : mBroadcastQueues) {
19054                r = queue.mPendingBroadcast;
19055                if (r != null && r.curApp == app) {
19056                    // found it; report which queue it's in
19057                    return queue;
19058                }
19059            }
19060        }
19061
19062        return null;
19063    }
19064
19065    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19066            int targetUid, ComponentName targetComponent, String targetProcess) {
19067        if (!mTrackingAssociations) {
19068            return null;
19069        }
19070        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19071                = mAssociations.get(targetUid);
19072        if (components == null) {
19073            components = new ArrayMap<>();
19074            mAssociations.put(targetUid, components);
19075        }
19076        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19077        if (sourceUids == null) {
19078            sourceUids = new SparseArray<>();
19079            components.put(targetComponent, sourceUids);
19080        }
19081        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19082        if (sourceProcesses == null) {
19083            sourceProcesses = new ArrayMap<>();
19084            sourceUids.put(sourceUid, sourceProcesses);
19085        }
19086        Association ass = sourceProcesses.get(sourceProcess);
19087        if (ass == null) {
19088            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19089                    targetProcess);
19090            sourceProcesses.put(sourceProcess, ass);
19091        }
19092        ass.mCount++;
19093        ass.mNesting++;
19094        if (ass.mNesting == 1) {
19095            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19096            ass.mLastState = sourceState;
19097        }
19098        return ass;
19099    }
19100
19101    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19102            ComponentName targetComponent) {
19103        if (!mTrackingAssociations) {
19104            return;
19105        }
19106        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19107                = mAssociations.get(targetUid);
19108        if (components == null) {
19109            return;
19110        }
19111        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19112        if (sourceUids == null) {
19113            return;
19114        }
19115        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19116        if (sourceProcesses == null) {
19117            return;
19118        }
19119        Association ass = sourceProcesses.get(sourceProcess);
19120        if (ass == null || ass.mNesting <= 0) {
19121            return;
19122        }
19123        ass.mNesting--;
19124        if (ass.mNesting == 0) {
19125            long uptime = SystemClock.uptimeMillis();
19126            ass.mTime += uptime - ass.mStartTime;
19127            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19128                    += uptime - ass.mLastStateUptime;
19129            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19130        }
19131    }
19132
19133    private void noteUidProcessState(final int uid, final int state) {
19134        mBatteryStatsService.noteUidProcessState(uid, state);
19135        if (mTrackingAssociations) {
19136            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19137                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19138                        = mAssociations.valueAt(i1);
19139                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19140                    SparseArray<ArrayMap<String, Association>> sourceUids
19141                            = targetComponents.valueAt(i2);
19142                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19143                    if (sourceProcesses != null) {
19144                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19145                            Association ass = sourceProcesses.valueAt(i4);
19146                            if (ass.mNesting >= 1) {
19147                                // currently associated
19148                                long uptime = SystemClock.uptimeMillis();
19149                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19150                                        += uptime - ass.mLastStateUptime;
19151                                ass.mLastState = state;
19152                                ass.mLastStateUptime = uptime;
19153                            }
19154                        }
19155                    }
19156                }
19157            }
19158        }
19159    }
19160
19161    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19162            boolean doingAll, long now) {
19163        if (mAdjSeq == app.adjSeq) {
19164            // This adjustment has already been computed.
19165            return app.curRawAdj;
19166        }
19167
19168        if (app.thread == null) {
19169            app.adjSeq = mAdjSeq;
19170            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19171            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19172            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19173        }
19174
19175        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19176        app.adjSource = null;
19177        app.adjTarget = null;
19178        app.empty = false;
19179        app.cached = false;
19180
19181        final int activitiesSize = app.activities.size();
19182
19183        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19184            // The max adjustment doesn't allow this app to be anything
19185            // below foreground, so it is not worth doing work for it.
19186            app.adjType = "fixed";
19187            app.adjSeq = mAdjSeq;
19188            app.curRawAdj = app.maxAdj;
19189            app.foregroundActivities = false;
19190            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19191            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19192            // System processes can do UI, and when they do we want to have
19193            // them trim their memory after the user leaves the UI.  To
19194            // facilitate this, here we need to determine whether or not it
19195            // is currently showing UI.
19196            app.systemNoUi = true;
19197            if (app == TOP_APP || app.hasTopUi) {
19198                app.systemNoUi = false;
19199                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19200                app.adjType = "pers-top-activity";
19201            } else if (activitiesSize > 0) {
19202                for (int j = 0; j < activitiesSize; j++) {
19203                    final ActivityRecord r = app.activities.get(j);
19204                    if (r.visible) {
19205                        app.systemNoUi = false;
19206                    }
19207                }
19208            }
19209            if (!app.systemNoUi) {
19210                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19211            }
19212            return (app.curAdj=app.maxAdj);
19213        }
19214
19215        app.systemNoUi = false;
19216
19217        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19218
19219        // Determine the importance of the process, starting with most
19220        // important to least, and assign an appropriate OOM adjustment.
19221        int adj;
19222        int schedGroup;
19223        int procState;
19224        boolean foregroundActivities = false;
19225        BroadcastQueue queue;
19226        if (app == TOP_APP || app.hasTopUi) {
19227            // The last app on the list is the foreground app.
19228            adj = ProcessList.FOREGROUND_APP_ADJ;
19229            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19230            app.adjType = "top-activity";
19231            foregroundActivities = true;
19232            procState = PROCESS_STATE_CUR_TOP;
19233        } else if (app.instrumentationClass != null) {
19234            // Don't want to kill running instrumentation.
19235            adj = ProcessList.FOREGROUND_APP_ADJ;
19236            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19237            app.adjType = "instrumentation";
19238            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19239        } else if ((queue = isReceivingBroadcast(app)) != null) {
19240            // An app that is currently receiving a broadcast also
19241            // counts as being in the foreground for OOM killer purposes.
19242            // It's placed in a sched group based on the nature of the
19243            // broadcast as reflected by which queue it's active in.
19244            adj = ProcessList.FOREGROUND_APP_ADJ;
19245            schedGroup = (queue == mFgBroadcastQueue)
19246                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19247            app.adjType = "broadcast";
19248            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19249        } else if (app.executingServices.size() > 0) {
19250            // An app that is currently executing a service callback also
19251            // counts as being in the foreground.
19252            adj = ProcessList.FOREGROUND_APP_ADJ;
19253            schedGroup = app.execServicesFg ?
19254                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19255            app.adjType = "exec-service";
19256            procState = ActivityManager.PROCESS_STATE_SERVICE;
19257            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19258        } else {
19259            // As far as we know the process is empty.  We may change our mind later.
19260            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19261            // At this point we don't actually know the adjustment.  Use the cached adj
19262            // value that the caller wants us to.
19263            adj = cachedAdj;
19264            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19265            app.cached = true;
19266            app.empty = true;
19267            app.adjType = "cch-empty";
19268        }
19269
19270        // Examine all activities if not already foreground.
19271        if (!foregroundActivities && activitiesSize > 0) {
19272            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19273            for (int j = 0; j < activitiesSize; j++) {
19274                final ActivityRecord r = app.activities.get(j);
19275                if (r.app != app) {
19276                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19277                            + " instead of expected " + app);
19278                    if (r.app == null || (r.app.uid == app.uid)) {
19279                        // Only fix things up when they look sane
19280                        r.app = app;
19281                    } else {
19282                        continue;
19283                    }
19284                }
19285                if (r.visible) {
19286                    // App has a visible activity; only upgrade adjustment.
19287                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19288                        adj = ProcessList.VISIBLE_APP_ADJ;
19289                        app.adjType = "visible";
19290                    }
19291                    if (procState > PROCESS_STATE_CUR_TOP) {
19292                        procState = PROCESS_STATE_CUR_TOP;
19293                    }
19294                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19295                    app.cached = false;
19296                    app.empty = false;
19297                    foregroundActivities = true;
19298                    if (r.task != null && minLayer > 0) {
19299                        final int layer = r.task.mLayerRank;
19300                        if (layer >= 0 && minLayer > layer) {
19301                            minLayer = layer;
19302                        }
19303                    }
19304                    break;
19305                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19306                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19307                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19308                        app.adjType = "pausing";
19309                    }
19310                    if (procState > PROCESS_STATE_CUR_TOP) {
19311                        procState = PROCESS_STATE_CUR_TOP;
19312                    }
19313                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19314                    app.cached = false;
19315                    app.empty = false;
19316                    foregroundActivities = true;
19317                } else if (r.state == ActivityState.STOPPING) {
19318                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19319                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19320                        app.adjType = "stopping";
19321                    }
19322                    // For the process state, we will at this point consider the
19323                    // process to be cached.  It will be cached either as an activity
19324                    // or empty depending on whether the activity is finishing.  We do
19325                    // this so that we can treat the process as cached for purposes of
19326                    // memory trimming (determing current memory level, trim command to
19327                    // send to process) since there can be an arbitrary number of stopping
19328                    // processes and they should soon all go into the cached state.
19329                    if (!r.finishing) {
19330                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19331                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19332                        }
19333                    }
19334                    app.cached = false;
19335                    app.empty = false;
19336                    foregroundActivities = true;
19337                } else {
19338                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19339                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19340                        app.adjType = "cch-act";
19341                    }
19342                }
19343            }
19344            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19345                adj += minLayer;
19346            }
19347        }
19348
19349        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19350                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19351            if (app.foregroundServices) {
19352                // The user is aware of this app, so make it visible.
19353                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19354                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19355                app.cached = false;
19356                app.adjType = "fg-service";
19357                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19358            } else if (app.forcingToForeground != null) {
19359                // The user is aware of this app, so make it visible.
19360                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19361                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19362                app.cached = false;
19363                app.adjType = "force-fg";
19364                app.adjSource = app.forcingToForeground;
19365                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19366            }
19367        }
19368
19369        if (app == mHeavyWeightProcess) {
19370            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19371                // We don't want to kill the current heavy-weight process.
19372                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19373                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19374                app.cached = false;
19375                app.adjType = "heavy";
19376            }
19377            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19378                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19379            }
19380        }
19381
19382        if (app == mHomeProcess) {
19383            if (adj > ProcessList.HOME_APP_ADJ) {
19384                // This process is hosting what we currently consider to be the
19385                // home app, so we don't want to let it go into the background.
19386                adj = ProcessList.HOME_APP_ADJ;
19387                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19388                app.cached = false;
19389                app.adjType = "home";
19390            }
19391            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19392                procState = ActivityManager.PROCESS_STATE_HOME;
19393            }
19394        }
19395
19396        if (app == mPreviousProcess && app.activities.size() > 0) {
19397            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19398                // This was the previous process that showed UI to the user.
19399                // We want to try to keep it around more aggressively, to give
19400                // a good experience around switching between two apps.
19401                adj = ProcessList.PREVIOUS_APP_ADJ;
19402                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19403                app.cached = false;
19404                app.adjType = "previous";
19405            }
19406            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19407                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19408            }
19409        }
19410
19411        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19412                + " reason=" + app.adjType);
19413
19414        // By default, we use the computed adjustment.  It may be changed if
19415        // there are applications dependent on our services or providers, but
19416        // this gives us a baseline and makes sure we don't get into an
19417        // infinite recursion.
19418        app.adjSeq = mAdjSeq;
19419        app.curRawAdj = adj;
19420        app.hasStartedServices = false;
19421
19422        if (mBackupTarget != null && app == mBackupTarget.app) {
19423            // If possible we want to avoid killing apps while they're being backed up
19424            if (adj > ProcessList.BACKUP_APP_ADJ) {
19425                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19426                adj = ProcessList.BACKUP_APP_ADJ;
19427                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19428                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19429                }
19430                app.adjType = "backup";
19431                app.cached = false;
19432            }
19433            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19434                procState = ActivityManager.PROCESS_STATE_BACKUP;
19435            }
19436        }
19437
19438        boolean mayBeTop = false;
19439
19440        for (int is = app.services.size()-1;
19441                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19442                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19443                        || procState > ActivityManager.PROCESS_STATE_TOP);
19444                is--) {
19445            ServiceRecord s = app.services.valueAt(is);
19446            if (s.startRequested) {
19447                app.hasStartedServices = true;
19448                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19449                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19450                }
19451                if (app.hasShownUi && app != mHomeProcess) {
19452                    // If this process has shown some UI, let it immediately
19453                    // go to the LRU list because it may be pretty heavy with
19454                    // UI stuff.  We'll tag it with a label just to help
19455                    // debug and understand what is going on.
19456                    if (adj > ProcessList.SERVICE_ADJ) {
19457                        app.adjType = "cch-started-ui-services";
19458                    }
19459                } else {
19460                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19461                        // This service has seen some activity within
19462                        // recent memory, so we will keep its process ahead
19463                        // of the background processes.
19464                        if (adj > ProcessList.SERVICE_ADJ) {
19465                            adj = ProcessList.SERVICE_ADJ;
19466                            app.adjType = "started-services";
19467                            app.cached = false;
19468                        }
19469                    }
19470                    // If we have let the service slide into the background
19471                    // state, still have some text describing what it is doing
19472                    // even though the service no longer has an impact.
19473                    if (adj > ProcessList.SERVICE_ADJ) {
19474                        app.adjType = "cch-started-services";
19475                    }
19476                }
19477            }
19478
19479            for (int conni = s.connections.size()-1;
19480                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19481                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19482                            || procState > ActivityManager.PROCESS_STATE_TOP);
19483                    conni--) {
19484                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19485                for (int i = 0;
19486                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19487                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19488                                || procState > ActivityManager.PROCESS_STATE_TOP);
19489                        i++) {
19490                    // XXX should compute this based on the max of
19491                    // all connected clients.
19492                    ConnectionRecord cr = clist.get(i);
19493                    if (cr.binding.client == app) {
19494                        // Binding to ourself is not interesting.
19495                        continue;
19496                    }
19497
19498                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19499                        ProcessRecord client = cr.binding.client;
19500                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19501                                TOP_APP, doingAll, now);
19502                        int clientProcState = client.curProcState;
19503                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19504                            // If the other app is cached for any reason, for purposes here
19505                            // we are going to consider it empty.  The specific cached state
19506                            // doesn't propagate except under certain conditions.
19507                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19508                        }
19509                        String adjType = null;
19510                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19511                            // Not doing bind OOM management, so treat
19512                            // this guy more like a started service.
19513                            if (app.hasShownUi && app != mHomeProcess) {
19514                                // If this process has shown some UI, let it immediately
19515                                // go to the LRU list because it may be pretty heavy with
19516                                // UI stuff.  We'll tag it with a label just to help
19517                                // debug and understand what is going on.
19518                                if (adj > clientAdj) {
19519                                    adjType = "cch-bound-ui-services";
19520                                }
19521                                app.cached = false;
19522                                clientAdj = adj;
19523                                clientProcState = procState;
19524                            } else {
19525                                if (now >= (s.lastActivity
19526                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19527                                    // This service has not seen activity within
19528                                    // recent memory, so allow it to drop to the
19529                                    // LRU list if there is no other reason to keep
19530                                    // it around.  We'll also tag it with a label just
19531                                    // to help debug and undertand what is going on.
19532                                    if (adj > clientAdj) {
19533                                        adjType = "cch-bound-services";
19534                                    }
19535                                    clientAdj = adj;
19536                                }
19537                            }
19538                        }
19539                        if (adj > clientAdj) {
19540                            // If this process has recently shown UI, and
19541                            // the process that is binding to it is less
19542                            // important than being visible, then we don't
19543                            // care about the binding as much as we care
19544                            // about letting this process get into the LRU
19545                            // list to be killed and restarted if needed for
19546                            // memory.
19547                            if (app.hasShownUi && app != mHomeProcess
19548                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19549                                adjType = "cch-bound-ui-services";
19550                            } else {
19551                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19552                                        |Context.BIND_IMPORTANT)) != 0) {
19553                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19554                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19555                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19556                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19557                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19558                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19559                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19560                                    adj = clientAdj;
19561                                } else {
19562                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19563                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19564                                    }
19565                                }
19566                                if (!client.cached) {
19567                                    app.cached = false;
19568                                }
19569                                adjType = "service";
19570                            }
19571                        }
19572                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19573                            // This will treat important bound services identically to
19574                            // the top app, which may behave differently than generic
19575                            // foreground work.
19576                            if (client.curSchedGroup > schedGroup) {
19577                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19578                                    schedGroup = client.curSchedGroup;
19579                                } else {
19580                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19581                                }
19582                            }
19583                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19584                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19585                                    // Special handling of clients who are in the top state.
19586                                    // We *may* want to consider this process to be in the
19587                                    // top state as well, but only if there is not another
19588                                    // reason for it to be running.  Being on the top is a
19589                                    // special state, meaning you are specifically running
19590                                    // for the current top app.  If the process is already
19591                                    // running in the background for some other reason, it
19592                                    // is more important to continue considering it to be
19593                                    // in the background state.
19594                                    mayBeTop = true;
19595                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19596                                } else {
19597                                    // Special handling for above-top states (persistent
19598                                    // processes).  These should not bring the current process
19599                                    // into the top state, since they are not on top.  Instead
19600                                    // give them the best state after that.
19601                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19602                                        clientProcState =
19603                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19604                                    } else if (mWakefulness
19605                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19606                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19607                                                    != 0) {
19608                                        clientProcState =
19609                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19610                                    } else {
19611                                        clientProcState =
19612                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19613                                    }
19614                                }
19615                            }
19616                        } else {
19617                            if (clientProcState <
19618                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19619                                clientProcState =
19620                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19621                            }
19622                        }
19623                        if (procState > clientProcState) {
19624                            procState = clientProcState;
19625                        }
19626                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19627                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19628                            app.pendingUiClean = true;
19629                        }
19630                        if (adjType != null) {
19631                            app.adjType = adjType;
19632                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19633                                    .REASON_SERVICE_IN_USE;
19634                            app.adjSource = cr.binding.client;
19635                            app.adjSourceProcState = clientProcState;
19636                            app.adjTarget = s.name;
19637                        }
19638                    }
19639                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19640                        app.treatLikeActivity = true;
19641                    }
19642                    final ActivityRecord a = cr.activity;
19643                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19644                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19645                            (a.visible || a.state == ActivityState.RESUMED ||
19646                             a.state == ActivityState.PAUSING)) {
19647                            adj = ProcessList.FOREGROUND_APP_ADJ;
19648                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19649                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19650                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19651                                } else {
19652                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19653                                }
19654                            }
19655                            app.cached = false;
19656                            app.adjType = "service";
19657                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19658                                    .REASON_SERVICE_IN_USE;
19659                            app.adjSource = a;
19660                            app.adjSourceProcState = procState;
19661                            app.adjTarget = s.name;
19662                        }
19663                    }
19664                }
19665            }
19666        }
19667
19668        for (int provi = app.pubProviders.size()-1;
19669                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19670                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19671                        || procState > ActivityManager.PROCESS_STATE_TOP);
19672                provi--) {
19673            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19674            for (int i = cpr.connections.size()-1;
19675                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19676                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19677                            || procState > ActivityManager.PROCESS_STATE_TOP);
19678                    i--) {
19679                ContentProviderConnection conn = cpr.connections.get(i);
19680                ProcessRecord client = conn.client;
19681                if (client == app) {
19682                    // Being our own client is not interesting.
19683                    continue;
19684                }
19685                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19686                int clientProcState = client.curProcState;
19687                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19688                    // If the other app is cached for any reason, for purposes here
19689                    // we are going to consider it empty.
19690                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19691                }
19692                if (adj > clientAdj) {
19693                    if (app.hasShownUi && app != mHomeProcess
19694                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19695                        app.adjType = "cch-ui-provider";
19696                    } else {
19697                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19698                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19699                        app.adjType = "provider";
19700                    }
19701                    app.cached &= client.cached;
19702                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19703                            .REASON_PROVIDER_IN_USE;
19704                    app.adjSource = client;
19705                    app.adjSourceProcState = clientProcState;
19706                    app.adjTarget = cpr.name;
19707                }
19708                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19709                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19710                        // Special handling of clients who are in the top state.
19711                        // We *may* want to consider this process to be in the
19712                        // top state as well, but only if there is not another
19713                        // reason for it to be running.  Being on the top is a
19714                        // special state, meaning you are specifically running
19715                        // for the current top app.  If the process is already
19716                        // running in the background for some other reason, it
19717                        // is more important to continue considering it to be
19718                        // in the background state.
19719                        mayBeTop = true;
19720                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19721                    } else {
19722                        // Special handling for above-top states (persistent
19723                        // processes).  These should not bring the current process
19724                        // into the top state, since they are not on top.  Instead
19725                        // give them the best state after that.
19726                        clientProcState =
19727                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19728                    }
19729                }
19730                if (procState > clientProcState) {
19731                    procState = clientProcState;
19732                }
19733                if (client.curSchedGroup > schedGroup) {
19734                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19735                }
19736            }
19737            // If the provider has external (non-framework) process
19738            // dependencies, ensure that its adjustment is at least
19739            // FOREGROUND_APP_ADJ.
19740            if (cpr.hasExternalProcessHandles()) {
19741                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19742                    adj = ProcessList.FOREGROUND_APP_ADJ;
19743                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19744                    app.cached = false;
19745                    app.adjType = "provider";
19746                    app.adjTarget = cpr.name;
19747                }
19748                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19749                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19750                }
19751            }
19752        }
19753
19754        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19755            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19756                adj = ProcessList.PREVIOUS_APP_ADJ;
19757                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19758                app.cached = false;
19759                app.adjType = "provider";
19760            }
19761            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19762                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19763            }
19764        }
19765
19766        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19767            // A client of one of our services or providers is in the top state.  We
19768            // *may* want to be in the top state, but not if we are already running in
19769            // the background for some other reason.  For the decision here, we are going
19770            // to pick out a few specific states that we want to remain in when a client
19771            // is top (states that tend to be longer-term) and otherwise allow it to go
19772            // to the top state.
19773            switch (procState) {
19774                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19775                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19776                case ActivityManager.PROCESS_STATE_SERVICE:
19777                    // These all are longer-term states, so pull them up to the top
19778                    // of the background states, but not all the way to the top state.
19779                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19780                    break;
19781                default:
19782                    // Otherwise, top is a better choice, so take it.
19783                    procState = ActivityManager.PROCESS_STATE_TOP;
19784                    break;
19785            }
19786        }
19787
19788        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19789            if (app.hasClientActivities) {
19790                // This is a cached process, but with client activities.  Mark it so.
19791                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19792                app.adjType = "cch-client-act";
19793            } else if (app.treatLikeActivity) {
19794                // This is a cached process, but somebody wants us to treat it like it has
19795                // an activity, okay!
19796                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19797                app.adjType = "cch-as-act";
19798            }
19799        }
19800
19801        if (adj == ProcessList.SERVICE_ADJ) {
19802            if (doingAll) {
19803                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19804                mNewNumServiceProcs++;
19805                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19806                if (!app.serviceb) {
19807                    // This service isn't far enough down on the LRU list to
19808                    // normally be a B service, but if we are low on RAM and it
19809                    // is large we want to force it down since we would prefer to
19810                    // keep launcher over it.
19811                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19812                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19813                        app.serviceHighRam = true;
19814                        app.serviceb = true;
19815                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19816                    } else {
19817                        mNewNumAServiceProcs++;
19818                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19819                    }
19820                } else {
19821                    app.serviceHighRam = false;
19822                }
19823            }
19824            if (app.serviceb) {
19825                adj = ProcessList.SERVICE_B_ADJ;
19826            }
19827        }
19828
19829        app.curRawAdj = adj;
19830
19831        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19832        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19833        if (adj > app.maxAdj) {
19834            adj = app.maxAdj;
19835            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19836                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19837            }
19838        }
19839
19840        // Do final modification to adj.  Everything we do between here and applying
19841        // the final setAdj must be done in this function, because we will also use
19842        // it when computing the final cached adj later.  Note that we don't need to
19843        // worry about this for max adj above, since max adj will always be used to
19844        // keep it out of the cached vaues.
19845        app.curAdj = app.modifyRawOomAdj(adj);
19846        app.curSchedGroup = schedGroup;
19847        app.curProcState = procState;
19848        app.foregroundActivities = foregroundActivities;
19849
19850        return app.curRawAdj;
19851    }
19852
19853    /**
19854     * Record new PSS sample for a process.
19855     */
19856    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19857            long now) {
19858        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19859                swapPss * 1024);
19860        proc.lastPssTime = now;
19861        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19862        if (DEBUG_PSS) Slog.d(TAG_PSS,
19863                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19864                + " state=" + ProcessList.makeProcStateString(procState));
19865        if (proc.initialIdlePss == 0) {
19866            proc.initialIdlePss = pss;
19867        }
19868        proc.lastPss = pss;
19869        proc.lastSwapPss = swapPss;
19870        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19871            proc.lastCachedPss = pss;
19872            proc.lastCachedSwapPss = swapPss;
19873        }
19874
19875        final SparseArray<Pair<Long, String>> watchUids
19876                = mMemWatchProcesses.getMap().get(proc.processName);
19877        Long check = null;
19878        if (watchUids != null) {
19879            Pair<Long, String> val = watchUids.get(proc.uid);
19880            if (val == null) {
19881                val = watchUids.get(0);
19882            }
19883            if (val != null) {
19884                check = val.first;
19885            }
19886        }
19887        if (check != null) {
19888            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19889                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19890                if (!isDebuggable) {
19891                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19892                        isDebuggable = true;
19893                    }
19894                }
19895                if (isDebuggable) {
19896                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19897                    final ProcessRecord myProc = proc;
19898                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19899                    mMemWatchDumpProcName = proc.processName;
19900                    mMemWatchDumpFile = heapdumpFile.toString();
19901                    mMemWatchDumpPid = proc.pid;
19902                    mMemWatchDumpUid = proc.uid;
19903                    BackgroundThread.getHandler().post(new Runnable() {
19904                        @Override
19905                        public void run() {
19906                            revokeUriPermission(ActivityThread.currentActivityThread()
19907                                            .getApplicationThread(),
19908                                    DumpHeapActivity.JAVA_URI,
19909                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19910                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19911                                    UserHandle.myUserId());
19912                            ParcelFileDescriptor fd = null;
19913                            try {
19914                                heapdumpFile.delete();
19915                                fd = ParcelFileDescriptor.open(heapdumpFile,
19916                                        ParcelFileDescriptor.MODE_CREATE |
19917                                                ParcelFileDescriptor.MODE_TRUNCATE |
19918                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19919                                                ParcelFileDescriptor.MODE_APPEND);
19920                                IApplicationThread thread = myProc.thread;
19921                                if (thread != null) {
19922                                    try {
19923                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19924                                                "Requesting dump heap from "
19925                                                + myProc + " to " + heapdumpFile);
19926                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19927                                    } catch (RemoteException e) {
19928                                    }
19929                                }
19930                            } catch (FileNotFoundException e) {
19931                                e.printStackTrace();
19932                            } finally {
19933                                if (fd != null) {
19934                                    try {
19935                                        fd.close();
19936                                    } catch (IOException e) {
19937                                    }
19938                                }
19939                            }
19940                        }
19941                    });
19942                } else {
19943                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19944                            + ", but debugging not enabled");
19945                }
19946            }
19947        }
19948    }
19949
19950    /**
19951     * Schedule PSS collection of a process.
19952     */
19953    void requestPssLocked(ProcessRecord proc, int procState) {
19954        if (mPendingPssProcesses.contains(proc)) {
19955            return;
19956        }
19957        if (mPendingPssProcesses.size() == 0) {
19958            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19959        }
19960        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19961        proc.pssProcState = procState;
19962        mPendingPssProcesses.add(proc);
19963    }
19964
19965    /**
19966     * Schedule PSS collection of all processes.
19967     */
19968    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19969        if (!always) {
19970            if (now < (mLastFullPssTime +
19971                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19972                return;
19973            }
19974        }
19975        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19976        mLastFullPssTime = now;
19977        mFullPssPending = true;
19978        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19979        mPendingPssProcesses.clear();
19980        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19981            ProcessRecord app = mLruProcesses.get(i);
19982            if (app.thread == null
19983                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19984                continue;
19985            }
19986            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19987                app.pssProcState = app.setProcState;
19988                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19989                        mTestPssMode, isSleepingLocked(), now);
19990                mPendingPssProcesses.add(app);
19991            }
19992        }
19993        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19994    }
19995
19996    public void setTestPssMode(boolean enabled) {
19997        synchronized (this) {
19998            mTestPssMode = enabled;
19999            if (enabled) {
20000                // Whenever we enable the mode, we want to take a snapshot all of current
20001                // process mem use.
20002                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20003            }
20004        }
20005    }
20006
20007    /**
20008     * Ask a given process to GC right now.
20009     */
20010    final void performAppGcLocked(ProcessRecord app) {
20011        try {
20012            app.lastRequestedGc = SystemClock.uptimeMillis();
20013            if (app.thread != null) {
20014                if (app.reportLowMemory) {
20015                    app.reportLowMemory = false;
20016                    app.thread.scheduleLowMemory();
20017                } else {
20018                    app.thread.processInBackground();
20019                }
20020            }
20021        } catch (Exception e) {
20022            // whatever.
20023        }
20024    }
20025
20026    /**
20027     * Returns true if things are idle enough to perform GCs.
20028     */
20029    private final boolean canGcNowLocked() {
20030        boolean processingBroadcasts = false;
20031        for (BroadcastQueue q : mBroadcastQueues) {
20032            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20033                processingBroadcasts = true;
20034            }
20035        }
20036        return !processingBroadcasts
20037                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20038    }
20039
20040    /**
20041     * Perform GCs on all processes that are waiting for it, but only
20042     * if things are idle.
20043     */
20044    final void performAppGcsLocked() {
20045        final int N = mProcessesToGc.size();
20046        if (N <= 0) {
20047            return;
20048        }
20049        if (canGcNowLocked()) {
20050            while (mProcessesToGc.size() > 0) {
20051                ProcessRecord proc = mProcessesToGc.remove(0);
20052                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20053                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20054                            <= SystemClock.uptimeMillis()) {
20055                        // To avoid spamming the system, we will GC processes one
20056                        // at a time, waiting a few seconds between each.
20057                        performAppGcLocked(proc);
20058                        scheduleAppGcsLocked();
20059                        return;
20060                    } else {
20061                        // It hasn't been long enough since we last GCed this
20062                        // process...  put it in the list to wait for its time.
20063                        addProcessToGcListLocked(proc);
20064                        break;
20065                    }
20066                }
20067            }
20068
20069            scheduleAppGcsLocked();
20070        }
20071    }
20072
20073    /**
20074     * If all looks good, perform GCs on all processes waiting for them.
20075     */
20076    final void performAppGcsIfAppropriateLocked() {
20077        if (canGcNowLocked()) {
20078            performAppGcsLocked();
20079            return;
20080        }
20081        // Still not idle, wait some more.
20082        scheduleAppGcsLocked();
20083    }
20084
20085    /**
20086     * Schedule the execution of all pending app GCs.
20087     */
20088    final void scheduleAppGcsLocked() {
20089        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20090
20091        if (mProcessesToGc.size() > 0) {
20092            // Schedule a GC for the time to the next process.
20093            ProcessRecord proc = mProcessesToGc.get(0);
20094            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20095
20096            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20097            long now = SystemClock.uptimeMillis();
20098            if (when < (now+GC_TIMEOUT)) {
20099                when = now + GC_TIMEOUT;
20100            }
20101            mHandler.sendMessageAtTime(msg, when);
20102        }
20103    }
20104
20105    /**
20106     * Add a process to the array of processes waiting to be GCed.  Keeps the
20107     * list in sorted order by the last GC time.  The process can't already be
20108     * on the list.
20109     */
20110    final void addProcessToGcListLocked(ProcessRecord proc) {
20111        boolean added = false;
20112        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20113            if (mProcessesToGc.get(i).lastRequestedGc <
20114                    proc.lastRequestedGc) {
20115                added = true;
20116                mProcessesToGc.add(i+1, proc);
20117                break;
20118            }
20119        }
20120        if (!added) {
20121            mProcessesToGc.add(0, proc);
20122        }
20123    }
20124
20125    /**
20126     * Set up to ask a process to GC itself.  This will either do it
20127     * immediately, or put it on the list of processes to gc the next
20128     * time things are idle.
20129     */
20130    final void scheduleAppGcLocked(ProcessRecord app) {
20131        long now = SystemClock.uptimeMillis();
20132        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20133            return;
20134        }
20135        if (!mProcessesToGc.contains(app)) {
20136            addProcessToGcListLocked(app);
20137            scheduleAppGcsLocked();
20138        }
20139    }
20140
20141    final void checkExcessivePowerUsageLocked(boolean doKills) {
20142        updateCpuStatsNow();
20143
20144        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20145        boolean doWakeKills = doKills;
20146        boolean doCpuKills = doKills;
20147        if (mLastPowerCheckRealtime == 0) {
20148            doWakeKills = false;
20149        }
20150        if (mLastPowerCheckUptime == 0) {
20151            doCpuKills = false;
20152        }
20153        if (stats.isScreenOn()) {
20154            doWakeKills = false;
20155        }
20156        final long curRealtime = SystemClock.elapsedRealtime();
20157        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20158        final long curUptime = SystemClock.uptimeMillis();
20159        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20160        mLastPowerCheckRealtime = curRealtime;
20161        mLastPowerCheckUptime = curUptime;
20162        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20163            doWakeKills = false;
20164        }
20165        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20166            doCpuKills = false;
20167        }
20168        int i = mLruProcesses.size();
20169        while (i > 0) {
20170            i--;
20171            ProcessRecord app = mLruProcesses.get(i);
20172            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20173                long wtime;
20174                synchronized (stats) {
20175                    wtime = stats.getProcessWakeTime(app.info.uid,
20176                            app.pid, curRealtime);
20177                }
20178                long wtimeUsed = wtime - app.lastWakeTime;
20179                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20180                if (DEBUG_POWER) {
20181                    StringBuilder sb = new StringBuilder(128);
20182                    sb.append("Wake for ");
20183                    app.toShortString(sb);
20184                    sb.append(": over ");
20185                    TimeUtils.formatDuration(realtimeSince, sb);
20186                    sb.append(" used ");
20187                    TimeUtils.formatDuration(wtimeUsed, sb);
20188                    sb.append(" (");
20189                    sb.append((wtimeUsed*100)/realtimeSince);
20190                    sb.append("%)");
20191                    Slog.i(TAG_POWER, sb.toString());
20192                    sb.setLength(0);
20193                    sb.append("CPU for ");
20194                    app.toShortString(sb);
20195                    sb.append(": over ");
20196                    TimeUtils.formatDuration(uptimeSince, sb);
20197                    sb.append(" used ");
20198                    TimeUtils.formatDuration(cputimeUsed, sb);
20199                    sb.append(" (");
20200                    sb.append((cputimeUsed*100)/uptimeSince);
20201                    sb.append("%)");
20202                    Slog.i(TAG_POWER, sb.toString());
20203                }
20204                // If a process has held a wake lock for more
20205                // than 50% of the time during this period,
20206                // that sounds bad.  Kill!
20207                if (doWakeKills && realtimeSince > 0
20208                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20209                    synchronized (stats) {
20210                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20211                                realtimeSince, wtimeUsed);
20212                    }
20213                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20214                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20215                } else if (doCpuKills && uptimeSince > 0
20216                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20217                    synchronized (stats) {
20218                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20219                                uptimeSince, cputimeUsed);
20220                    }
20221                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20222                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20223                } else {
20224                    app.lastWakeTime = wtime;
20225                    app.lastCpuTime = app.curCpuTime;
20226                }
20227            }
20228        }
20229    }
20230
20231    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20232            long nowElapsed) {
20233        boolean success = true;
20234
20235        if (app.curRawAdj != app.setRawAdj) {
20236            app.setRawAdj = app.curRawAdj;
20237        }
20238
20239        int changes = 0;
20240
20241        if (app.curAdj != app.setAdj) {
20242            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20243            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20244                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20245                    + app.adjType);
20246            app.setAdj = app.curAdj;
20247            app.verifiedAdj = ProcessList.INVALID_ADJ;
20248        }
20249
20250        if (app.setSchedGroup != app.curSchedGroup) {
20251            int oldSchedGroup = app.setSchedGroup;
20252            app.setSchedGroup = app.curSchedGroup;
20253            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20254                    "Setting sched group of " + app.processName
20255                    + " to " + app.curSchedGroup);
20256            if (app.waitingToKill != null && app.curReceiver == null
20257                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20258                app.kill(app.waitingToKill, true);
20259                success = false;
20260            } else {
20261                int processGroup;
20262                switch (app.curSchedGroup) {
20263                    case ProcessList.SCHED_GROUP_BACKGROUND:
20264                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20265                        break;
20266                    case ProcessList.SCHED_GROUP_TOP_APP:
20267                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20268                        processGroup = Process.THREAD_GROUP_TOP_APP;
20269                        break;
20270                    default:
20271                        processGroup = Process.THREAD_GROUP_DEFAULT;
20272                        break;
20273                }
20274                long oldId = Binder.clearCallingIdentity();
20275                try {
20276                    Process.setProcessGroup(app.pid, processGroup);
20277                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20278                        // do nothing if we already switched to RT
20279                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20280                            // Switch VR thread for app to SCHED_FIFO
20281                            if (mInVrMode && app.vrThreadTid != 0) {
20282                                Process.setThreadScheduler(app.vrThreadTid,
20283                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20284                            }
20285                            if (mUseFifoUiScheduling) {
20286                                // Switch UI pipeline for app to SCHED_FIFO
20287                                app.savedPriority = Process.getThreadPriority(app.pid);
20288                                Process.setThreadScheduler(app.pid,
20289                                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20290                                if (app.renderThreadTid != 0) {
20291                                    Process.setThreadScheduler(app.renderThreadTid,
20292                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20293                                    if (DEBUG_OOM_ADJ) {
20294                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20295                                            app.renderThreadTid + ") to FIFO");
20296                                    }
20297                                } else {
20298                                    if (DEBUG_OOM_ADJ) {
20299                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20300                                    }
20301                                }
20302                            }
20303                        }
20304                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20305                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20306                        // Reset VR thread to SCHED_OTHER
20307                        // Safe to do even if we're not in VR mode
20308                        if (app.vrThreadTid != 0) {
20309                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20310                        }
20311                        if (mUseFifoUiScheduling) {
20312                            // Reset UI pipeline to SCHED_OTHER
20313                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20314                            Process.setThreadPriority(app.pid, app.savedPriority);
20315                            if (app.renderThreadTid != 0) {
20316                                Process.setThreadScheduler(app.renderThreadTid,
20317                                    Process.SCHED_OTHER, 0);
20318                                Process.setThreadPriority(app.renderThreadTid, -4);
20319                            }
20320                        }
20321                    }
20322                } catch (Exception e) {
20323                    Slog.w(TAG, "Failed setting process group of " + app.pid
20324                            + " to " + app.curSchedGroup);
20325                    e.printStackTrace();
20326                } finally {
20327                    Binder.restoreCallingIdentity(oldId);
20328                }
20329            }
20330        }
20331        if (app.repForegroundActivities != app.foregroundActivities) {
20332            app.repForegroundActivities = app.foregroundActivities;
20333            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20334        }
20335        if (app.repProcState != app.curProcState) {
20336            app.repProcState = app.curProcState;
20337            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20338            if (app.thread != null) {
20339                try {
20340                    if (false) {
20341                        //RuntimeException h = new RuntimeException("here");
20342                        Slog.i(TAG, "Sending new process state " + app.repProcState
20343                                + " to " + app /*, h*/);
20344                    }
20345                    app.thread.setProcessState(app.repProcState);
20346                } catch (RemoteException e) {
20347                }
20348            }
20349        }
20350        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20351                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20352            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20353                // Experimental code to more aggressively collect pss while
20354                // running test...  the problem is that this tends to collect
20355                // the data right when a process is transitioning between process
20356                // states, which well tend to give noisy data.
20357                long start = SystemClock.uptimeMillis();
20358                long pss = Debug.getPss(app.pid, mTmpLong, null);
20359                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20360                mPendingPssProcesses.remove(app);
20361                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20362                        + " to " + app.curProcState + ": "
20363                        + (SystemClock.uptimeMillis()-start) + "ms");
20364            }
20365            app.lastStateTime = now;
20366            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20367                    mTestPssMode, isSleepingLocked(), now);
20368            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20369                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20370                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20371                    + (app.nextPssTime-now) + ": " + app);
20372        } else {
20373            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20374                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20375                    mTestPssMode)))) {
20376                requestPssLocked(app, app.setProcState);
20377                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20378                        mTestPssMode, isSleepingLocked(), now);
20379            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20380                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20381        }
20382        if (app.setProcState != app.curProcState) {
20383            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20384                    "Proc state change of " + app.processName
20385                            + " to " + app.curProcState);
20386            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20387            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20388            if (setImportant && !curImportant) {
20389                // This app is no longer something we consider important enough to allow to
20390                // use arbitrary amounts of battery power.  Note
20391                // its current wake lock time to later know to kill it if
20392                // it is not behaving well.
20393                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20394                synchronized (stats) {
20395                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20396                            app.pid, nowElapsed);
20397                }
20398                app.lastCpuTime = app.curCpuTime;
20399
20400            }
20401            // Inform UsageStats of important process state change
20402            // Must be called before updating setProcState
20403            maybeUpdateUsageStatsLocked(app, nowElapsed);
20404
20405            app.setProcState = app.curProcState;
20406            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20407                app.notCachedSinceIdle = false;
20408            }
20409            if (!doingAll) {
20410                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20411            } else {
20412                app.procStateChanged = true;
20413            }
20414        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20415                > USAGE_STATS_INTERACTION_INTERVAL) {
20416            // For apps that sit around for a long time in the interactive state, we need
20417            // to report this at least once a day so they don't go idle.
20418            maybeUpdateUsageStatsLocked(app, nowElapsed);
20419        }
20420
20421        if (changes != 0) {
20422            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20423                    "Changes in " + app + ": " + changes);
20424            int i = mPendingProcessChanges.size()-1;
20425            ProcessChangeItem item = null;
20426            while (i >= 0) {
20427                item = mPendingProcessChanges.get(i);
20428                if (item.pid == app.pid) {
20429                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20430                            "Re-using existing item: " + item);
20431                    break;
20432                }
20433                i--;
20434            }
20435            if (i < 0) {
20436                // No existing item in pending changes; need a new one.
20437                final int NA = mAvailProcessChanges.size();
20438                if (NA > 0) {
20439                    item = mAvailProcessChanges.remove(NA-1);
20440                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20441                            "Retrieving available item: " + item);
20442                } else {
20443                    item = new ProcessChangeItem();
20444                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20445                            "Allocating new item: " + item);
20446                }
20447                item.changes = 0;
20448                item.pid = app.pid;
20449                item.uid = app.info.uid;
20450                if (mPendingProcessChanges.size() == 0) {
20451                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20452                            "*** Enqueueing dispatch processes changed!");
20453                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20454                }
20455                mPendingProcessChanges.add(item);
20456            }
20457            item.changes |= changes;
20458            item.processState = app.repProcState;
20459            item.foregroundActivities = app.repForegroundActivities;
20460            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20461                    "Item " + Integer.toHexString(System.identityHashCode(item))
20462                    + " " + app.toShortString() + ": changes=" + item.changes
20463                    + " procState=" + item.processState
20464                    + " foreground=" + item.foregroundActivities
20465                    + " type=" + app.adjType + " source=" + app.adjSource
20466                    + " target=" + app.adjTarget);
20467        }
20468
20469        return success;
20470    }
20471
20472    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20473        final UidRecord.ChangeItem pendingChange;
20474        if (uidRec == null || uidRec.pendingChange == null) {
20475            if (mPendingUidChanges.size() == 0) {
20476                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20477                        "*** Enqueueing dispatch uid changed!");
20478                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20479            }
20480            final int NA = mAvailUidChanges.size();
20481            if (NA > 0) {
20482                pendingChange = mAvailUidChanges.remove(NA-1);
20483                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20484                        "Retrieving available item: " + pendingChange);
20485            } else {
20486                pendingChange = new UidRecord.ChangeItem();
20487                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20488                        "Allocating new item: " + pendingChange);
20489            }
20490            if (uidRec != null) {
20491                uidRec.pendingChange = pendingChange;
20492                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20493                    // If this uid is going away, and we haven't yet reported it is gone,
20494                    // then do so now.
20495                    change = UidRecord.CHANGE_GONE_IDLE;
20496                }
20497            } else if (uid < 0) {
20498                throw new IllegalArgumentException("No UidRecord or uid");
20499            }
20500            pendingChange.uidRecord = uidRec;
20501            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20502            mPendingUidChanges.add(pendingChange);
20503        } else {
20504            pendingChange = uidRec.pendingChange;
20505            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20506                change = UidRecord.CHANGE_GONE_IDLE;
20507            }
20508        }
20509        pendingChange.change = change;
20510        pendingChange.processState = uidRec != null
20511                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20512    }
20513
20514    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20515            String authority) {
20516        if (app == null) return;
20517        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20518            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20519            if (userState == null) return;
20520            final long now = SystemClock.elapsedRealtime();
20521            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20522            if (lastReported == null || lastReported < now - 60 * 1000L) {
20523                mUsageStatsService.reportContentProviderUsage(
20524                        authority, providerPkgName, app.userId);
20525                userState.mProviderLastReportedFg.put(authority, now);
20526            }
20527        }
20528    }
20529
20530    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20531        if (DEBUG_USAGE_STATS) {
20532            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20533                    + "] state changes: old = " + app.setProcState + ", new = "
20534                    + app.curProcState);
20535        }
20536        if (mUsageStatsService == null) {
20537            return;
20538        }
20539        boolean isInteraction;
20540        // To avoid some abuse patterns, we are going to be careful about what we consider
20541        // to be an app interaction.  Being the top activity doesn't count while the display
20542        // is sleeping, nor do short foreground services.
20543        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20544            isInteraction = true;
20545            app.fgInteractionTime = 0;
20546        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20547            if (app.fgInteractionTime == 0) {
20548                app.fgInteractionTime = nowElapsed;
20549                isInteraction = false;
20550            } else {
20551                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20552            }
20553        } else {
20554            isInteraction = app.curProcState
20555                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20556            app.fgInteractionTime = 0;
20557        }
20558        if (isInteraction && (!app.reportedInteraction
20559                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20560            app.interactionEventTime = nowElapsed;
20561            String[] packages = app.getPackageList();
20562            if (packages != null) {
20563                for (int i = 0; i < packages.length; i++) {
20564                    mUsageStatsService.reportEvent(packages[i], app.userId,
20565                            UsageEvents.Event.SYSTEM_INTERACTION);
20566                }
20567            }
20568        }
20569        app.reportedInteraction = isInteraction;
20570        if (!isInteraction) {
20571            app.interactionEventTime = 0;
20572        }
20573    }
20574
20575    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20576        if (proc.thread != null) {
20577            if (proc.baseProcessTracker != null) {
20578                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20579            }
20580        }
20581    }
20582
20583    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20584            ProcessRecord TOP_APP, boolean doingAll, long now) {
20585        if (app.thread == null) {
20586            return false;
20587        }
20588
20589        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20590
20591        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20592    }
20593
20594    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20595            boolean oomAdj) {
20596        if (isForeground != proc.foregroundServices) {
20597            proc.foregroundServices = isForeground;
20598            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20599                    proc.info.uid);
20600            if (isForeground) {
20601                if (curProcs == null) {
20602                    curProcs = new ArrayList<ProcessRecord>();
20603                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20604                }
20605                if (!curProcs.contains(proc)) {
20606                    curProcs.add(proc);
20607                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20608                            proc.info.packageName, proc.info.uid);
20609                }
20610            } else {
20611                if (curProcs != null) {
20612                    if (curProcs.remove(proc)) {
20613                        mBatteryStatsService.noteEvent(
20614                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20615                                proc.info.packageName, proc.info.uid);
20616                        if (curProcs.size() <= 0) {
20617                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20618                        }
20619                    }
20620                }
20621            }
20622            if (oomAdj) {
20623                updateOomAdjLocked();
20624            }
20625        }
20626    }
20627
20628    private final ActivityRecord resumedAppLocked() {
20629        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20630        String pkg;
20631        int uid;
20632        if (act != null) {
20633            pkg = act.packageName;
20634            uid = act.info.applicationInfo.uid;
20635        } else {
20636            pkg = null;
20637            uid = -1;
20638        }
20639        // Has the UID or resumed package name changed?
20640        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20641                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20642            if (mCurResumedPackage != null) {
20643                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20644                        mCurResumedPackage, mCurResumedUid);
20645            }
20646            mCurResumedPackage = pkg;
20647            mCurResumedUid = uid;
20648            if (mCurResumedPackage != null) {
20649                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20650                        mCurResumedPackage, mCurResumedUid);
20651            }
20652        }
20653        return act;
20654    }
20655
20656    final boolean updateOomAdjLocked(ProcessRecord app) {
20657        final ActivityRecord TOP_ACT = resumedAppLocked();
20658        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20659        final boolean wasCached = app.cached;
20660
20661        mAdjSeq++;
20662
20663        // This is the desired cached adjusment we want to tell it to use.
20664        // If our app is currently cached, we know it, and that is it.  Otherwise,
20665        // we don't know it yet, and it needs to now be cached we will then
20666        // need to do a complete oom adj.
20667        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20668                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20669        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20670                SystemClock.uptimeMillis());
20671        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20672            // Changed to/from cached state, so apps after it in the LRU
20673            // list may also be changed.
20674            updateOomAdjLocked();
20675        }
20676        return success;
20677    }
20678
20679    final void updateOomAdjLocked() {
20680        final ActivityRecord TOP_ACT = resumedAppLocked();
20681        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20682        final long now = SystemClock.uptimeMillis();
20683        final long nowElapsed = SystemClock.elapsedRealtime();
20684        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20685        final int N = mLruProcesses.size();
20686
20687        if (false) {
20688            RuntimeException e = new RuntimeException();
20689            e.fillInStackTrace();
20690            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20691        }
20692
20693        // Reset state in all uid records.
20694        for (int i=mActiveUids.size()-1; i>=0; i--) {
20695            final UidRecord uidRec = mActiveUids.valueAt(i);
20696            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20697                    "Starting update of " + uidRec);
20698            uidRec.reset();
20699        }
20700
20701        mStackSupervisor.rankTaskLayersIfNeeded();
20702
20703        mAdjSeq++;
20704        mNewNumServiceProcs = 0;
20705        mNewNumAServiceProcs = 0;
20706
20707        final int emptyProcessLimit;
20708        final int cachedProcessLimit;
20709        if (mProcessLimit <= 0) {
20710            emptyProcessLimit = cachedProcessLimit = 0;
20711        } else if (mProcessLimit == 1) {
20712            emptyProcessLimit = 1;
20713            cachedProcessLimit = 0;
20714        } else {
20715            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20716            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20717        }
20718
20719        // Let's determine how many processes we have running vs.
20720        // how many slots we have for background processes; we may want
20721        // to put multiple processes in a slot of there are enough of
20722        // them.
20723        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20724                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20725        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20726        if (numEmptyProcs > cachedProcessLimit) {
20727            // If there are more empty processes than our limit on cached
20728            // processes, then use the cached process limit for the factor.
20729            // This ensures that the really old empty processes get pushed
20730            // down to the bottom, so if we are running low on memory we will
20731            // have a better chance at keeping around more cached processes
20732            // instead of a gazillion empty processes.
20733            numEmptyProcs = cachedProcessLimit;
20734        }
20735        int emptyFactor = numEmptyProcs/numSlots;
20736        if (emptyFactor < 1) emptyFactor = 1;
20737        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20738        if (cachedFactor < 1) cachedFactor = 1;
20739        int stepCached = 0;
20740        int stepEmpty = 0;
20741        int numCached = 0;
20742        int numEmpty = 0;
20743        int numTrimming = 0;
20744
20745        mNumNonCachedProcs = 0;
20746        mNumCachedHiddenProcs = 0;
20747
20748        // First update the OOM adjustment for each of the
20749        // application processes based on their current state.
20750        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20751        int nextCachedAdj = curCachedAdj+1;
20752        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20753        int nextEmptyAdj = curEmptyAdj+2;
20754        for (int i=N-1; i>=0; i--) {
20755            ProcessRecord app = mLruProcesses.get(i);
20756            if (!app.killedByAm && app.thread != null) {
20757                app.procStateChanged = false;
20758                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20759
20760                // If we haven't yet assigned the final cached adj
20761                // to the process, do that now.
20762                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20763                    switch (app.curProcState) {
20764                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20765                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20766                            // This process is a cached process holding activities...
20767                            // assign it the next cached value for that type, and then
20768                            // step that cached level.
20769                            app.curRawAdj = curCachedAdj;
20770                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20771                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20772                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20773                                    + ")");
20774                            if (curCachedAdj != nextCachedAdj) {
20775                                stepCached++;
20776                                if (stepCached >= cachedFactor) {
20777                                    stepCached = 0;
20778                                    curCachedAdj = nextCachedAdj;
20779                                    nextCachedAdj += 2;
20780                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20781                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20782                                    }
20783                                }
20784                            }
20785                            break;
20786                        default:
20787                            // For everything else, assign next empty cached process
20788                            // level and bump that up.  Note that this means that
20789                            // long-running services that have dropped down to the
20790                            // cached level will be treated as empty (since their process
20791                            // state is still as a service), which is what we want.
20792                            app.curRawAdj = curEmptyAdj;
20793                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20794                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20795                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20796                                    + ")");
20797                            if (curEmptyAdj != nextEmptyAdj) {
20798                                stepEmpty++;
20799                                if (stepEmpty >= emptyFactor) {
20800                                    stepEmpty = 0;
20801                                    curEmptyAdj = nextEmptyAdj;
20802                                    nextEmptyAdj += 2;
20803                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20804                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20805                                    }
20806                                }
20807                            }
20808                            break;
20809                    }
20810                }
20811
20812                applyOomAdjLocked(app, true, now, nowElapsed);
20813
20814                // Count the number of process types.
20815                switch (app.curProcState) {
20816                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20817                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20818                        mNumCachedHiddenProcs++;
20819                        numCached++;
20820                        if (numCached > cachedProcessLimit) {
20821                            app.kill("cached #" + numCached, true);
20822                        }
20823                        break;
20824                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20825                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20826                                && app.lastActivityTime < oldTime) {
20827                            app.kill("empty for "
20828                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20829                                    / 1000) + "s", true);
20830                        } else {
20831                            numEmpty++;
20832                            if (numEmpty > emptyProcessLimit) {
20833                                app.kill("empty #" + numEmpty, true);
20834                            }
20835                        }
20836                        break;
20837                    default:
20838                        mNumNonCachedProcs++;
20839                        break;
20840                }
20841
20842                if (app.isolated && app.services.size() <= 0) {
20843                    // If this is an isolated process, and there are no
20844                    // services running in it, then the process is no longer
20845                    // needed.  We agressively kill these because we can by
20846                    // definition not re-use the same process again, and it is
20847                    // good to avoid having whatever code was running in them
20848                    // left sitting around after no longer needed.
20849                    app.kill("isolated not needed", true);
20850                } else {
20851                    // Keeping this process, update its uid.
20852                    final UidRecord uidRec = app.uidRecord;
20853                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20854                        uidRec.curProcState = app.curProcState;
20855                    }
20856                }
20857
20858                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20859                        && !app.killedByAm) {
20860                    numTrimming++;
20861                }
20862            }
20863        }
20864
20865        mNumServiceProcs = mNewNumServiceProcs;
20866
20867        // Now determine the memory trimming level of background processes.
20868        // Unfortunately we need to start at the back of the list to do this
20869        // properly.  We only do this if the number of background apps we
20870        // are managing to keep around is less than half the maximum we desire;
20871        // if we are keeping a good number around, we'll let them use whatever
20872        // memory they want.
20873        final int numCachedAndEmpty = numCached + numEmpty;
20874        int memFactor;
20875        if (numCached <= ProcessList.TRIM_CACHED_APPS
20876                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20877            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20878                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20879            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20880                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20881            } else {
20882                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20883            }
20884        } else {
20885            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20886        }
20887        // We always allow the memory level to go up (better).  We only allow it to go
20888        // down if we are in a state where that is allowed, *and* the total number of processes
20889        // has gone down since last time.
20890        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20891                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20892                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20893        if (memFactor > mLastMemoryLevel) {
20894            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20895                memFactor = mLastMemoryLevel;
20896                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20897            }
20898        }
20899        if (memFactor != mLastMemoryLevel) {
20900            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20901        }
20902        mLastMemoryLevel = memFactor;
20903        mLastNumProcesses = mLruProcesses.size();
20904        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20905        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20906        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20907            if (mLowRamStartTime == 0) {
20908                mLowRamStartTime = now;
20909            }
20910            int step = 0;
20911            int fgTrimLevel;
20912            switch (memFactor) {
20913                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20914                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20915                    break;
20916                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20917                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20918                    break;
20919                default:
20920                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20921                    break;
20922            }
20923            int factor = numTrimming/3;
20924            int minFactor = 2;
20925            if (mHomeProcess != null) minFactor++;
20926            if (mPreviousProcess != null) minFactor++;
20927            if (factor < minFactor) factor = minFactor;
20928            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20929            for (int i=N-1; i>=0; i--) {
20930                ProcessRecord app = mLruProcesses.get(i);
20931                if (allChanged || app.procStateChanged) {
20932                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20933                    app.procStateChanged = false;
20934                }
20935                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20936                        && !app.killedByAm) {
20937                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20938                        try {
20939                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20940                                    "Trimming memory of " + app.processName + " to " + curLevel);
20941                            app.thread.scheduleTrimMemory(curLevel);
20942                        } catch (RemoteException e) {
20943                        }
20944                        if (false) {
20945                            // For now we won't do this; our memory trimming seems
20946                            // to be good enough at this point that destroying
20947                            // activities causes more harm than good.
20948                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20949                                    && app != mHomeProcess && app != mPreviousProcess) {
20950                                // Need to do this on its own message because the stack may not
20951                                // be in a consistent state at this point.
20952                                // For these apps we will also finish their activities
20953                                // to help them free memory.
20954                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20955                            }
20956                        }
20957                    }
20958                    app.trimMemoryLevel = curLevel;
20959                    step++;
20960                    if (step >= factor) {
20961                        step = 0;
20962                        switch (curLevel) {
20963                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20964                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20965                                break;
20966                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20967                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20968                                break;
20969                        }
20970                    }
20971                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20972                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20973                            && app.thread != null) {
20974                        try {
20975                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20976                                    "Trimming memory of heavy-weight " + app.processName
20977                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20978                            app.thread.scheduleTrimMemory(
20979                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20980                        } catch (RemoteException e) {
20981                        }
20982                    }
20983                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20984                } else {
20985                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20986                            || app.systemNoUi) && app.pendingUiClean) {
20987                        // If this application is now in the background and it
20988                        // had done UI, then give it the special trim level to
20989                        // have it free UI resources.
20990                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20991                        if (app.trimMemoryLevel < level && app.thread != null) {
20992                            try {
20993                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20994                                        "Trimming memory of bg-ui " + app.processName
20995                                        + " to " + level);
20996                                app.thread.scheduleTrimMemory(level);
20997                            } catch (RemoteException e) {
20998                            }
20999                        }
21000                        app.pendingUiClean = false;
21001                    }
21002                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21003                        try {
21004                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21005                                    "Trimming memory of fg " + app.processName
21006                                    + " to " + fgTrimLevel);
21007                            app.thread.scheduleTrimMemory(fgTrimLevel);
21008                        } catch (RemoteException e) {
21009                        }
21010                    }
21011                    app.trimMemoryLevel = fgTrimLevel;
21012                }
21013            }
21014        } else {
21015            if (mLowRamStartTime != 0) {
21016                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21017                mLowRamStartTime = 0;
21018            }
21019            for (int i=N-1; i>=0; i--) {
21020                ProcessRecord app = mLruProcesses.get(i);
21021                if (allChanged || app.procStateChanged) {
21022                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21023                    app.procStateChanged = false;
21024                }
21025                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21026                        || app.systemNoUi) && app.pendingUiClean) {
21027                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21028                            && app.thread != null) {
21029                        try {
21030                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21031                                    "Trimming memory of ui hidden " + app.processName
21032                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21033                            app.thread.scheduleTrimMemory(
21034                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21035                        } catch (RemoteException e) {
21036                        }
21037                    }
21038                    app.pendingUiClean = false;
21039                }
21040                app.trimMemoryLevel = 0;
21041            }
21042        }
21043
21044        if (mAlwaysFinishActivities) {
21045            // Need to do this on its own message because the stack may not
21046            // be in a consistent state at this point.
21047            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21048        }
21049
21050        if (allChanged) {
21051            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21052        }
21053
21054        // Update from any uid changes.
21055        for (int i=mActiveUids.size()-1; i>=0; i--) {
21056            final UidRecord uidRec = mActiveUids.valueAt(i);
21057            int uidChange = UidRecord.CHANGE_PROCSTATE;
21058            if (uidRec.setProcState != uidRec.curProcState) {
21059                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21060                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21061                        + " to " + uidRec.curProcState);
21062                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21063                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21064                        uidRec.lastBackgroundTime = nowElapsed;
21065                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21066                            // Note: the background settle time is in elapsed realtime, while
21067                            // the handler time base is uptime.  All this means is that we may
21068                            // stop background uids later than we had intended, but that only
21069                            // happens because the device was sleeping so we are okay anyway.
21070                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21071                        }
21072                    }
21073                } else {
21074                    if (uidRec.idle) {
21075                        uidChange = UidRecord.CHANGE_ACTIVE;
21076                        uidRec.idle = false;
21077                    }
21078                    uidRec.lastBackgroundTime = 0;
21079                }
21080                uidRec.setProcState = uidRec.curProcState;
21081                enqueueUidChangeLocked(uidRec, -1, uidChange);
21082                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21083            }
21084        }
21085
21086        if (mProcessStats.shouldWriteNowLocked(now)) {
21087            mHandler.post(new Runnable() {
21088                @Override public void run() {
21089                    synchronized (ActivityManagerService.this) {
21090                        mProcessStats.writeStateAsyncLocked();
21091                    }
21092                }
21093            });
21094        }
21095
21096        if (DEBUG_OOM_ADJ) {
21097            final long duration = SystemClock.uptimeMillis() - now;
21098            if (false) {
21099                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21100                        new RuntimeException("here").fillInStackTrace());
21101            } else {
21102                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21103            }
21104        }
21105    }
21106
21107    final void idleUids() {
21108        synchronized (this) {
21109            final long nowElapsed = SystemClock.elapsedRealtime();
21110            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21111            long nextTime = 0;
21112            for (int i=mActiveUids.size()-1; i>=0; i--) {
21113                final UidRecord uidRec = mActiveUids.valueAt(i);
21114                final long bgTime = uidRec.lastBackgroundTime;
21115                if (bgTime > 0 && !uidRec.idle) {
21116                    if (bgTime <= maxBgTime) {
21117                        uidRec.idle = true;
21118                        doStopUidLocked(uidRec.uid, uidRec);
21119                    } else {
21120                        if (nextTime == 0 || nextTime > bgTime) {
21121                            nextTime = bgTime;
21122                        }
21123                    }
21124                }
21125            }
21126            if (nextTime > 0) {
21127                mHandler.removeMessages(IDLE_UIDS_MSG);
21128                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21129                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21130            }
21131        }
21132    }
21133
21134    final void runInBackgroundDisabled(int uid) {
21135        synchronized (this) {
21136            UidRecord uidRec = mActiveUids.get(uid);
21137            if (uidRec != null) {
21138                // This uid is actually running...  should it be considered background now?
21139                if (uidRec.idle) {
21140                    doStopUidLocked(uidRec.uid, uidRec);
21141                }
21142            } else {
21143                // This uid isn't actually running...  still send a report about it being "stopped".
21144                doStopUidLocked(uid, null);
21145            }
21146        }
21147    }
21148
21149    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21150        mServices.stopInBackgroundLocked(uid);
21151        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21152    }
21153
21154    final void trimApplications() {
21155        synchronized (this) {
21156            int i;
21157
21158            // First remove any unused application processes whose package
21159            // has been removed.
21160            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21161                final ProcessRecord app = mRemovedProcesses.get(i);
21162                if (app.activities.size() == 0
21163                        && app.curReceiver == null && app.services.size() == 0) {
21164                    Slog.i(
21165                        TAG, "Exiting empty application process "
21166                        + app.toShortString() + " ("
21167                        + (app.thread != null ? app.thread.asBinder() : null)
21168                        + ")\n");
21169                    if (app.pid > 0 && app.pid != MY_PID) {
21170                        app.kill("empty", false);
21171                    } else {
21172                        try {
21173                            app.thread.scheduleExit();
21174                        } catch (Exception e) {
21175                            // Ignore exceptions.
21176                        }
21177                    }
21178                    cleanUpApplicationRecordLocked(app, false, true, -1);
21179                    mRemovedProcesses.remove(i);
21180
21181                    if (app.persistent) {
21182                        addAppLocked(app.info, false, null /* ABI override */);
21183                    }
21184                }
21185            }
21186
21187            // Now update the oom adj for all processes.
21188            updateOomAdjLocked();
21189        }
21190    }
21191
21192    /** This method sends the specified signal to each of the persistent apps */
21193    public void signalPersistentProcesses(int sig) throws RemoteException {
21194        if (sig != Process.SIGNAL_USR1) {
21195            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21196        }
21197
21198        synchronized (this) {
21199            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21200                    != PackageManager.PERMISSION_GRANTED) {
21201                throw new SecurityException("Requires permission "
21202                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21203            }
21204
21205            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21206                ProcessRecord r = mLruProcesses.get(i);
21207                if (r.thread != null && r.persistent) {
21208                    Process.sendSignal(r.pid, sig);
21209                }
21210            }
21211        }
21212    }
21213
21214    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21215        if (proc == null || proc == mProfileProc) {
21216            proc = mProfileProc;
21217            profileType = mProfileType;
21218            clearProfilerLocked();
21219        }
21220        if (proc == null) {
21221            return;
21222        }
21223        try {
21224            proc.thread.profilerControl(false, null, profileType);
21225        } catch (RemoteException e) {
21226            throw new IllegalStateException("Process disappeared");
21227        }
21228    }
21229
21230    private void clearProfilerLocked() {
21231        if (mProfileFd != null) {
21232            try {
21233                mProfileFd.close();
21234            } catch (IOException e) {
21235            }
21236        }
21237        mProfileApp = null;
21238        mProfileProc = null;
21239        mProfileFile = null;
21240        mProfileType = 0;
21241        mAutoStopProfiler = false;
21242        mSamplingInterval = 0;
21243    }
21244
21245    public boolean profileControl(String process, int userId, boolean start,
21246            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21247
21248        try {
21249            synchronized (this) {
21250                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21251                // its own permission.
21252                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21253                        != PackageManager.PERMISSION_GRANTED) {
21254                    throw new SecurityException("Requires permission "
21255                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21256                }
21257
21258                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21259                    throw new IllegalArgumentException("null profile info or fd");
21260                }
21261
21262                ProcessRecord proc = null;
21263                if (process != null) {
21264                    proc = findProcessLocked(process, userId, "profileControl");
21265                }
21266
21267                if (start && (proc == null || proc.thread == null)) {
21268                    throw new IllegalArgumentException("Unknown process: " + process);
21269                }
21270
21271                if (start) {
21272                    stopProfilerLocked(null, 0);
21273                    setProfileApp(proc.info, proc.processName, profilerInfo);
21274                    mProfileProc = proc;
21275                    mProfileType = profileType;
21276                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21277                    try {
21278                        fd = fd.dup();
21279                    } catch (IOException e) {
21280                        fd = null;
21281                    }
21282                    profilerInfo.profileFd = fd;
21283                    proc.thread.profilerControl(start, profilerInfo, profileType);
21284                    fd = null;
21285                    mProfileFd = null;
21286                } else {
21287                    stopProfilerLocked(proc, profileType);
21288                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21289                        try {
21290                            profilerInfo.profileFd.close();
21291                        } catch (IOException e) {
21292                        }
21293                    }
21294                }
21295
21296                return true;
21297            }
21298        } catch (RemoteException e) {
21299            throw new IllegalStateException("Process disappeared");
21300        } finally {
21301            if (profilerInfo != null && profilerInfo.profileFd != null) {
21302                try {
21303                    profilerInfo.profileFd.close();
21304                } catch (IOException e) {
21305                }
21306            }
21307        }
21308    }
21309
21310    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21311        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21312                userId, true, ALLOW_FULL_ONLY, callName, null);
21313        ProcessRecord proc = null;
21314        try {
21315            int pid = Integer.parseInt(process);
21316            synchronized (mPidsSelfLocked) {
21317                proc = mPidsSelfLocked.get(pid);
21318            }
21319        } catch (NumberFormatException e) {
21320        }
21321
21322        if (proc == null) {
21323            ArrayMap<String, SparseArray<ProcessRecord>> all
21324                    = mProcessNames.getMap();
21325            SparseArray<ProcessRecord> procs = all.get(process);
21326            if (procs != null && procs.size() > 0) {
21327                proc = procs.valueAt(0);
21328                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21329                    for (int i=1; i<procs.size(); i++) {
21330                        ProcessRecord thisProc = procs.valueAt(i);
21331                        if (thisProc.userId == userId) {
21332                            proc = thisProc;
21333                            break;
21334                        }
21335                    }
21336                }
21337            }
21338        }
21339
21340        return proc;
21341    }
21342
21343    public boolean dumpHeap(String process, int userId, boolean managed,
21344            String path, ParcelFileDescriptor fd) throws RemoteException {
21345
21346        try {
21347            synchronized (this) {
21348                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21349                // its own permission (same as profileControl).
21350                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21351                        != PackageManager.PERMISSION_GRANTED) {
21352                    throw new SecurityException("Requires permission "
21353                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21354                }
21355
21356                if (fd == null) {
21357                    throw new IllegalArgumentException("null fd");
21358                }
21359
21360                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21361                if (proc == null || proc.thread == null) {
21362                    throw new IllegalArgumentException("Unknown process: " + process);
21363                }
21364
21365                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21366                if (!isDebuggable) {
21367                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21368                        throw new SecurityException("Process not debuggable: " + proc);
21369                    }
21370                }
21371
21372                proc.thread.dumpHeap(managed, path, fd);
21373                fd = null;
21374                return true;
21375            }
21376        } catch (RemoteException e) {
21377            throw new IllegalStateException("Process disappeared");
21378        } finally {
21379            if (fd != null) {
21380                try {
21381                    fd.close();
21382                } catch (IOException e) {
21383                }
21384            }
21385        }
21386    }
21387
21388    @Override
21389    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21390            String reportPackage) {
21391        if (processName != null) {
21392            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21393                    "setDumpHeapDebugLimit()");
21394        } else {
21395            synchronized (mPidsSelfLocked) {
21396                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21397                if (proc == null) {
21398                    throw new SecurityException("No process found for calling pid "
21399                            + Binder.getCallingPid());
21400                }
21401                if (!Build.IS_DEBUGGABLE
21402                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21403                    throw new SecurityException("Not running a debuggable build");
21404                }
21405                processName = proc.processName;
21406                uid = proc.uid;
21407                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21408                    throw new SecurityException("Package " + reportPackage + " is not running in "
21409                            + proc);
21410                }
21411            }
21412        }
21413        synchronized (this) {
21414            if (maxMemSize > 0) {
21415                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21416            } else {
21417                if (uid != 0) {
21418                    mMemWatchProcesses.remove(processName, uid);
21419                } else {
21420                    mMemWatchProcesses.getMap().remove(processName);
21421                }
21422            }
21423        }
21424    }
21425
21426    @Override
21427    public void dumpHeapFinished(String path) {
21428        synchronized (this) {
21429            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21430                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21431                        + " does not match last pid " + mMemWatchDumpPid);
21432                return;
21433            }
21434            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21435                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21436                        + " does not match last path " + mMemWatchDumpFile);
21437                return;
21438            }
21439            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21440            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21441        }
21442    }
21443
21444    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21445    public void monitor() {
21446        synchronized (this) { }
21447    }
21448
21449    void onCoreSettingsChange(Bundle settings) {
21450        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21451            ProcessRecord processRecord = mLruProcesses.get(i);
21452            try {
21453                if (processRecord.thread != null) {
21454                    processRecord.thread.setCoreSettings(settings);
21455                }
21456            } catch (RemoteException re) {
21457                /* ignore */
21458            }
21459        }
21460    }
21461
21462    // Multi-user methods
21463
21464    /**
21465     * Start user, if its not already running, but don't bring it to foreground.
21466     */
21467    @Override
21468    public boolean startUserInBackground(final int userId) {
21469        return mUserController.startUser(userId, /* foreground */ false);
21470    }
21471
21472    @Override
21473    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21474        return mUserController.unlockUser(userId, token, secret, listener);
21475    }
21476
21477    @Override
21478    public boolean switchUser(final int targetUserId) {
21479        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21480        UserInfo currentUserInfo;
21481        UserInfo targetUserInfo;
21482        synchronized (this) {
21483            int currentUserId = mUserController.getCurrentUserIdLocked();
21484            currentUserInfo = mUserController.getUserInfo(currentUserId);
21485            targetUserInfo = mUserController.getUserInfo(targetUserId);
21486            if (targetUserInfo == null) {
21487                Slog.w(TAG, "No user info for user #" + targetUserId);
21488                return false;
21489            }
21490            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21491                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21492                        + " when device is in demo mode");
21493                return false;
21494            }
21495            if (!targetUserInfo.supportsSwitchTo()) {
21496                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21497                return false;
21498            }
21499            if (targetUserInfo.isManagedProfile()) {
21500                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21501                return false;
21502            }
21503            mUserController.setTargetUserIdLocked(targetUserId);
21504        }
21505        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21506        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21507        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21508        return true;
21509    }
21510
21511    void scheduleStartProfilesLocked() {
21512        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21513            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21514                    DateUtils.SECOND_IN_MILLIS);
21515        }
21516    }
21517
21518    @Override
21519    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21520        return mUserController.stopUser(userId, force, callback);
21521    }
21522
21523    @Override
21524    public UserInfo getCurrentUser() {
21525        return mUserController.getCurrentUser();
21526    }
21527
21528    @Override
21529    public boolean isUserRunning(int userId, int flags) {
21530        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21531                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21532            String msg = "Permission Denial: isUserRunning() from pid="
21533                    + Binder.getCallingPid()
21534                    + ", uid=" + Binder.getCallingUid()
21535                    + " requires " + INTERACT_ACROSS_USERS;
21536            Slog.w(TAG, msg);
21537            throw new SecurityException(msg);
21538        }
21539        synchronized (this) {
21540            return mUserController.isUserRunningLocked(userId, flags);
21541        }
21542    }
21543
21544    @Override
21545    public int[] getRunningUserIds() {
21546        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21547                != PackageManager.PERMISSION_GRANTED) {
21548            String msg = "Permission Denial: isUserRunning() from pid="
21549                    + Binder.getCallingPid()
21550                    + ", uid=" + Binder.getCallingUid()
21551                    + " requires " + INTERACT_ACROSS_USERS;
21552            Slog.w(TAG, msg);
21553            throw new SecurityException(msg);
21554        }
21555        synchronized (this) {
21556            return mUserController.getStartedUserArrayLocked();
21557        }
21558    }
21559
21560    @Override
21561    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21562        mUserController.registerUserSwitchObserver(observer, name);
21563    }
21564
21565    @Override
21566    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21567        mUserController.unregisterUserSwitchObserver(observer);
21568    }
21569
21570    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21571        if (info == null) return null;
21572        ApplicationInfo newInfo = new ApplicationInfo(info);
21573        newInfo.initForUser(userId);
21574        return newInfo;
21575    }
21576
21577    public boolean isUserStopped(int userId) {
21578        synchronized (this) {
21579            return mUserController.getStartedUserStateLocked(userId) == null;
21580        }
21581    }
21582
21583    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21584        if (aInfo == null
21585                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21586            return aInfo;
21587        }
21588
21589        ActivityInfo info = new ActivityInfo(aInfo);
21590        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21591        return info;
21592    }
21593
21594    private boolean processSanityChecksLocked(ProcessRecord process) {
21595        if (process == null || process.thread == null) {
21596            return false;
21597        }
21598
21599        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21600        if (!isDebuggable) {
21601            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21602                return false;
21603            }
21604        }
21605
21606        return true;
21607    }
21608
21609    public boolean startBinderTracking() throws RemoteException {
21610        synchronized (this) {
21611            mBinderTransactionTrackingEnabled = true;
21612            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21613            // permission (same as profileControl).
21614            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21615                    != PackageManager.PERMISSION_GRANTED) {
21616                throw new SecurityException("Requires permission "
21617                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21618            }
21619
21620            for (int i = 0; i < mLruProcesses.size(); i++) {
21621                ProcessRecord process = mLruProcesses.get(i);
21622                if (!processSanityChecksLocked(process)) {
21623                    continue;
21624                }
21625                try {
21626                    process.thread.startBinderTracking();
21627                } catch (RemoteException e) {
21628                    Log.v(TAG, "Process disappared");
21629                }
21630            }
21631            return true;
21632        }
21633    }
21634
21635    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21636        try {
21637            synchronized (this) {
21638                mBinderTransactionTrackingEnabled = false;
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                if (fd == null) {
21648                    throw new IllegalArgumentException("null fd");
21649                }
21650
21651                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21652                pw.println("Binder transaction traces for all processes.\n");
21653                for (ProcessRecord process : mLruProcesses) {
21654                    if (!processSanityChecksLocked(process)) {
21655                        continue;
21656                    }
21657
21658                    pw.println("Traces for process: " + process.processName);
21659                    pw.flush();
21660                    try {
21661                        TransferPipe tp = new TransferPipe();
21662                        try {
21663                            process.thread.stopBinderTrackingAndDump(
21664                                    tp.getWriteFd().getFileDescriptor());
21665                            tp.go(fd.getFileDescriptor());
21666                        } finally {
21667                            tp.kill();
21668                        }
21669                    } catch (IOException e) {
21670                        pw.println("Failure while dumping IPC traces from " + process +
21671                                ".  Exception: " + e);
21672                        pw.flush();
21673                    } catch (RemoteException e) {
21674                        pw.println("Got a RemoteException while dumping IPC traces from " +
21675                                process + ".  Exception: " + e);
21676                        pw.flush();
21677                    }
21678                }
21679                fd = null;
21680                return true;
21681            }
21682        } finally {
21683            if (fd != null) {
21684                try {
21685                    fd.close();
21686                } catch (IOException e) {
21687                }
21688            }
21689        }
21690    }
21691
21692    private final class LocalService extends ActivityManagerInternal {
21693        @Override
21694        public void onWakefulnessChanged(int wakefulness) {
21695            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21696        }
21697
21698        @Override
21699        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21700                String processName, String abiOverride, int uid, Runnable crashHandler) {
21701            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21702                    processName, abiOverride, uid, crashHandler);
21703        }
21704
21705        @Override
21706        public SleepToken acquireSleepToken(String tag) {
21707            Preconditions.checkNotNull(tag);
21708
21709            ComponentName requestedVrService = null;
21710            ComponentName callingVrActivity = null;
21711            int userId = -1;
21712            synchronized (ActivityManagerService.this) {
21713                if (mFocusedActivity != null) {
21714                    requestedVrService = mFocusedActivity.requestedVrComponent;
21715                    callingVrActivity = mFocusedActivity.info.getComponentName();
21716                    userId = mFocusedActivity.userId;
21717                }
21718            }
21719
21720            if (requestedVrService != null) {
21721                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21722            }
21723
21724            synchronized (ActivityManagerService.this) {
21725                SleepTokenImpl token = new SleepTokenImpl(tag);
21726                mSleepTokens.add(token);
21727                updateSleepIfNeededLocked();
21728                return token;
21729            }
21730        }
21731
21732        @Override
21733        public ComponentName getHomeActivityForUser(int userId) {
21734            synchronized (ActivityManagerService.this) {
21735                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21736                return homeActivity == null ? null : homeActivity.realActivity;
21737            }
21738        }
21739
21740        @Override
21741        public void onUserRemoved(int userId) {
21742            synchronized (ActivityManagerService.this) {
21743                ActivityManagerService.this.onUserStoppedLocked(userId);
21744            }
21745        }
21746
21747        @Override
21748        public void onLocalVoiceInteractionStarted(IBinder activity,
21749                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21750            synchronized (ActivityManagerService.this) {
21751                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21752                        voiceSession, voiceInteractor);
21753            }
21754        }
21755
21756        @Override
21757        public void notifyStartingWindowDrawn() {
21758            synchronized (ActivityManagerService.this) {
21759                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21760            }
21761        }
21762
21763        @Override
21764        public void notifyAppTransitionStarting(int reason) {
21765            synchronized (ActivityManagerService.this) {
21766                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21767            }
21768        }
21769
21770        @Override
21771        public void notifyAppTransitionFinished() {
21772            synchronized (ActivityManagerService.this) {
21773                mStackSupervisor.notifyAppTransitionDone();
21774            }
21775        }
21776
21777        @Override
21778        public void notifyAppTransitionCancelled() {
21779            synchronized (ActivityManagerService.this) {
21780                mStackSupervisor.notifyAppTransitionDone();
21781            }
21782        }
21783
21784        @Override
21785        public List<IBinder> getTopVisibleActivities() {
21786            synchronized (ActivityManagerService.this) {
21787                return mStackSupervisor.getTopVisibleActivities();
21788            }
21789        }
21790
21791        @Override
21792        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21793            synchronized (ActivityManagerService.this) {
21794                mStackSupervisor.setDockedStackMinimized(minimized);
21795            }
21796        }
21797
21798        @Override
21799        public void killForegroundAppsForUser(int userHandle) {
21800            synchronized (ActivityManagerService.this) {
21801                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21802                final int NP = mProcessNames.getMap().size();
21803                for (int ip = 0; ip < NP; ip++) {
21804                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21805                    final int NA = apps.size();
21806                    for (int ia = 0; ia < NA; ia++) {
21807                        final ProcessRecord app = apps.valueAt(ia);
21808                        if (app.persistent) {
21809                            // We don't kill persistent processes.
21810                            continue;
21811                        }
21812                        if (app.removed) {
21813                            procs.add(app);
21814                        } else if (app.userId == userHandle && app.foregroundActivities) {
21815                            app.removed = true;
21816                            procs.add(app);
21817                        }
21818                    }
21819                }
21820
21821                final int N = procs.size();
21822                for (int i = 0; i < N; i++) {
21823                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21824                }
21825            }
21826        }
21827
21828        @Override
21829        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21830            if (!(target instanceof PendingIntentRecord)) {
21831                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21832                return;
21833            }
21834            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21835        }
21836
21837        @Override
21838        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21839                int userId) {
21840            Preconditions.checkNotNull(values, "Configuration must not be null");
21841            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21842            synchronized (ActivityManagerService.this) {
21843                updateConfigurationLocked(values, null, false, true, userId,
21844                        false /* deferResume */);
21845            }
21846        }
21847
21848        @Override
21849        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
21850                Bundle bOptions) {
21851            Preconditions.checkNotNull(intents, "intents");
21852            final String[] resolvedTypes = new String[intents.length];
21853            for (int i = 0; i < intents.length; i++) {
21854                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
21855            }
21856
21857            // UID of the package on user userId.
21858            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21859            // packageUid may not be initialized.
21860            int packageUid = 0;
21861            try {
21862                packageUid = AppGlobals.getPackageManager().getPackageUid(
21863                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
21864            } catch (RemoteException e) {
21865                // Shouldn't happen.
21866            }
21867
21868            synchronized (ActivityManagerService.this) {
21869                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
21870                        /*resultTo*/ null, bOptions, userId);
21871            }
21872        }
21873    }
21874
21875    private final class SleepTokenImpl extends SleepToken {
21876        private final String mTag;
21877        private final long mAcquireTime;
21878
21879        public SleepTokenImpl(String tag) {
21880            mTag = tag;
21881            mAcquireTime = SystemClock.uptimeMillis();
21882        }
21883
21884        @Override
21885        public void release() {
21886            synchronized (ActivityManagerService.this) {
21887                if (mSleepTokens.remove(this)) {
21888                    updateSleepIfNeededLocked();
21889                }
21890            }
21891        }
21892
21893        @Override
21894        public String toString() {
21895            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21896        }
21897    }
21898
21899    /**
21900     * An implementation of IAppTask, that allows an app to manage its own tasks via
21901     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21902     * only the process that calls getAppTasks() can call the AppTask methods.
21903     */
21904    class AppTaskImpl extends IAppTask.Stub {
21905        private int mTaskId;
21906        private int mCallingUid;
21907
21908        public AppTaskImpl(int taskId, int callingUid) {
21909            mTaskId = taskId;
21910            mCallingUid = callingUid;
21911        }
21912
21913        private void checkCaller() {
21914            if (mCallingUid != Binder.getCallingUid()) {
21915                throw new SecurityException("Caller " + mCallingUid
21916                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21917            }
21918        }
21919
21920        @Override
21921        public void finishAndRemoveTask() {
21922            checkCaller();
21923
21924            synchronized (ActivityManagerService.this) {
21925                long origId = Binder.clearCallingIdentity();
21926                try {
21927                    // We remove the task from recents to preserve backwards
21928                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21929                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21930                    }
21931                } finally {
21932                    Binder.restoreCallingIdentity(origId);
21933                }
21934            }
21935        }
21936
21937        @Override
21938        public ActivityManager.RecentTaskInfo getTaskInfo() {
21939            checkCaller();
21940
21941            synchronized (ActivityManagerService.this) {
21942                long origId = Binder.clearCallingIdentity();
21943                try {
21944                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21945                    if (tr == null) {
21946                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21947                    }
21948                    return createRecentTaskInfoFromTaskRecord(tr);
21949                } finally {
21950                    Binder.restoreCallingIdentity(origId);
21951                }
21952            }
21953        }
21954
21955        @Override
21956        public void moveToFront() {
21957            checkCaller();
21958            // Will bring task to front if it already has a root activity.
21959            final long origId = Binder.clearCallingIdentity();
21960            try {
21961                synchronized (this) {
21962                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21963                }
21964            } finally {
21965                Binder.restoreCallingIdentity(origId);
21966            }
21967        }
21968
21969        @Override
21970        public int startActivity(IBinder whoThread, String callingPackage,
21971                Intent intent, String resolvedType, Bundle bOptions) {
21972            checkCaller();
21973
21974            int callingUser = UserHandle.getCallingUserId();
21975            TaskRecord tr;
21976            IApplicationThread appThread;
21977            synchronized (ActivityManagerService.this) {
21978                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21979                if (tr == null) {
21980                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21981                }
21982                appThread = ApplicationThreadNative.asInterface(whoThread);
21983                if (appThread == null) {
21984                    throw new IllegalArgumentException("Bad app thread " + appThread);
21985                }
21986            }
21987            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21988                    resolvedType, null, null, null, null, 0, 0, null, null,
21989                    null, bOptions, false, callingUser, null, tr);
21990        }
21991
21992        @Override
21993        public void setExcludeFromRecents(boolean exclude) {
21994            checkCaller();
21995
21996            synchronized (ActivityManagerService.this) {
21997                long origId = Binder.clearCallingIdentity();
21998                try {
21999                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22000                    if (tr == null) {
22001                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22002                    }
22003                    Intent intent = tr.getBaseIntent();
22004                    if (exclude) {
22005                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22006                    } else {
22007                        intent.setFlags(intent.getFlags()
22008                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22009                    }
22010                } finally {
22011                    Binder.restoreCallingIdentity(origId);
22012                }
22013            }
22014        }
22015    }
22016
22017    /**
22018     * Kill processes for the user with id userId and that depend on the package named packageName
22019     */
22020    @Override
22021    public void killPackageDependents(String packageName, int userId) {
22022        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22023        if (packageName == null) {
22024            throw new NullPointerException(
22025                    "Cannot kill the dependents of a package without its name.");
22026        }
22027
22028        long callingId = Binder.clearCallingIdentity();
22029        IPackageManager pm = AppGlobals.getPackageManager();
22030        int pkgUid = -1;
22031        try {
22032            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22033        } catch (RemoteException e) {
22034        }
22035        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22036            throw new IllegalArgumentException(
22037                    "Cannot kill dependents of non-existing package " + packageName);
22038        }
22039        try {
22040            synchronized(this) {
22041                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22042                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22043                        "dep: " + packageName);
22044            }
22045        } finally {
22046            Binder.restoreCallingIdentity(callingId);
22047        }
22048    }
22049}
22050